all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Philipp Stephani <p.stephani2@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 24639@debbugs.gnu.org
Subject: bug#24639: 26.0.50; Terminal paste doesn't work right in term char mode
Date: Sat, 15 Oct 2016 13:25:18 +0000	[thread overview]
Message-ID: <CAArVCkRJxzfxBt9_QXgKOpyf6w+o5awK4dx8zxRQh+_Vfn=_Og@mail.gmail.com> (raw)
In-Reply-To: <834m4kg327.fsf@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 1344 bytes --]

Eli Zaretskii <eliz@gnu.org> schrieb am Mo., 10. Okt. 2016 um 07:56 Uhr:

> > From: Philipp Stephani <p.stephani2@gmail.com>
>
> > Date: Sun, 09 Oct 2016 20:48:59 +0000
>
> > Cc: 24639@debbugs.gnu.org
>
> >
>
> >  > > Maybe M-x term should temporarily bracketed paste mode when in char
>
> >  > > mode.
>
> >  >
>
> >  > That's what I was trying to suggest. Does this have downsides?
>
> >  >
>
> >  > I wouldn't expect any. Bracketed paste mode is a bit faster, but
> running a bit slower is better than not
>
> >  working
>
> >  > at all.
>
> >
>
> >  Then please push such a change to the emacs-25 branch.
>
> >
>
> > Unfortunately it's not that simple: Bracketed paste more should only be
> disabled when a term buffer is active
>
> > on an xterm and in char mode. So this will probably require an addition
> to window-configuration-change-hook
>
> > or similar.
>
>
>
> Sorry, I don't understand the reasons for the complication.  The "in
>
> char mode" part was already on the table when we discussed this
>
> previously.  Presumably, there's a function in term-mode which
>
> switches to and from char mode, and that function should turn
>
> bracketed paste mode on or off, accordingly.  Is that right?
>
>
>
>
The complication arises because char-mode is per-buffer, but bracketed
paste mode is per terminal. I've attached a patch now.

[-- Attachment #1.2: Type: text/html, Size: 2418 bytes --]

[-- Attachment #2: 0001-Disable-bracketed-paste-in-a-terminal-in-char-mode.txt --]
[-- Type: text/plain, Size: 7614 bytes --]

From ceb210fee033f59bb2f80a80cc1b988996933700 Mon Sep 17 00:00:00 2001
From: Philipp Stephani <phst@google.com>
Date: Sat, 15 Oct 2016 15:19:56 +0200
Subject: [PATCH] Disable bracketed paste in a terminal in char mode

In char mode, a terminal doesn't accept bracketed paste events,
therefore we should disable them; see Bug#24639.  To decouple the XTerm
management from term.el, introduce a per-buffer setting to disable
bracketed paste for that buffer.  If bracketed paste is inhiited for at
least one buffer in a terminal, it is disabled for the whole terminal.

* term/xterm.el (xterm-inhibit-bracketed-paste-mode): New mode to
inhibit XTerm bracketed paste per buffer.
(xterm--buffer-terminals, xterm--update-bracketed-paste)
(xterm--bracketed-paste-possible, xterm--is-xterm): New helper
functions.
(xterm--init-bracketed-paste-mode): Remove unused helper
function.
(terminal-init-xterm): Update bracketed paste status when
initializing an XTerm and on window configuration change.

* term.el (term-char-mode, term-line-mode): Inhibit XTerm
bracketed paste in char mode.
---
 lisp/term.el       |  7 +++++
 lisp/term/xterm.el | 88 ++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 86 insertions(+), 9 deletions(-)

diff --git a/lisp/term.el b/lisp/term.el
index f477bcc..fcaa01d 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -1246,6 +1246,11 @@ term-char-mode
 	      (end-of-line)
 	      (term-send-input))
 	  (setq term-input-sender save-input-sender))))
