@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, , ,
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
'(("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
"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
"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>\".
(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>."
(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
(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
"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