Ensure navigating by paragraphs in Eshell stops at prompts and paragraphs
The previous implementation in 6ae2b74ed2
only stopped at prompts,
which isn't the right behavior (bug#61545).
* lisp/eshell/em-prompt.el (eshell-forward-paragraph)
(eshell-backward-paragraph): Reimplement to handle prompts and
paragraphs (the latter by calling the original 'forward-paragraph').
* test/lisp/eshell/em-prompt-tests.el
(em-prompt-test/next-previous-prompt/multiline): Rename.
(em-prompt-test/forward-backward-paragraph-1): New function.
(em-prompt-test/forward-backward-paragraph)
(em-prompt-test/forward-backward-paragraph/multiline): New tests.
This commit is contained in:
parent
1a55e957ae
commit
e22b072423
2 changed files with 75 additions and 6 deletions
|
@ -167,17 +167,39 @@ negative, find the Nth next match."
|
|||
|
||||
(defun eshell-forward-paragraph (&optional n)
|
||||
"Move to the beginning of the Nth next prompt in the buffer.
|
||||
Like `forward-paragraph', but navigates using fields."
|
||||
Like `forward-paragraph', but also stops at the beginning of each prompt."
|
||||
(interactive "p")
|
||||
(eshell-next-prompt n)
|
||||
(goto-char (field-beginning (point) t)))
|
||||
(unless n (setq n 1))
|
||||
(let (;; We'll handle the "paragraph" starts ourselves.
|
||||
(paragraph-start regexp-unmatchable)
|
||||
(inhibit-field-text-motion t))
|
||||
(cond
|
||||
((> n 0)
|
||||
(while (and (> n 0) (< (point) (point-max)))
|
||||
(let ((next-paragraph (save-excursion (forward-paragraph) (point)))
|
||||
(next-prompt (save-excursion
|
||||
(if-let ((match (text-property-search-forward
|
||||
'field 'prompt t t)))
|
||||
(prop-match-beginning match)
|
||||
(point-max)))))
|
||||
(goto-char (min next-paragraph next-prompt)))
|
||||
(setq n (1- n))))
|
||||
((< n 0)
|
||||
(while (and (< n 0) (> (point) (point-min)))
|
||||
(let ((prev-paragraph (save-excursion (backward-paragraph) (point)))
|
||||
(prev-prompt (save-excursion
|
||||
(if (text-property-search-backward
|
||||
'field 'prompt t)
|
||||
(point)
|
||||
(point-min)))))
|
||||
(goto-char (max prev-paragraph prev-prompt)))
|
||||
(setq n (1+ n)))))))
|
||||
|
||||
(defun eshell-backward-paragraph (&optional n)
|
||||
"Move to the beginning of the Nth previous prompt in the buffer.
|
||||
Like `backward-paragraph', but navigates using fields."
|
||||
(interactive "p")
|
||||
(eshell-previous-prompt n)
|
||||
(goto-char (field-beginning (point) t)))
|
||||
(eshell-forward-paragraph (- (or n 1))))
|
||||
|
||||
(defun eshell-next-prompt (&optional n)
|
||||
"Move to end of Nth next prompt in the buffer."
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
|
||||
;;; Tests:
|
||||
|
||||
|
||||
;; Prompt output
|
||||
|
||||
(ert-deftest em-prompt-test/field-properties ()
|
||||
"Check that field properties are properly set on Eshell output/prompts."
|
||||
(with-temp-eshell
|
||||
|
@ -104,6 +107,9 @@ This tests the case when `eshell-highlight-prompt' is nil."
|
|||
'front-sticky '(read-only field font-lock-face)
|
||||
'rear-nonsticky '(read-only field font-lock-face)))))))
|
||||
|
||||
|
||||
;; Prompt navigation
|
||||
|
||||
(defun em-prompt-test/next-previous-prompt-1 ()
|
||||
"Helper for checking forward/backward navigation of old prompts."
|
||||
(with-temp-eshell
|
||||
|
@ -150,11 +156,52 @@ This tests the case when `eshell-highlight-prompt' is nil."
|
|||
"Check that navigating forward/backward through old prompts works correctly."
|
||||
(em-prompt-test/next-previous-prompt-1))
|
||||
|
||||
(ert-deftest em-prompt-test/next-previous-prompt-multiline ()
|
||||
(ert-deftest em-prompt-test/next-previous-prompt/multiline ()
|
||||
"Check old prompt forward/backward navigation for multiline prompts."
|
||||
(em-prompt-test--with-multiline
|
||||
(em-prompt-test/next-previous-prompt-1)))
|
||||
|
||||
(defun em-prompt-test/forward-backward-paragraph-1 ()
|
||||
"Helper for checking forward/backward navigation by paragraphs."
|
||||
(with-temp-eshell
|
||||
(cl-flet ((at-prompt-for-command-p (command)
|
||||
(and (equal (point) (field-beginning))
|
||||
(equal (get-text-property (point) 'field) 'prompt)
|
||||
(save-excursion
|
||||
(goto-char (field-end))
|
||||
(equal (field-string) command)))))
|
||||
(eshell-insert-command "echo 'high five'")
|
||||
(eshell-insert-command "echo 'up high\n\ndown low'")
|
||||
(eshell-insert-command "echo 'too slow'")
|
||||
(insert "echo goodby") ; A partially-entered command.
|
||||
(ert-info ("Go back to the last prompt")
|
||||
(eshell-backward-paragraph)
|
||||
(should (at-prompt-for-command-p "echo goodby")))
|
||||
(ert-info ("Go back to the paragraph break")
|
||||
(eshell-backward-paragraph 2)
|
||||
(should (looking-at "\ndown low\n")))
|
||||
(ert-info ("Go forward to the third prompt")
|
||||
(eshell-forward-paragraph)
|
||||
(should (at-prompt-for-command-p "echo 'too slow'\n")))
|
||||
(ert-info ("Go backward to before the first prompt")
|
||||
(eshell-backward-paragraph 5)
|
||||
(should (looking-back "Welcome to the Emacs shell\n")))
|
||||
(ert-info ("Go backward to the beginning of the buffer")
|
||||
(eshell-backward-paragraph)
|
||||
(should (bobp)))
|
||||
(ert-info ("Go forward to the second prompt")
|
||||
(eshell-forward-paragraph 3)
|
||||
(should (at-prompt-for-command-p "echo 'up high\n\ndown low'\n"))))))
|
||||
|
||||
(ert-deftest em-prompt-test/forward-backward-paragraph ()
|
||||
"Check that navigating forward/backward through paragraphs works correctly."
|
||||
(em-prompt-test/forward-backward-paragraph-1))
|
||||
|
||||
(ert-deftest em-prompt-test/forward-backward-paragraph/multiline ()
|
||||
"Check paragraph forward/backward navigation for multiline prompts."
|
||||
(em-prompt-test--with-multiline
|
||||
(em-prompt-test/forward-backward-paragraph-1)))
|
||||
|
||||
(defun em-prompt-test/forward-backward-matching-input-1 ()
|
||||
"Helper for checking forward/backward navigation via regexps."
|
||||
(with-temp-eshell
|
||||
|
|
Loading…
Add table
Reference in a new issue