unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Ashton Wiersdorf <ashton@wiersdorfmail.net>, 74230@debbugs.gnu.org
Cc: eliz@gnu.org
Subject: bug#74230: 30.0.92; eshell-emit-prompt clobbers text properties
Date: Thu, 7 Nov 2024 10:16:16 -0800	[thread overview]
Message-ID: <42bd1d73-8faf-b12b-e3c3-06c814d395a4@gmail.com> (raw)
In-Reply-To: <m2zfmc6x6a.fsf@wiersdorfmail.net>

[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]

On 11/6/2024 10:21 AM, Ashton Wiersdorf wrote:
> In Emacs 29.4, the function did *not* overwrite the text properties of
> the prompt `rear-nonsticky (read-only)`. The new version overwrites the
> rear-nonsticky property so that it is only `(field)`.

Thanks for noticing this.

> If I set `eshell-highlight-prompt' to `t', then I get the read-only
> behavior that I want, but now I cannot get the pleasant component
> highlighting that `fancy-shell' is meant to provide.

If you set the 'face' attribute instead of the 'font-lock-face' 
attribute, you should get the highlighting you want (that's what I do) 
while 'eshell-highlight-prompt' is non-nil.

Here's a patch to fix this though so that we're more careful about not 
clobbering stickiness properties. Eli, what do you think about this 
patch? It fixes a regression from Emacs 29, but the diff is fairly large 
for so late in the Emacs 30 cycle. Unfortunately, I can't think of a 
better solution that doesn't just shuffle the bug around to a different 
spot. On the plus side, this code already has regression tests, and it 
was easy to add a new one for this case.

Personally, I'd be ok with having this be a known bug (there's a 
workaround for Emacs 30) and fixing it on master. But if you think this 
change is ok for the release branch, I'd also be ok with installing 
there; then people don't need to deal with the workaround.

[-- Attachment #2: 0001-Don-t-clobber-stickiness-text-properties-when-printi.patch --]
[-- Type: text/plain, Size: 5857 bytes --]

From 8b8e4830f45e69329018bc87121e12ee6ddfb9d4 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Thu, 7 Nov 2024 10:08:33 -0800
Subject: [PATCH] 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).
---
 lisp/eshell/em-prompt.el            | 36 ++++++++++++++++++-----------
 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 @@ eshell-prompt-initialize
     (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 @@ eshell-emit-prompt
   (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))
 
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 @@ em-prompt-test/field-properties
                '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 @@ em-prompt-test/field-properties/no-highlight
                 (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 @@ em-prompt-test/after-failure
                '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
-- 
2.25.1


  reply	other threads:[~2024-11-07 18:16 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-06 18:21 bug#74230: 30.0.92; eshell-emit-prompt clobbers text properties Ashton Wiersdorf
2024-11-07 18:16 ` Jim Porter [this message]
2024-11-14  8:52   ` Eli Zaretskii
2024-11-14 18:33     ` Jim Porter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=42bd1d73-8faf-b12b-e3c3-06c814d395a4@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=74230@debbugs.gnu.org \
    --cc=ashton@wiersdorfmail.net \
    --cc=eliz@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).