X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/dd72e25cb2561f180437db5e84b08dd7670809ae..34cba8e885f2ed1c0e9c805ad89b9464e0b5766a:/lisp/simple.el diff --git a/lisp/simple.el b/lisp/simple.el index d84708217b..36d2d0b3a1 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -611,7 +611,7 @@ In some text modes, where TAB inserts a tab, this command indents to the column specified by the function `current-left-margin'." (interactive "*") (delete-horizontal-space t) - (newline 1 t) + (newline nil t) (indent-according-to-mode)) (defun reindent-then-newline-and-indent () @@ -1628,36 +1628,37 @@ a special event, so ignore the prefix argument and don't clear it." (prog1 prefix-arg (setq current-prefix-arg prefix-arg) (setq prefix-arg nil))))) - (and (symbolp cmd) - (get cmd 'disabled) - ;; FIXME: Weird calling convention! - (run-hooks 'disabled-command-function)) - (let ((final cmd)) - (while - (progn - (setq final (indirect-function final)) - (if (autoloadp final) - (setq final (autoload-do-load final cmd))))) - (cond - ((arrayp final) - ;; If requested, place the macro in the command history. For - ;; other sorts of commands, call-interactively takes care of this. - (when record-flag - (push `(execute-kbd-macro ,final ,prefixarg) command-history) - ;; Don't keep command history around forever. - (when (and (numberp history-length) (> history-length 0)) - (let ((cell (nthcdr history-length command-history))) - (if (consp cell) (setcdr cell nil))))) - (execute-kbd-macro final prefixarg)) - (t - ;; Pass `cmd' rather than `final', for the backtrace's sake. - (prog1 (call-interactively cmd record-flag keys) - (when (and (symbolp cmd) - (get cmd 'byte-obsolete-info) - (not (get cmd 'command-execute-obsolete-warned))) - (put cmd 'command-execute-obsolete-warned t) - (message "%s" (macroexp--obsolete-warning - cmd (get cmd 'byte-obsolete-info) "command"))))))))) + (if (and (symbolp cmd) + (get cmd 'disabled) + disabled-command-function) + ;; FIXME: Weird calling convention! + (run-hooks 'disabled-command-function) + (let ((final cmd)) + (while + (progn + (setq final (indirect-function final)) + (if (autoloadp final) + (setq final (autoload-do-load final cmd))))) + (cond + ((arrayp final) + ;; If requested, place the macro in the command history. For + ;; other sorts of commands, call-interactively takes care of this. + (when record-flag + (push `(execute-kbd-macro ,final ,prefixarg) command-history) + ;; Don't keep command history around forever. + (when (and (numberp history-length) (> history-length 0)) + (let ((cell (nthcdr history-length command-history))) + (if (consp cell) (setcdr cell nil))))) + (execute-kbd-macro final prefixarg)) + (t + ;; Pass `cmd' rather than `final', for the backtrace's sake. + (prog1 (call-interactively cmd record-flag keys) + (when (and (symbolp cmd) + (get cmd 'byte-obsolete-info) + (not (get cmd 'command-execute-obsolete-warned))) + (put cmd 'command-execute-obsolete-warned t) + (message "%s" (macroexp--obsolete-warning + cmd (get cmd 'byte-obsolete-info) "command")))))))))) (defvar minibuffer-history nil "Default minibuffer history list. @@ -2142,7 +2143,12 @@ as an argument limits undo to changes within the current region." ;; above when checking. (while (eq (car list) nil) (setq list (cdr list))) - (puthash list (if undo-in-region t pending-undo-list) + (puthash list + ;; Prevent identity mapping. This can happen if + ;; consecutive nils are erroneously in undo list. + (if (or undo-in-region (eq list pending-undo-list)) + t + pending-undo-list) undo-equiv-table)) ;; Don't specify a position in the undo record for the undo command. ;; Instead, undoing this should move point to where the change is. @@ -2289,20 +2295,38 @@ Return what remains of the list." (when (let ((apos (abs pos))) (or (< apos (point-min)) (> apos (point-max)))) (error "Changes to be undone are outside visible portion of buffer")) - (if (< pos 0) - (progn - (goto-char (- pos)) - (insert string)) - (goto-char pos) - ;; Now that we record marker adjustments - ;; (caused by deletion) for undo, - ;; we should always insert after markers, - ;; so that undoing the marker adjustments - ;; put the markers back in the right place. - (insert string) - (goto-char pos))) + (let (valid-marker-adjustments) + ;; Check that marker adjustments which were recorded + ;; with the (STRING . POS) record are still valid, ie + ;; the markers haven't moved. We check their validity + ;; before reinserting the string so as we don't need to + ;; mind marker insertion-type. + (while (and (markerp (car-safe (car list))) + (integerp (cdr-safe (car list)))) + (let* ((marker-adj (pop list)) + (m (car marker-adj))) + (and (eq (marker-buffer m) (current-buffer)) + (= pos m) + (push marker-adj valid-marker-adjustments)))) + ;; Insert string and adjust point + (if (< pos 0) + (progn + (goto-char (- pos)) + (insert string)) + (goto-char pos) + (insert string) + (goto-char pos)) + ;; Adjust the valid marker adjustments + (dolist (adj valid-marker-adjustments) + (set-marker (car adj) + (- (car adj) (cdr adj)))))) ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET. (`(,(and marker (pred markerp)) . ,(and offset (pred integerp))) + (warn "Encountered %S entry in undo list with no matching (TEXT . POS) entry" + next) + ;; Even though these elements are not expected in the undo + ;; list, adjust them to be conservative for the 24.4 + ;; release. (Bug#16818) (when (marker-buffer marker) (set-marker marker (- marker offset) @@ -2341,8 +2365,6 @@ are ignored. If BEG and END are nil, all undo elements are used." (undo-make-selective-list (min beg end) (max beg end)) buffer-undo-list))) -(defvar undo-adjusted-markers) - (defun undo-make-selective-list (start end) "Return a list of undo elements for the region START to END. The elements come from `buffer-undo-list', but we keep only @@ -2351,7 +2373,6 @@ If we find an element that crosses an edge of this region, we stop and ignore all further elements." (let ((undo-list-copy (undo-copy-list buffer-undo-list)) (undo-list (list nil)) - undo-adjusted-markers some-rejected undo-elt temp-undo-list delta) (while undo-list-copy @@ -2361,15 +2382,30 @@ we stop and ignore all further elements." ;; This is a "was unmodified" element. ;; Keep it if we have kept everything thus far. (not some-rejected)) + ;; Skip over marker adjustments, instead relying on + ;; finding them after (TEXT . POS) elements + ((markerp (car-safe undo-elt)) + nil) (t (undo-elt-in-region undo-elt start end))))) (if keep-this (progn (setq end (+ end (cdr (undo-delta undo-elt)))) ;; Don't put two nils together in the list - (if (not (and (eq (car undo-list) nil) - (eq undo-elt nil))) - (setq undo-list (cons undo-elt undo-list)))) + (when (not (and (eq (car undo-list) nil) + (eq undo-elt nil))) + (setq undo-list (cons undo-elt undo-list)) + ;; If (TEXT . POS), "keep" its subsequent (MARKER + ;; . ADJUSTMENT) whose markers haven't moved. + (when (and (stringp (car-safe undo-elt)) + (integerp (cdr-safe undo-elt))) + (let ((list-i (cdr undo-list-copy))) + (while (markerp (car-safe (car list-i))) + (let* ((adj-elt (pop list-i)) + (m (car adj-elt))) + (and (eq (marker-buffer m) (current-buffer)) + (= (cdr undo-elt) m) + (push adj-elt undo-list)))))))) (if (undo-elt-crosses-region undo-elt start end) (setq undo-list-copy nil) (setq some-rejected t) @@ -2417,7 +2453,12 @@ we stop and ignore all further elements." (defun undo-elt-in-region (undo-elt start end) "Determine whether UNDO-ELT falls inside the region START ... END. -If it crosses the edge, we return nil." +If it crosses the edge, we return nil. + +Generally this function is not useful for determining +whether (MARKER . ADJUSTMENT) undo elements are in the region, +because markers can be arbitrarily relocated. Instead, pass the +marker adjustment's corresponding (TEXT . POS) element." (cond ((integerp undo-elt) (and (>= undo-elt start) (<= undo-elt end))) @@ -2430,17 +2471,8 @@ If it crosses the edge, we return nil." (and (>= (abs (cdr undo-elt)) start) (<= (abs (cdr undo-elt)) end))) ((and (consp undo-elt) (markerp (car undo-elt))) - ;; This is a marker-adjustment element (MARKER . ADJUSTMENT). - ;; See if MARKER is inside the region. - (let ((alist-elt (assq (car undo-elt) undo-adjusted-markers))) - (unless alist-elt - (setq alist-elt (cons (car undo-elt) - (marker-position (car undo-elt)))) - (setq undo-adjusted-markers - (cons alist-elt undo-adjusted-markers))) - (and (cdr alist-elt) - (>= (cdr alist-elt) start) - (<= (cdr alist-elt) end)))) + ;; (MARKER . ADJUSTMENT) + (<= start (car undo-elt) end)) ((null (car undo-elt)) ;; (nil PROPERTY VALUE BEG . END) (let ((tail (nthcdr 3 undo-elt))) @@ -4386,7 +4418,8 @@ run `deactivate-mark-hook'." (if (eq (car-safe transient-mark-mode) 'only) (setq transient-mark-mode (cdr transient-mark-mode))) (setq mark-active nil) - (run-hooks 'deactivate-mark-hook)))) + (run-hooks 'deactivate-mark-hook)) + (redisplay--update-region-highlight (selected-window)))) (defun activate-mark (&optional no-tmm) "Activate the mark. @@ -4462,7 +4495,12 @@ Some commands act specially on the region when Transient Mark mode is enabled. Usually, such commands should use `use-region-p' instead of this function, because `use-region-p' also checks the value of `use-empty-active-region'." - (and transient-mark-mode mark-active)) + (and transient-mark-mode mark-active + ;; FIXME: Somehow we sometimes end up with mark-active non-nil but + ;; without the mark being set (e.g. bug#17324). We really should fix + ;; that problem, but in the mean time, let's make sure we don't say the + ;; region is active when there's no mark. + (mark))) (defvar redisplay-unhighlight-region-function @@ -4475,6 +4513,11 @@ also checks the value of `use-empty-active-region'." (funcall redisplay-unhighlight-region-function rol) (overlay-put nrol 'window window) (overlay-put nrol 'face 'region) + ;; Normal priority so that a large region doesn't hide all the + ;; overlays within it, but high secondary priority so that if it + ;; ends/starts in the middle of a small overlay, that small overlay + ;; won't hide the region's boundaries. + (overlay-put nrol 'priority '(nil . 100)) nrol) (unless (and (eq (overlay-buffer rol) (current-buffer)) (eq (overlay-start rol) start) @@ -6832,7 +6875,7 @@ With a prefix argument, set VARIABLE to VALUE buffer-locally." (defvar completion-list-mode-map (let ((map (make-sparse-keymap))) - (define-key map [mouse-2] 'mouse-choose-completion) + (define-key map [mouse-2] 'choose-completion) (define-key map [follow-link] 'mouse-face) (define-key map [down-mouse-2] nil) (define-key map "\C-m" 'choose-completion) @@ -7081,8 +7124,7 @@ back on `completion-list-insert-choice-function' when nil." "Major mode for buffers showing lists of possible completions. Type \\\\[choose-completion] in the completion list\ to select the completion near point. -Use \\\\[mouse-choose-completion] to select one\ - with the mouse. +Or click to select one with the mouse. \\{completion-list-mode-map}" (set (make-local-variable 'completion-base-size) nil)) @@ -7140,7 +7182,7 @@ Called from `temp-buffer-show-hook'." (goto-char (point-min)) (if (display-mouse-p) (insert (substitute-command-keys - "Click \\[mouse-choose-completion] on a completion to select it.\n"))) + "Click on a completion to select it.\n"))) (insert (substitute-command-keys "In this buffer, type \\[choose-completion] to \ select the completion near point.\n\n"))))))