+
+    ;; Turn off XTerm bracketed paste (Bug#24639).
+    (when (fboundp 'xterm-inhibit-bracketed-paste-mode)
+      (xterm-inhibit-bracketed-paste-mode))
+
     (term-update-mode-line)))
 
 (defun term-line-mode  ()
@@ -1255,6 +1260,8 @@ term-line-mode
   (interactive)
   (when (term-in-char-mode)
     (use-local-map term-old-mode-map)
+    (when (fboundp 'xterm-inhibit-bracketed-paste-mode)
+      (xterm-inhibit-bracketed-paste-mode 0))
     (term-update-mode-line)))
 
 (defun term-update-mode-line ()
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 19eb37a..5292e65 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -752,6 +752,78 @@ xterm--push-map
    basemap
    (make-composed-keymap map (keymap-parent basemap))))
 
+(define-minor-mode xterm-inhibit-bracketed-paste-mode
+  "Toggle whether XTerm bracketed paste should be allowed in this bugger.
+With a prefix argument ARG, forbid bracketed paste if ARG is
+positive, and allow it otherwise.  If called from Lisp, forbid
+bracketed paste if ARG is omitted or nil, and toggle the state of
+ARG is `toggle'.  If XTerm bracketed paste is allowed (the
+default), it will be used to paste text from an X selection upon
+reception of the `xterm-paste' event.  Otherwise the selection
+will be inserted character by character, which is much slower.
+Therefore, bracketed paste should only be disabled in buffers
+that can't deal with the `xterm-paste' event, such as terminal
+emulation buffers."
+  :group xterm
+  ;; Update the bracketed paste flag in all terminals that display the
+  ;; current buffer.
+  (mapc #'xterm--update-bracketed-paste (xterm--buffer-terminals)))
+
+(defun xterm--buffer-terminals (&optional buffer)
+  "Return all terminals that contain a window that displays BUFFER.
+BUFFER defaults to the current buffer."
+  (cl-delete-duplicates
+   (cl-loop for window in (get-buffer-window-list buffer nil t)
+            for terminal = (frame-terminal (window-frame window))
+            collect terminal)
+   :test 'eq))
+
+(defun xterm--update-bracketed-paste (&optional terminal)
+  "Enable or disable bracketed paste for TERMINAL.
+TERMINAL must be a live terminal; it defaults to the terminal
+displaying the selected frame.  If any buffer displayed on the
+frames of TERMINAL inhibits bracketed paste by enabling
+`xterm-inhibit-bracketed-paste-mode', disable bracketed paste for
+TERMINAL.  If there is no such buffer, enable bracketed paste."
+  (unless terminal (setq terminal (frame-terminal)))
+  (cl-check-type terminal terminal-live)
+  (when (xterm--is-xterm terminal)
+    (cl-symbol-macrolet
+        ((enabled-param (terminal-parameter terminal 'xterm--bracketed-paste))
+         (set-strings-param (terminal-parameter terminal 'tty-mode-set-strings))
+         (reset-strings-param
+          (terminal-parameter terminal 'tty-mode-reset-strings)))
+      (let ((is-enabled enabled-param)
+            (should-enable (xterm--bracketed-paste-possible terminal))
+            (enable-seq "\e[?2004h")
+            (disable-seq "\e[?2004l"))
+        (cond
+         ;; Unconditionally send terminal sequences: terminals that
+         ;; don't support bracketed paste just ignore the sequences.
+         ((and (not is-enabled) should-enable)
+          (send-string-to-terminal enable-seq terminal)
+          (push disable-seq reset-strings-param)
+          (push enable-seq set-strings-param)
+          (setq enabled-param t))
+         ((and is-enabled (not should-enable))
+          (send-string-to-terminal disable-seq)
+          (cl-callf2 delete disable-seq reset-strings-param)
+          (cl-callf2 delete enable-seq set-strings-param)
+          (setq enabled-param nil)))))))
+
+(defun xterm--bracketed-paste-possible (terminal)
+  "Return non-nil if bracketed paste could be enabled on TERMINAL.
+If any buffer displayed on the frames of TERMINAL inhibits
+bracketed paste by enabling `xterm-inhibit-bracketed-paste-mode',
+return nil.  If there is no such buffer, return non-nil."
+  (cl-check-type terminal terminal-live)
+  (cl-loop for frame being the frames
+           if (eq (frame-terminal frame) terminal)
+           always (cl-loop
+                   for window being the windows of frame
+                   never (buffer-local-value 'xterm-inhibit-bracketed-paste-mode
+                                             (window-buffer window)))))
+
 (defun terminal-init-xterm ()
   "Terminal initialization function for xterm."
   ;; rxvt terminals sometimes set the TERM variable to "xterm", but
@@ -789,9 +861,8 @@ terminal-init-xterm
     (when (memq 'setSelection xterm-extra-capabilities)
       (xterm--init-activate-set-selection)))
 
-  ;; Unconditionally enable bracketed paste mode: terminals that don't
-  ;; support it just ignore the sequence.
-  (xterm--init-bracketed-paste-mode)
+  (add-hook 'window-configuration-change-hook #'xterm--update-bracketed-paste)
+  (xterm--update-bracketed-paste)
 
   (run-hooks 'terminal-init-xterm-hook))
 
@@ -801,12 +872,6 @@ xterm--init-modify-other-keys
   (push "\e[>4m" (terminal-parameter nil 'tty-mode-reset-strings))
   (push "\e[>4;1m" (terminal-parameter nil 'tty-mode-set-strings)))
 
-(defun xterm--init-bracketed-paste-mode ()
-  "Terminal initialization for bracketed paste mode."
-  (send-string-to-terminal "\e[?2004h")
-  (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings))
-  (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings)))
-
 (defun xterm--init-activate-get-selection ()
   "Terminal initialization for `gui-get-selection'."
   (set-terminal-parameter nil 'xterm--get-selection t))
@@ -987,6 +1052,11 @@ xterm-maybe-set-dark-background-mode
     (set-terminal-parameter nil 'background-mode 'dark)
     t))
 
+(defun xterm--is-xterm (&optional terminal)
+  "Return non-nil if TERMINAL is an XTerm-like terminal.
+TERMINAL defaults to the terminal of the selected frame."
+  (eq (terminal-parameter terminal 'terminal-initted) 'terminal-init-xterm))
+
 (provide 'xterm)                        ;Backward compatibility.
 (provide 'term/xterm)
 ;;; xterm.el ends here
-- 
2.10.1


  reply	other threads:[~2016-10-15 13:25 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-07 18:02 bug#24639: 26.0.50; Terminal paste doesn't work right in term char mode Philipp
2016-10-07 19:05 ` Eli Zaretskii
2016-10-07 19:19   ` Philipp Stephani
2016-10-07 19:25     ` Eli Zaretskii
2016-10-07 20:19       ` Philipp Stephani
2016-10-08  5:27         ` Eli Zaretskii
2016-10-09 20:48           ` Philipp Stephani
2016-10-10  5:56             ` Eli Zaretskii
2016-10-15 13:25               ` Philipp Stephani [this message]
2016-10-15 14:31                 ` Eli Zaretskii
2016-10-15 14:38                   ` Philipp Stephani
2016-10-15 15:07                     ` Eli Zaretskii
2016-11-06 18:43                       ` Philipp Stephani
2016-11-06 18:43                         ` bug#24639: [PATCH] Send text received by bracketed paste to process Philipp Stephani
2016-11-07 18:35                           ` Eli Zaretskii
2016-11-10 21:57                             ` Philipp Stephani

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

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

  git send-email \
    --in-reply-to='CAArVCkRJxzfxBt9_QXgKOpyf6w+o5awK4dx8zxRQh+_Vfn=_Og@mail.gmail.com' \
    --to=p.stephani2@gmail.com \
    --cc=24639@debbugs.gnu.org \
    --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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.