From b91eafe31a524b391d5cec079cf8f36c2f9d5f30 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Thu, 12 Mar 2015 22:22:22 +0200 Subject: [PATCH] Support goal column in multi-line minibuffer * lisp/simple.el (next-line-or-history-element) (previous-line-or-history-element): Remember the goal column of possibly multi-line input, and restore it afterwards. Fixes: debbugs:19824 --- lisp/ChangeLog | 6 ++++++ lisp/simple.el | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 97253c8824e..8ddf9ed02ad 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2015-03-12 Juri Linkov + + * simple.el (next-line-or-history-element) + (previous-line-or-history-element): Remember the goal column of + possibly multi-line input, and restore it afterwards. (Bug#19824) + 2015-03-12 Rasmus Pank Roulund * ido.el (ido-add-virtual-buffers-to-list): Include bookmark-alist diff --git a/lisp/simple.el b/lisp/simple.el index 4deb4cfce2e..98188a07b6f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1992,7 +1992,14 @@ When point moves over the bottom line of multi-line minibuffer, puts ARGth next element of the minibuffer history in the minibuffer." (interactive "^p") (or arg (setq arg 1)) - (let ((old-point (point))) + (let* ((old-point (point)) + ;; Remember the original goal column of possibly multi-line input + ;; excluding the length of the prompt on the first line. + (prompt-end (minibuffer-prompt-end)) + (old-column (unless (and (eolp) (> (point) prompt-end)) + (if (= (line-number-at-pos) 1) + (max (- (current-column) (1- prompt-end)) 0) + (current-column))))) (condition-case nil (with-no-warnings (next-line arg)) @@ -2000,7 +2007,14 @@ next element of the minibuffer history in the minibuffer." ;; Restore old position since `line-move-visual' moves point to ;; the end of the line when it fails to go to the next line. (goto-char old-point) - (next-history-element arg))))) + (next-history-element arg) + ;; Restore the original goal column on the last line + ;; of possibly multi-line input. + (goto-char (point-max)) + (when old-column + (if (= (line-number-at-pos) 1) + (move-to-column (+ old-column (1- (minibuffer-prompt-end)))) + (move-to-column old-column))))))) (defun previous-line-or-history-element (&optional arg) "Move cursor vertically up ARG lines, or to the previous history element. @@ -2008,7 +2022,14 @@ When point moves over the top line of multi-line minibuffer, puts ARGth previous element of the minibuffer history in the minibuffer." (interactive "^p") (or arg (setq arg 1)) - (let ((old-point (point))) + (let* ((old-point (point)) + ;; Remember the original goal column of possibly multi-line input + ;; excluding the length of the prompt on the first line. + (prompt-end (minibuffer-prompt-end)) + (old-column (unless (and (eolp) (> (point) prompt-end)) + (if (= (line-number-at-pos) 1) + (max (- (current-column) (1- prompt-end)) 0) + (current-column))))) (condition-case nil (with-no-warnings (previous-line arg)) @@ -2016,7 +2037,15 @@ previous element of the minibuffer history in the minibuffer." ;; Restore old position since `line-move-visual' moves point to ;; the beginning of the line when it fails to go to the previous line. (goto-char old-point) - (previous-history-element arg))))) + (previous-history-element arg) + ;; Restore the original goal column on the first line + ;; of possibly multi-line input. + (goto-char (minibuffer-prompt-end)) + (if old-column + (if (= (line-number-at-pos) 1) + (move-to-column (+ old-column (1- (minibuffer-prompt-end)))) + (move-to-column old-column)) + (goto-char (line-end-position))))))) (defun next-complete-history-element (n) "Get next history element which completes the minibuffer before the point. -- 2.39.2