From: miha--- via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Lars Ingebrigtsen <larsi@gnus.org>
Cc: 3735@debbugs.gnu.org, dsb@smart.net, Chong Yidong <cyd@gnu.org>,
18135@debbugs.gnu.org, Don Hopkins <don@donhopkins.com>
Subject: bug#18135: bug#3735: shell-mode editing, movement, and command entry broken by prompt/output changes
Date: Tue, 07 Dec 2021 17:57:34 +0100 [thread overview]
Message-ID: <878rww4akh.fsf@miha-pc> (raw)
In-Reply-To: <8735n6svhn.fsf@gnus.org>
[-- Attachment #1.1: Type: text/plain, Size: 1305 bytes --]
Lars Ingebrigtsen <larsi@gnus.org> writes:
> miha@kamnitnik.top writes:
>
>> Reproducer:
>>
>> - copy " -la" into kill ring
>> - type "echo ls" into M-x shell
>> - (Shell gives output line "ls".)
>> - Go up to output line "ls" (C-p).
>> - yank " -la"
>> - press C-b
>> - the line now "ls -la" with point after "l"
>> - press RET
>>
>> Only " -la" is sent to the process instead of "ls -la"
>
> Thanks; with that I'm also able to reproduce the problem.
>
>> I am willing to write up a patch to fix this. I'm thinking of having
>> comint-mode register a function in after-change-functions to mark text
>> inserted in the 'output' field as 'output'. Would this be okay or are
>> there any obvious flaws with this approach?
>
> I think that sounds like a promising approach, but I wonder whether
> something could be done with rear-nonsticky here. `field' isn't
> rear-sticky here for probably good reasons, but perhaps something
> could be tweaked there? (I haven't actually tried, though.)
Yeah I thought about that too. However, commands such as 'yank' or
'just-one-space' use insert rather than insert-and-inherit and thus
always bypass inheritance of surrounding text properties regardless of
it's stickiness. That is why I settled for using the
'insert-in-front-hooks' text property, patch attached.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-Improve-yanking-in-the-middle-of-comint-process-outp.patch --]
[-- Type: text/x-patch, Size: 4576 bytes --]
From 7914fe85ba096f93d4b6817bc0d7b7976f3d316a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miha=20Rihtar=C5=A1i=C4=8D?= <miha@kamnitnik.top>
Date: Tue, 7 Dec 2021 16:59:39 +0100
Subject: [PATCH] Improve yanking in the middle of comint process output
* lisp/comint.el
(comint--unmark-string-as-output): New function to remove unwanted
properties from text yanked from comint buffers.
(comint-mode): Use it as a 'filter-buffer-substring-function'.
(comint-output-filter): Set 'insert-in-front-hooks' text property on
process output such that text yanked by the user in the middle of
process output is marked as process output (Bug#3735).
(comint--mark-as-output): New function.
(comint--mark-yanked-as-output): New function.
---
lisp/comint.el | 54 +++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 45 insertions(+), 9 deletions(-)
diff --git a/lisp/comint.el b/lisp/comint.el
index 544f0b8b82..5f99f560cf 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -730,6 +730,8 @@ comint-mode
(or (file-remote-p default-directory) ""))
(setq-local comint-accum-marker (make-marker))
(setq-local font-lock-defaults '(nil t))
+ (add-function :filter-return (local 'filter-buffer-substring-function)
+ #'comint--unmark-string-as-output)
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
(add-hook 'isearch-mode-hook 'comint-history-isearch-setup nil t)
(add-hook 'completion-at-point-functions 'comint-completion-at-point nil t)
@@ -1815,7 +1817,8 @@ comint-add-to-input-history
(ring-insert comint-input-ring cmd)))
(defconst comint--prompt-rear-nonsticky
- '(field inhibit-line-move-field-capture read-only font-lock-face)
+ '( field inhibit-line-move-field-capture read-only font-lock-face
+ insert-in-front-hooks)
"Text properties we set on the prompt and don't want to leak past it.")
(defun comint-send-input (&optional no-newline artificial)
@@ -2152,14 +2155,7 @@ comint-output-filter
(goto-char (process-mark process)) ; In case a filter moved it.
(unless comint-use-prompt-regexp
- (with-silent-modifications
- (add-text-properties comint-last-output-start (point)
- `(rear-nonsticky
- ,comint--prompt-rear-nonsticky
- front-sticky
- (field inhibit-line-move-field-capture)
- field output
- inhibit-line-move-field-capture t))))
+ (comint--mark-as-output comint-last-output-start (point)))
;; Highlight the prompt, where we define `prompt' to mean
;; the most recent output that doesn't end with a newline.
@@ -2191,6 +2187,46 @@ comint-output-filter
,comint--prompt-rear-nonsticky)))
(goto-char saved-point)))))))
+(defun comint--mark-as-output (beg end)
+ (with-silent-modifications
+ (add-text-properties
+ beg end
+ `(rear-nonsticky
+ ,comint--prompt-rear-nonsticky
+ front-sticky
+ (field inhibit-line-move-field-capture)
+ field output
+ inhibit-line-move-field-capture t
+ ;; Text inserted by a user in the middle of process output
+ ;; should be marked as output. This is needed for commands
+ ;; such as `yank' or `just-one-space' which don't use
+ ;; `insert-and-inherit' and thus bypass default text property
+ ;; inheritance.
+ insert-in-front-hooks
+ (,#'comint--mark-as-output ,#'comint--mark-yanked-as-output)))))
+
+(defun comint--mark-yanked-as-output (beg end)
+ ;; `yank' removes the field text property from the text it inserts
+ ;; due to `yank-excluded-properties', so arrange for this text
+ ;; property to be reapplied in the `after-change-functions'.
+ (let (fun)
+ (setq
+ fun
+ (lambda (beg1 end1 _len1)
+ (remove-hook 'after-change-functions fun t)
+ (when (and (= beg beg1)
+ (= end end1))
+ (comint--mark-as-output beg1 end1))))
+ (add-hook 'after-change-functions fun nil t)))
+
+(defun comint--unmark-string-as-output (string)
+ (remove-list-of-text-properties
+ 0 (length string)
+ '( rear-nonsticky front-sticky field
+ inhibit-line-move-field-capture insert-in-front-hooks)
+ string)
+ string)
+
(defun comint-preinput-scroll-to-bottom ()
"Go to the end of buffer in all windows showing it.
Movement occurs if point in the selected window is not after the process mark,
--
2.34.1
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]
next prev parent reply other threads:[~2021-12-07 16:57 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-28 12:52 bug#18135: Emacs bug # 3735 definitely not fixed (5 years later) Don Hopkins
2017-05-06 14:46 ` Chong Yidong
2021-12-04 21:15 ` bug#18135: bug#3735: shell-mode editing, movement, and command entry broken by prompt/output changes Lars Ingebrigtsen
2021-12-04 22:18 ` Don Hopkins
2021-12-05 16:13 ` miha--- via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-12-05 19:27 ` Lars Ingebrigtsen
2021-12-07 16:57 ` miha--- via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2021-12-07 20:16 ` bug#3735: " Lars Ingebrigtsen
2021-12-08 0:20 ` Don Hopkins
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=878rww4akh.fsf@miha-pc \
--to=bug-gnu-emacs@gnu.org \
--cc=18135@debbugs.gnu.org \
--cc=3735@debbugs.gnu.org \
--cc=cyd@gnu.org \
--cc=don@donhopkins.com \
--cc=dsb@smart.net \
--cc=larsi@gnus.org \
--cc=miha@kamnitnik.top \
/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).