emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c257fd3a40 3/3: Use the 'field' property to navigate through Eshe


From: Jim Porter
Subject: master c257fd3a40 3/3: Use the 'field' property to navigate through Eshell prompts
Date: Sat, 14 Jan 2023 14:30:12 -0500 (EST)

branch: master
commit c257fd3a406d6aa83be60b96217e42b49b62cf5f
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Jim Porter <jporterbugs@gmail.com>

    Use the 'field' property to navigate through Eshell prompts
    
    * lisp/eshell/esh-mode.el (eshell-skip-prompt-function): Make
    obsolete.
    
    * lisp/eshell/em-prompt.el (eshell-prompt-regexp): Update docstring.
    (eshell-prompt-initialize): Don't set 'eshell-skip-prompt-function'.
    (eshell-next-prompt): Search for the 'field' property set to 'prompt'
    to find the next prompt.
    (eshell-previous-prompt): Move 'forward-line' call into
    'eshell-next-prompt'.
    (eshell-forward-matching-input, eshell-backward-matching-input):
    Reimplement on top of 'eshell-next-prompt'.
    (eshell-skip-prompt): Make obsolete.
    
    * test/lisp/eshell/em-prompt-tests.el
    (em-prompt-test/next-previous-prompt): New test.
---
 lisp/eshell/em-prompt.el            | 88 ++++++++++++++++++-------------------
 lisp/eshell/esh-mode.el             |  2 +
 test/lisp/eshell/em-prompt-tests.el | 37 ++++++++++++++++
 3 files changed, 83 insertions(+), 44 deletions(-)

diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el
index 5a89ff35a2..52d46282c5 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -29,6 +29,8 @@
 (require 'esh-mode)
 (eval-when-compile (require 'eshell))
 
+(require 'text-property-search)
+
 ;;;###autoload
 (progn
 (defgroup eshell-prompt nil
@@ -58,11 +60,12 @@ prompt."
   :group 'eshell-prompt)
 
 (defcustom eshell-prompt-regexp "^[^#$\n]* [#$] "
-  "A regexp which fully matches your eshell prompt.
-This setting is important, since it affects how eshell will interpret
-the lines that are passed to it.
-If this variable is changed, all Eshell buffers must be exited and
-re-entered for it to take effect."
+  "A regexp which fully matches your Eshell prompt.
+This is useful for navigating by paragraph using \
+\\[forward-paragraph] and \\[backward-paragraph].
+
+If this variable is changed, all Eshell buffers must be exited
+and re-entered for it to take effect."
   :type 'regexp
   :group 'eshell-prompt)
 
@@ -123,7 +126,6 @@ arriving, or after."
     (if eshell-prompt-regexp
         (setq-local paragraph-start eshell-prompt-regexp))
 
-    (setq-local eshell-skip-prompt-function #'eshell-skip-prompt)
     (eshell-prompt-mode)))
 
 (defun eshell-emit-prompt ()
@@ -149,57 +151,55 @@ arriving, or after."
       (eshell-interactive-filter nil prompt)))
   (run-hooks 'eshell-after-prompt-hook))
 
-(defun eshell-backward-matching-input (regexp arg)
-  "Search backward through buffer for match for REGEXP.
-Matches are searched for on lines that match `eshell-prompt-regexp'.
-With prefix argument N, search for Nth previous match.
-If N is negative, find the next or Nth next match."
-  (interactive (eshell-regexp-arg "Backward input matching (regexp): "))
-  (let* ((re (concat eshell-prompt-regexp ".*" regexp))
-        (pos (save-excursion (end-of-line (if (> arg 0) 0 1))
-                             (if (re-search-backward re nil t arg)
-                                 (point)))))
-    (if (null pos)
-       (progn (message "Not found")
-              (ding))
-      (goto-char pos)
-      (beginning-of-line))))
-
 (defun eshell-forward-matching-input (regexp arg)
-  "Search forward through buffer for match for REGEXP.
-Matches are searched for on lines that match `eshell-prompt-regexp'.
-With prefix argument N, search for Nth following match.
-If N is negative, find the previous or Nth previous match."
+  "Search forward through buffer for command input that matches REGEXP.
+With prefix argument N, search for Nth next match.  If N is
+negative, find the Nth previous match."
   (interactive (eshell-regexp-arg "Forward input matching (regexp): "))
-  (eshell-backward-matching-input regexp (- arg)))
+  (let ((direction (if (> arg 0) 1 -1))
+        (count (abs arg)))
+    (unless (catch 'found
+              (while (> count 0)
+                (eshell-next-prompt direction)
+                (when (and (string-match regexp (field-string))
+                           (= (setq count (1- count)) 0))
+                  (throw 'found t))))
+      (message "Not found")
+      (ding))))
+
+(defun eshell-backward-matching-input (regexp arg)
+  "Search backward through buffer for command input that matches REGEXP.
+With prefix argument N, search for Nth previous match.  If N is
+negative, find the Nth next match."
+  (interactive (eshell-regexp-arg "Backward input matching (regexp): "))
+  (eshell-forward-matching-input regexp (- arg)))
 
 (defun eshell-next-prompt (n)
-  "Move to end of Nth next prompt in the buffer.
-See `eshell-prompt-regexp'."
+  "Move to end of Nth next prompt in the buffer."
   (interactive "p")
-  (if eshell-highlight-prompt
-      (progn
-        (while (< n 0)
-          (while (and (re-search-backward eshell-prompt-regexp nil t)
-                      (not (get-text-property (match-beginning 0) 
'read-only))))
-          (setq n (1+ n)))
-        (while (> n 0)
-          (while (and (re-search-forward eshell-prompt-regexp nil t)
-                      (not (get-text-property (match-beginning 0) 
'read-only))))
-          (setq n (1- n))))
-    (re-search-forward eshell-prompt-regexp nil t n))
-  (eshell-skip-prompt))
+  (if (natnump n)
+      (while (and (> n 0)
+                  (text-property-search-forward 'field 'prompt t))
+        (setq n (1- n)))
+    (let (match this-match)
+      (forward-line 0)           ; Don't count prompt on current line.
+      (while (and (< n 0)
+                  (setq this-match (text-property-search-backward
+                                    'field 'prompt t)))
+        (setq match this-match
+              n (1+ n)))
+      (when match
+        (goto-char (prop-match-end match))))))
 
 (defun eshell-previous-prompt (n)
-  "Move to end of Nth previous prompt in the buffer.
-See `eshell-prompt-regexp'."
+  "Move to end of Nth previous prompt in the buffer."
   (interactive "p")
-  (forward-line 0)            ; Don't count prompt on current line.
   (eshell-next-prompt (- n)))
 
 (defun eshell-skip-prompt ()
   "Skip past the text matching regexp `eshell-prompt-regexp'.
 If this takes us past the end of the current line, don't skip at all."
+  (declare (obsolete nil "30.1"))
   (let ((eol (line-end-position)))
     (if (and (looking-at eshell-prompt-regexp)
             (<= (match-end 0) eol))
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index 90e003d188..503d9ba1b6 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -176,6 +176,8 @@ This is used by `eshell-watch-for-password-prompt'."
   "A function called from beginning of line to skip the prompt."
   :type '(choice (const nil) function))
 
+(make-obsolete-variable 'eshell-skip-prompt-function nil "30.1")
+
 (defcustom eshell-status-in-mode-line t
   "If non-nil, let the user know a command is running in the mode line."
   :type 'boolean)
diff --git a/test/lisp/eshell/em-prompt-tests.el 
b/test/lisp/eshell/em-prompt-tests.el
index 695cb1bab2..91464a98c2 100644
--- a/test/lisp/eshell/em-prompt-tests.el
+++ b/test/lisp/eshell/em-prompt-tests.el
@@ -78,4 +78,41 @@ This tests the case when `eshell-highlight-prompt' is nil."
                 (propertize "hello\n" 'rear-nonsticky '(field)
                             'field 'command-output)))))))
 
+(ert-deftest em-prompt-test/next-previous-prompt ()
+  "Check that navigating forward/backward through old prompts works correctly."
+  (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-deftest em-prompt-test/forward-backward-matching-input ()
+  "Check that navigating forward/backward via regexps works correctly."
+  (with-temp-eshell
+   (eshell-insert-command "echo one")
+   (eshell-insert-command "printnl something else")
+   (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"))))
+
 ;;; em-prompt-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]