all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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

* bug#71545: 30.0.50; [PATCH] Fix paragraph navigation in Eshell
  2024-06-14  4:42 ` Jim Porter
@ 2024-06-21  2:09   ` Jim Porter
  0 siblings, 0 replies; 3+ messages in thread
From: Jim Porter @ 2024-06-21  2:09 UTC (permalink / raw)
  To: 71545-done

On 6/13/2024 9:42 PM, Jim Porter wrote:
> My previous patch had a typo that snuck in. Here's the fixed version.

Merged as e22b072423a to the master branch, and closing this bug.





^ permalink raw reply	[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.