1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-21 06:55:39 +00:00

Don't clobber stickiness text properties when printing Eshell prompt

* lisp/eshell/em-prompt.el (eshell--append-text-property): New
function...
(eshell-emit-prompt): ... use it.

* test/lisp/eshell/em-prompt-tests.el
(em-prompt-test/field-properties/merge-stickiness): New test.
(em-prompt-test/field-properties, em-prompt-test/after-failure): Reorder
stickiness values (bug#74230).
This commit is contained in:
Jim Porter 2024-11-07 10:08:33 -08:00
parent e30c83e166
commit df288d2e41
2 changed files with 54 additions and 17 deletions

View File

@ -119,6 +119,19 @@ arriving, or after."
(add-hook 'eshell-post-command-hook 'eshell-emit-prompt nil t)
(eshell-prompt-mode)))
(defun eshell--append-text-property (start end prop value &optional object)
"Append to a text property from START to END.
PROP is the text property to append to, and VALUE is the list of
property values to append. OBJECT is the object to propertize, as with
`put-text-property' (which see)."
(let (next)
(while (< start end)
(setq next (next-single-property-change start prop object end))
(put-text-property start next prop
(append (get-text-property start prop object) value)
object)
(setq start next))))
(defun eshell-emit-prompt ()
"Emit a prompt if eshell is being used interactively."
(when (boundp 'ansi-color-context-region)
@ -126,19 +139,16 @@ arriving, or after."
(run-hooks 'eshell-before-prompt-hook)
(if (not eshell-prompt-function)
(set-marker eshell-last-output-end (point))
(let ((prompt (funcall eshell-prompt-function)))
(add-text-properties
0 (length prompt)
(if eshell-highlight-prompt
'( read-only t
field prompt
font-lock-face eshell-prompt
front-sticky (read-only field font-lock-face)
rear-nonsticky (read-only field font-lock-face))
'( field prompt
front-sticky (field)
rear-nonsticky (field)))
prompt)
(let* ((prompt (funcall eshell-prompt-function))
(len (length prompt))
(sticky-props '(field)))
(put-text-property 0 len 'field 'prompt prompt)
(when eshell-highlight-prompt
(add-text-properties
0 len '(read-only t font-lock-face eshell-prompt) prompt)
(setq sticky-props `(read-only font-lock-face . ,sticky-props)))
(eshell--append-text-property 0 len 'front-sticky sticky-props prompt)
(eshell--append-text-property 0 len 'rear-nonsticky sticky-props prompt)
(eshell-interactive-filter nil prompt)))
(run-hooks 'eshell-after-prompt-hook))

View File

@ -57,8 +57,8 @@
'read-only t
'field 'prompt
'font-lock-face 'eshell-prompt
'front-sticky '(read-only field font-lock-face)
'rear-nonsticky '(read-only field font-lock-face))))
'front-sticky '(read-only font-lock-face field)
'rear-nonsticky '(read-only font-lock-face field))))
(should (equal last-input "echo hello\n"))
(should (equal-including-properties
last-output
@ -88,6 +88,33 @@ This tests the case when `eshell-highlight-prompt' is nil."
(apply #'propertize "hello\n"
eshell-command-output-properties)))))))
(ert-deftest em-prompt-test/field-properties/merge-stickiness ()
"Check that stickiness properties are properly merged on Eshell prompts."
(let ((eshell-prompt-function
(lambda ()
(concat (propertize (eshell/pwd) 'front-sticky '(front))
(propertize "$ " 'rear-nonsticky '(rear))))))
(with-temp-eshell
(eshell-insert-command "echo hello")
(let ((last-prompt (field-string (1- eshell-last-input-start))))
(should (equal-including-properties
last-prompt
(concat
(propertize
(directory-file-name default-directory)
'read-only t
'field 'prompt
'font-lock-face 'eshell-prompt
'front-sticky '(front read-only font-lock-face field)
'rear-nonsticky '(read-only font-lock-face field))
(propertize
"$ "
'read-only t
'field 'prompt
'font-lock-face 'eshell-prompt
'front-sticky '(read-only font-lock-face field)
'rear-nonsticky '(rear read-only font-lock-face field)))))))))
(ert-deftest em-prompt-test/after-failure ()
"Check that current prompt shows the exit code of the last failed command."
(with-temp-eshell
@ -104,8 +131,8 @@ This tests the case when `eshell-highlight-prompt' is nil."
'read-only t
'field 'prompt
'font-lock-face 'eshell-prompt
'front-sticky '(read-only field font-lock-face)
'rear-nonsticky '(read-only field font-lock-face)))))))
'front-sticky '(read-only font-lock-face field)
'rear-nonsticky '(read-only font-lock-face field)))))))
;; Prompt navigation