]> git.eshelyaron.com Git - emacs.git/commitdiff
Add a new Eshell special reference type for markers
authorJim Porter <jporterbugs@gmail.com>
Tue, 10 Oct 2023 03:25:28 +0000 (20:25 -0700)
committerJim Porter <jporterbugs@gmail.com>
Tue, 24 Oct 2023 19:28:00 +0000 (12:28 -0700)
* lisp/eshell/esh-arg.el (eshell-get-marker, eshell-insert-marker)
(eshell-complete-marker-ref): New functions...
(eshell-special-ref-alist): ... Add them to the new "marker" entry.

* test/lisp/eshell/esh-arg-tests.el
(esh-arg-test/special-reference/marker)
(esh-arg-test/special-reference/nested)
(esh-arg-test/special-reference/lisp-form):
* test/lisp/eshell/em-cmpl-tests.el
(em-cmpl-test/special-ref-completion/type)
(em-cmpl-test/special-ref-completion/marker): New tests.

* doc/misc/eshell.texi (Arguments): Document the new special ref type.

* etc/NEWS: Announce this change (bug#66458).

doc/misc/eshell.texi
etc/NEWS
lisp/eshell/esh-arg.el
test/lisp/eshell/em-cmpl-tests.el
test/lisp/eshell/esh-arg-tests.el

index b5cc9faeec20bdbf6683fbf6166cb15fe5edfad8..e8aa8cdc6a3d2daaaebf9a9327ebe3b4bc9ce4e5 100644 (file)
@@ -400,6 +400,14 @@ Return the buffer named @var{name}.  This is equivalent to
 @samp{$(get-buffer-create "@var{name}")} (@pxref{Creating Buffers, , ,
 elisp, The Emacs Lisp Reference Manual}).
 
+@item #<marker @var{position} @var{buffer-or-name}>
+Return a marker at @var{position} in the buffer @var{buffer-or-name}.
+@var{buffer-or-name} can either be a string naming a buffer or an
+actual buffer object.  This is roughly equivalent to creating a new
+marker and calling @samp{$(set-marker marker @var{position}
+@var{buffer-or-name})} (@pxref{Moving Markers, , , elisp, The Emacs
+Lisp Reference Manual}).
+
 @item #<process @var{name}>
 Return the process named @var{name}.  This is equivalent to
 @samp{$(get-process "@var{name}")} (@pxref{Process Information, , ,
index e6c476605221fba024c32332f8b782822fd9fc1c..29744d3ad77133e2984ae7494b9d4ae7b45cd2a0 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -430,6 +430,14 @@ appropriate, but still allow piping the output elsewhere if desired.
 For more information, see the "(eshell) Built-ins" node in the Eshell
 manual.
 
++++
+*** New special reference type '#<marker POSITION BUFFER>'.
+This special reference type returns a marker at 'POSITION' in
+'BUFFER'.  You can insert it by typing or using the new interactive
+command 'eshell-insert-marker'.  You can also insert markers of any
+type with the new command 'eshell-insert-special-reference'.  See the
+"(eshell) Arguments" node in the Eshell manual for more details.
+
 +++
 *** New splice operator for Eshell dollar expansions.
 Dollar expansions in Eshell now let you splice the elements of the
index d5fcabccb14bd8e53ad2d1429ff7682a21c08d79..2bdfdff8a3a449223edf6e76f31f0d5da9f0a4e8 100644 (file)
@@ -169,7 +169,11 @@ treated as a literal character."
   '(("buffer"
      (creation-function   eshell-get-buffer)
      (insertion-function  eshell-insert-buffer-name)
-     (completion-function eshell-complete-buffer-ref)))
+     (completion-function eshell-complete-buffer-ref))
+    ("marker"
+     (creation-function   eshell-get-marker)
+     (insertion-function  eshell-insert-marker)
+     (completion-function eshell-complete-marker-ref)))
   "Alist of special reference types for Eshell.
 Each entry is a list of the form (TYPE (KEY VALUE)...).  TYPE is
 the name of the special reference type, and each KEY/VALUE pair
