(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)
(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))
'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
(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
'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)))))))
\f
;; Prompt navigation