* bug#71545: 30.0.50; [PATCH] Fix paragraph navigation in Eshell
@ 2024-06-14 4:33 Jim Porter
2024-06-14 4:42 ` Jim Porter
0 siblings, 1 reply; 3+ messages in thread
From: Jim Porter @ 2024-06-14 4:33 UTC (permalink / raw)
To: 71545
[-- Attachment #1: Type: text/plain, Size: 444 bytes --]
A while back, I updated how forward- and backward-paragraph work in
Eshell so that we didn't have to rely on regexps to detect the prompt
(paragraph navigation in Eshell has always stopped at prompts as well as
blank lines separating paragraphs). I got that implementation wrong, and
since then it's only navigated between prompts. Attached is a patch to
restore the proper behavior, plus some tests to make sure I got it right
this time.
[-- Attachment #2: 0001-Ensure-navigating-by-paragraphs-in-Eshell-stops-at-p.patch --]
[-- Type: text/plain, Size: 6913 bytes --]
From f015b7f1d7ef35edf59c7899fe6b4d27f016dc76 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Thu, 13 Jun 2024 21:26:53 -0700
Subject: [PATCH] Ensure navigating by paragraphs in Eshell stops at prompts
and paragraphs
The previous implementation in 6ae2b74ed20 only stopped at prompts,
which isn't the right behavior.
* 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.
---
lisp/eshell/em-prompt.el | 34 ++++++++++++++++----
test/lisp/eshell/em-prompt-tests.el | 49 ++++++++++++++++++++++++++++-
2 files changed, 76 insertions(+), 7 deletions(-)
diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el
index b6556d29544..fb4e51cdfe0 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -117,7 +117,7 @@ eshell-prompt-initialize
"Initialize the prompting code."
(unless eshell-non-interactive-p
(add-hook 'eshell-post-command-hook 'eshell-emit-prompt nil t)
- (eshell-prompt-mode)))
+ (eshell-prompt-mode))
(defun eshell-emit-prompt ()
"Emit a prompt if eshell is being used interactively."
@@ -167,17 +167,39 @@ eshell-backward-matching-input
(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."
diff --git a/test/lisp/eshell/em-prompt-tests.el b/test/lisp/eshell/em-prompt-tests.el
index 964609e6410..fbadade061f 100644
--- a/test/lisp/eshell/em-prompt-tests.el
+++ b/test/lisp/eshell/em-prompt-tests.el
@@ -39,6 +39,9 @@ em-prompt-test--with-multiline
;;; Tests:
+\f
+;; 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 @@ em-prompt-test/after-failure
'front-sticky '(read-only field font-lock-face)
'rear-nonsticky '(read-only field font-lock-face)))))))
+\f
+;; 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 @@ em-prompt-test/next-previous-prompt
"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
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* bug#71545: 30.0.50; [PATCH] Fix paragraph navigation in Eshell
2024-06-14 4:33 bug#71545: 30.0.50; [PATCH] Fix paragraph navigation in Eshell Jim Porter
@ 2024-06-14 4:42 ` Jim Porter
2024-06-21 2:09 ` Jim Porter
0 siblings, 1 reply; 3+ messages in thread
From: Jim Porter @ 2024-06-14 4:42 UTC (permalink / raw)
To: 71545
[-- Attachment #1: Type: text/plain, Size: 69 bytes --]
My previous patch had a typo that snuck in. Here's the fixed version.
[-- Attachment #2: 0001-Ensure-navigating-by-paragraphs-in-Eshell-stops-at-p.patch --]
[-- Type: text/plain, Size: 6582 bytes --]
From ac9aadef8863a2067202edc00501c34e22006222 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Thu, 13 Jun 2024 21:26:53 -0700
Subject: [PATCH] Ensure navigating by paragraphs in Eshell stops at prompts
and paragraphs
The previous implementation in 6ae2b74ed20 only stopped at prompts,
which isn't the right behavior.
* 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.
---
lisp/eshell/em-prompt.el | 32 ++++++++++++++++---
test/lisp/eshell/em-prompt-tests.el | 49 ++++++++++++++++++++++++++++-
2 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el
index b6556d29544..7de2bd4dc21 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -167,17 +167,39 @@ eshell-backward-matching-input
(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."
diff --git a/test/lisp/eshell/em-prompt-tests.el b/test/lisp/eshell/em-prompt-tests.el
index 964609e6410..fbadade061f 100644
--- a/test/lisp/eshell/em-prompt-tests.el
+++ b/test/lisp/eshell/em-prompt-tests.el
@@ -39,6 +39,9 @@ em-prompt-test--with-multiline
;;; Tests:
+\f
+;; 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 @@ em-prompt-test/after-failure
'front-sticky '(read-only field font-lock-face)
'rear-nonsticky '(read-only field font-lock-face)))))))
+\f
+;; 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 @@ em-prompt-test/next-previous-prompt
"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
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-06-21 2:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-14 4:33 bug#71545: 30.0.50; [PATCH] Fix paragraph navigation in Eshell Jim Porter
2024-06-14 4:42 ` Jim Porter
2024-06-21 2:09 ` Jim Porter
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.