@@ -717,5 +721,26 @@ single argument."
   "Perform completion for buffer references."
   (pcomplete-here (mapcar #'buffer-name (buffer-list))))
 
+(defun eshell-get-marker (position buffer-or-name)
+  "Return the marker for character number POSITION in BUFFER-OR-NAME.
+BUFFER-OR-NAME can be a buffer or a string.  If a string and a
+live buffer with that name exists, use that buffer.  If no such
+buffer exists, create a new buffer with that name and use it."
+  (let ((marker (make-marker)))
+    (set-marker marker (string-to-number position)
+                (get-buffer-create buffer-or-name))))
+
+(defun eshell-insert-marker (position buffer-name)
+  "Insert a marker into the current buffer at point.
+This marker will point to POSITION in BUFFER-NAME."
+  (interactive "nPosition: \nBName of buffer: ")
+  (insert-and-inherit "#<marker " (number-to-string position) " "
+                      (eshell-quote-argument buffer-name) ">"))
+
+(defun eshell-complete-marker-ref ()
+  "Perform completion for marker references."
+  (pcomplete-here)
+  (pcomplete-here (mapcar #'buffer-name (buffer-list))))
+
 (provide 'esh-arg)
 ;;; esh-arg.el ends here
index 29a41625d5e476eeef8bd2528c6885b00f839e43..dd3c338ac5435fc47189eb286943beedb3bb4d9c 100644 (file)
@@ -243,14 +243,17 @@ See <lisp/eshell/esh-cmd.el>."
                   "echo $(eshell/echo"))))
 
 (ert-deftest em-cmpl-test/special-ref-completion/type ()
-  "Test completion of the start of special references like \"#<buffer\".
+  "Test completion of the start of special reference types like \"#<buffer\".
 See <lisp/eshell/esh-arg.el>."
   (with-temp-eshell
    (should (equal (eshell-insert-and-complete "echo hi > #<buf")
                   "echo hi > #<buffer ")))
   (with-temp-eshell
    (should (equal (eshell-insert-and-complete "echo hi > #<proc")
-                  "echo hi > #<process "))))
+                  "echo hi > #<process ")))
+  (with-temp-eshell
+   (should (equal (eshell-insert-and-complete "echo hi > #<mark")
+                  "echo hi > #<marker "))))
 
 (ert-deftest em-cmpl-test/special-ref-completion/implicit-buffer ()
   "Test completion of special references like \"#<buf>\".
@@ -282,6 +285,31 @@ See <lisp/eshell/esh-arg.el>."
                       (format "echo hi > #<buffer %s> "
                               (string-replace " " "\\ " bufname))))))))
 
+(ert-deftest em-cmpl-test/special-ref-completion/marker ()
+  "Test completion of special references like \"#<marker 1 buf>\".
+See <lisp/eshell/esh-arg.el>."
+  (let (bufname)
+    (with-temp-buffer
+      (setq bufname (rename-buffer "my-buffer" t))
+      ;; Complete the buffer name in various forms.
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 my-buf")
+                      (format "echo hi > #<marker 1 %s> " bufname))))
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 #<my-buf")
+                      (format "echo hi > #<marker 1 #<%s>> " bufname))))
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 #<buffer my-buf")
+                      (format "echo hi > #<marker 1 #<buffer %s>> " bufname))))
+      ;; Partially-complete the "buffer" type name.
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 #<buf")
+                      "echo hi > #<marker 1 #<buffer "))))))
+
 (ert-deftest em-cmpl-test/variable-ref-completion ()
   "Test completion of variable references like \"$var\".
 See <lisp/eshell/esh-var.el>."
index 0e07d10756208d77e879375478ffc393b962f8f7..1eb8e08b88331f4d328445ed6f59595714ffb82c 100644 (file)
@@ -118,6 +118,17 @@ treated literally, as a backslash and a newline."
      (format "echo #<buffer %s>" (buffer-name))
      (current-buffer))))
 
+(ert-deftest esh-arg-test/special-reference/marker ()
+  "Test that \"#<marker N buf>\" refers to a marker in the buffer \"buf\"."
+  (with-temp-buffer
+    (rename-buffer "my-buffer" t)
+    (insert "hello")
+    (let ((marker (make-marker)))
+      (set-marker marker 1 (current-buffer))
+      (eshell-command-result-equal
+       (format "echo #<marker 1 %s>" (buffer-name))
+       marker))))
+
 (ert-deftest esh-arg-test/special-reference/quoted ()
   "Test that '#<buffer \"foo bar\">' refers to the buffer \"foo bar\"."
   (with-temp-buffer
@@ -129,6 +140,20 @@ treated literally, as a backslash and a newline."
      (format "echo #<buffer '%s'>" (buffer-name))
      (current-buffer))))
 
+(ert-deftest esh-arg-test/special-reference/nested ()
+  "Test that nested special references work correctly."
+  (with-temp-buffer
+    (rename-buffer "my-buffer" t)
+    (insert "hello")
+    (let ((marker (make-marker)))
+      (set-marker marker 1 (current-buffer))
+      (eshell-command-result-equal
+       (format "echo #<marker 1 #<%s>>" (buffer-name))
+       marker)
+      (eshell-command-result-equal
+       (format "echo #<marker 1 #<buffer %s>>" (buffer-name))
+       marker))))
+
 (ert-deftest esh-arg-test/special-reference/var-expansion ()
   "Test that variable expansion inside special references works."
   (with-temp-buffer
@@ -141,6 +166,19 @@ treated literally, as a backslash and a newline."
        "echo #<buffer \"$eshell-test-value\">"
        (current-buffer)))))
 
+(ert-deftest esh-arg-test/special-reference/lisp-form ()
+  "Test that Lisp forms inside special references work."
+  (with-temp-eshell
+   (let ((marker (make-marker))
+         eshell-test-value)
+     (set-marker marker 1 (current-buffer))
+     (eshell-insert-command
+      "setq eshell-test-value #<marker 1 (current-buffer)>")
+     (should (equal eshell-test-value marker))
+     (eshell-insert-command
+      "setq eshell-test-value #<marker 1 #<buffer (buffer-name)>>")
+     (should (equal eshell-test-value marker)))))
+
 (ert-deftest esh-arg-test/special-reference/special-characters ()
   "Test that \"#<...>\" works correctly when escaping special characters."
   (with-temp-buffer