(interactive (eshell-regexp-arg "Backward input matching (regexp): "))
(eshell-forward-matching-input regexp (- arg)))
-(defun eshell-next-prompt (n)
+(defun eshell-next-prompt (&optional n)
"Move to end of Nth next prompt in the buffer."
(interactive "p")
+ (unless n (setq n 1))
+ ;; First, move point to our starting position: the end of the
+ ;; current prompt (aka the beginning of the input), if any. (The
+ ;; welcome message and output from commands don't count as having a
+ ;; current prompt.)
+ (pcase (get-text-property (point) 'field)
+ ('command-output)
+ ('prompt (goto-char (field-end)))
+ (_ (when-let ((match (text-property-search-backward 'field 'prompt t)))
+ (goto-char (prop-match-end match)))))
+ ;; Now, move forward/backward to our destination prompt.
(if (natnump n)
(while (and (> n 0)
(text-property-search-forward 'field 'prompt t))
(setq n (1- n)))
(let (match this-match)
- ;; Don't count the current prompt.
- (text-property-search-backward 'field 'prompt t)
+ ;; Go to the beginning of the current prompt.
+ (goto-char (field-beginning (point) t))
(while (and (< n 0)
(setq this-match (text-property-search-backward
'field 'prompt t)))
(when match
(goto-char (prop-match-end match))))))
-(defun eshell-previous-prompt (n)
+(defun eshell-previous-prompt (&optional n)
"Move to end of Nth previous prompt in the buffer."
(interactive "p")
- (eshell-next-prompt (- n)))
+ (eshell-next-prompt (- (or n 1))))
(defun eshell-skip-prompt ()
"Skip past the text matching regexp `eshell-prompt-regexp'.
(file-name-directory (or load-file-name
default-directory))))
+(defmacro em-prompt-test--with-multiline (&rest body)
+ "Execute BODY with a multiline Eshell prompt."
+ `(let ((eshell-prompt-function (lambda () "multiline prompt\n$ ")))
+ ,@body))
+
;;; Tests:
(ert-deftest em-prompt-test/field-properties ()
(apply #'propertize "hello\n"
eshell-command-output-properties)))))))
-(defmacro em-prompt-test--with-multiline (&rest body)
- "Execute BODY with a multiline Eshell prompt."
- `(let ((eshell-prompt-function (lambda () "multiline prompt\n$ ")))
- ,@body))
-
-(defun em-prompt-test/next-previous-prompt-with ()
+(defun em-prompt-test/next-previous-prompt-1 ()
"Helper for checking forward/backward navigation of old prompts."
(with-temp-eshell
(eshell-insert-command "echo one")
(eshell-insert-command "echo two")
(eshell-insert-command "echo three")
(insert "echo fou") ; A partially-entered command.
- ;; Go back one prompt.
- (eshell-previous-prompt 1)
- (should (equal (eshell-get-old-input) "echo three"))
- ;; Go back two prompts, starting from the end of this line.
- (end-of-line)
- (eshell-previous-prompt 2)
- (should (equal (eshell-get-old-input) "echo one"))
- ;; Go forward three prompts.
- (eshell-next-prompt 3)
- (should (equal (eshell-get-old-input) "echo fou"))))
+ (ert-info ("Go back one prompt")
+ (eshell-previous-prompt)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo three\n")))
+ (ert-info ("Go back two prompts, starting from the end of the input")
+ (end-of-line)
+ (eshell-previous-prompt 2)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo one\n")))
+ (ert-info ("Go to the current prompt, starting from the end of the input")
+ (end-of-line)
+ (eshell-previous-prompt 0)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo one\n")))
+ (ert-info ("Go forward one prompt")
+ (eshell-next-prompt)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo two\n")))
+ (ert-info ("Go forward two prompts")
+ (eshell-next-prompt 2)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo fou")))
+ (ert-info ("Go back one prompt, starting from the beginning of the line")
+ (forward-line 0)
+ (eshell-previous-prompt 1)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo three\n")))
+ (ert-info ("Go back one prompt, starting from the previous prompt's output")
+ (forward-line -1)
+ (eshell-previous-prompt 1)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo two\n")))))
(ert-deftest em-prompt-test/next-previous-prompt ()
"Check that navigating forward/backward through old prompts works correctly."
- (em-prompt-test/next-previous-prompt-with))
+ (em-prompt-test/next-previous-prompt-1))
(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-with)))
+ (em-prompt-test/next-previous-prompt-1)))
-(defun em-prompt-test/forward-backward-matching-input-with ()
+(defun em-prompt-test/forward-backward-matching-input-1 ()
"Helper for checking forward/backward navigation via regexps."
(with-temp-eshell
(eshell-insert-command "echo one")
(eshell-insert-command "echo two")
(eshell-insert-command "echo three")
(insert "echo fou") ; A partially-entered command.
- ;; Go back one prompt.
- (eshell-backward-matching-input "echo" 1)
- (should (equal (eshell-get-old-input) "echo three"))
- ;; Go back two prompts, starting from the end of this line.
- (end-of-line)
- (eshell-backward-matching-input "echo" 2)
- (should (equal (eshell-get-old-input) "echo one"))
- ;; Go forward three prompts.
- (eshell-forward-matching-input "echo" 3)
- (should (equal (eshell-get-old-input) "echo fou"))))
+ (ert-info ("Go back one prompt")
+ (eshell-backward-matching-input "echo" 1)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo three\n")))
+ (ert-info ("Go back two prompts, starting from the end of this line")
+ (end-of-line)
+ (eshell-backward-matching-input "echo" 2)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo one\n")))
+ (ert-info ("Go forward three prompts")
+ (eshell-forward-matching-input "echo" 3)
+ (should (equal (point) (field-beginning)))
+ (should (equal (field-string) "echo fou")))))
(ert-deftest em-prompt-test/forward-backward-matching-input ()
"Check that navigating forward/backward via regexps works correctly."
- (em-prompt-test/forward-backward-matching-input-with))
+ (em-prompt-test/forward-backward-matching-input-1))
(ert-deftest em-prompt-test/forward-backward-matching-input-multiline ()
"Check forward/backward regexp navigation for multiline prompts."
(em-prompt-test--with-multiline
- (em-prompt-test/forward-backward-matching-input-with)))
+ (em-prompt-test/forward-backward-matching-input-1)))
;;; em-prompt-tests.el ends here