diff options
| author | Jim Porter | 2024-11-07 10:08:33 -0800 |
|---|---|---|
| committer | Jim Porter | 2024-11-14 09:19:31 -0800 |
| commit | df288d2e4148e6e72f21752a510f98536e7705ac (patch) | |
| tree | 33b272e891ecababf896a7b0da46b640146ded8f | |
| parent | e30c83e166634e8cdfc9577b982deb7cc2619067 (diff) | |
| download | emacs-df288d2e4148e6e72f21752a510f98536e7705ac.tar.gz emacs-df288d2e4148e6e72f21752a510f98536e7705ac.zip | |
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).
| -rw-r--r-- | lisp/eshell/em-prompt.el | 36 | ||||
| -rw-r--r-- | test/lisp/eshell/em-prompt-tests.el | 35 |
2 files changed, 54 insertions, 17 deletions
diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el index de62b5c7d97..37970ac0ba5 100644 --- a/lisp/eshell/em-prompt.el +++ b/lisp/eshell/em-prompt.el | |||
| @@ -119,6 +119,19 @@ arriving, or after." | |||
| 119 | (add-hook 'eshell-post-command-hook 'eshell-emit-prompt nil t) | 119 | (add-hook 'eshell-post-command-hook 'eshell-emit-prompt nil t) |
| 120 | (eshell-prompt-mode))) | 120 | (eshell-prompt-mode))) |
| 121 | 121 | ||
| 122 | (defun eshell--append-text-property (start end prop value &optional object) | ||
| 123 | "Append to a text property from START to END. | ||
| 124 | PROP is the text property to append to, and VALUE is the list of | ||
| 125 | property values to append. OBJECT is the object to propertize, as with | ||
| 126 | `put-text-property' (which see)." | ||
| 127 | (let (next) | ||
| 128 | (while (< start end) | ||
| 129 | (setq next (next-single-property-change start prop object end)) | ||
| 130 | (put-text-property start next prop | ||
| 131 | (append (get-text-property start prop object) value) | ||
| 132 | object) | ||
| 133 | (setq start next)))) | ||
| 134 | |||
| 122 | (defun eshell-emit-prompt () | 135 | (defun eshell-emit-prompt () |
| 123 | "Emit a prompt if eshell is being used interactively." | 136 | "Emit a prompt if eshell is being used interactively." |
| 124 | (when (boundp 'ansi-color-context-region) | 137 | (when (boundp 'ansi-color-context-region) |
| @@ -126,19 +139,16 @@ arriving, or after." | |||
| 126 | (run-hooks 'eshell-before-prompt-hook) | 139 | (run-hooks 'eshell-before-prompt-hook) |
| 127 | (if (not eshell-prompt-function) | 140 | (if (not eshell-prompt-function) |
| 128 | (set-marker eshell-last-output-end (point)) | 141 | (set-marker eshell-last-output-end (point)) |
| 129 | (let ((prompt (funcall eshell-prompt-function))) | 142 | (let* ((prompt (funcall eshell-prompt-function)) |
| 130 | (add-text-properties | 143 | (len (length prompt)) |
| 131 | 0 (length prompt) | 144 | (sticky-props '(field))) |
| 132 | (if eshell-highlight-prompt | 145 | (put-text-property 0 len 'field 'prompt prompt) |
| 133 | '( read-only t | 146 | (when eshell-highlight-prompt |
| 134 | field prompt | 147 | (add-text-properties |
| 135 | font-lock-face eshell-prompt | 148 | 0 len '(read-only t font-lock-face eshell-prompt) prompt) |
| 136 | front-sticky (read-only field font-lock-face) | 149 | (setq sticky-props `(read-only font-lock-face . ,sticky-props))) |
| 137 | rear-nonsticky (read-only field font-lock-face)) | 150 | (eshell--append-text-property 0 len 'front-sticky sticky-props prompt) |
| 138 | '( field prompt | 151 | (eshell--append-text-property 0 len 'rear-nonsticky sticky-props prompt) |
| 139 | front-sticky (field) | ||
| 140 | rear-nonsticky (field))) | ||
| 141 | prompt) | ||
| 142 | (eshell-interactive-filter nil prompt))) | 152 | (eshell-interactive-filter nil prompt))) |
| 143 | (run-hooks 'eshell-after-prompt-hook)) | 153 | (run-hooks 'eshell-after-prompt-hook)) |
| 144 | 154 | ||
diff --git a/test/lisp/eshell/em-prompt-tests.el b/test/lisp/eshell/em-prompt-tests.el index fbadade061f..1c6e8e02293 100644 --- a/test/lisp/eshell/em-prompt-tests.el +++ b/test/lisp/eshell/em-prompt-tests.el | |||
| @@ -57,8 +57,8 @@ | |||
| 57 | 'read-only t | 57 | 'read-only t |
| 58 | 'field 'prompt | 58 | 'field 'prompt |
| 59 | 'font-lock-face 'eshell-prompt | 59 | 'font-lock-face 'eshell-prompt |
| 60 | 'front-sticky '(read-only field font-lock-face) | 60 | 'front-sticky '(read-only font-lock-face field) |
| 61 | 'rear-nonsticky '(read-only field font-lock-face)))) | 61 | 'rear-nonsticky '(read-only font-lock-face field)))) |
| 62 | (should (equal last-input "echo hello\n")) | 62 | (should (equal last-input "echo hello\n")) |
| 63 | (should (equal-including-properties | 63 | (should (equal-including-properties |
| 64 | last-output | 64 | last-output |
| @@ -88,6 +88,33 @@ This tests the case when `eshell-highlight-prompt' is nil." | |||
| 88 | (apply #'propertize "hello\n" | 88 | (apply #'propertize "hello\n" |
| 89 | eshell-command-output-properties))))))) | 89 | eshell-command-output-properties))))))) |
| 90 | 90 | ||
| 91 | (ert-deftest em-prompt-test/field-properties/merge-stickiness () | ||
| 92 | "Check that stickiness properties are properly merged on Eshell prompts." | ||
| 93 | (let ((eshell-prompt-function | ||
| 94 | (lambda () | ||
| 95 | (concat (propertize (eshell/pwd) 'front-sticky '(front)) | ||
| 96 | (propertize "$ " 'rear-nonsticky '(rear)))))) | ||
| 97 | (with-temp-eshell | ||
| 98 | (eshell-insert-command "echo hello") | ||
| 99 | (let ((last-prompt (field-string (1- eshell-last-input-start)))) | ||
| 100 | (should (equal-including-properties | ||
| 101 | last-prompt | ||
| 102 | (concat | ||
| 103 | (propertize | ||
| 104 | (directory-file-name default-directory) | ||
| 105 | 'read-only t | ||
| 106 | 'field 'prompt | ||
| 107 | 'font-lock-face 'eshell-prompt | ||
| 108 | 'front-sticky '(front read-only font-lock-face field) | ||
| 109 | 'rear-nonsticky '(read-only font-lock-face field)) | ||
| 110 | (propertize | ||
| 111 | "$ " | ||
| 112 | 'read-only t | ||
| 113 | 'field 'prompt | ||
| 114 | 'font-lock-face 'eshell-prompt | ||
| 115 | 'front-sticky '(read-only font-lock-face field) | ||
| 116 | 'rear-nonsticky '(rear read-only font-lock-face field))))))))) | ||
| 117 | |||
| 91 | (ert-deftest em-prompt-test/after-failure () | 118 | (ert-deftest em-prompt-test/after-failure () |
| 92 | "Check that current prompt shows the exit code of the last failed command." | 119 | "Check that current prompt shows the exit code of the last failed command." |
| 93 | (with-temp-eshell | 120 | (with-temp-eshell |
| @@ -104,8 +131,8 @@ This tests the case when `eshell-highlight-prompt' is nil." | |||
| 104 | 'read-only t | 131 | 'read-only t |
| 105 | 'field 'prompt | 132 | 'field 'prompt |
| 106 | 'font-lock-face 'eshell-prompt | 133 | 'font-lock-face 'eshell-prompt |
| 107 | 'front-sticky '(read-only field font-lock-face) | 134 | 'front-sticky '(read-only font-lock-face field) |
| 108 | 'rear-nonsticky '(read-only field font-lock-face))))))) | 135 | 'rear-nonsticky '(read-only font-lock-face field))))))) |
| 109 | 136 | ||
| 110 | 137 | ||
| 111 | ;; Prompt navigation | 138 | ;; Prompt navigation |