diff options
| author | Philipp Stephani | 2016-10-15 15:19:56 +0200 |
|---|---|---|
| committer | Philipp Stephani | 2016-10-15 17:13:27 +0200 |
| commit | cf566b46a6cf85c6d54d0b0db80e32ed6ae8d1ca (patch) | |
| tree | 976d4825752ceee0fd7baf0df5e666b810a57c72 | |
| parent | f68b463d1b05c7cd45b66a5cb0977c21016f5ea5 (diff) | |
| download | emacs-cf566b46a6cf85c6d54d0b0db80e32ed6ae8d1ca.tar.gz emacs-cf566b46a6cf85c6d54d0b0db80e32ed6ae8d1ca.zip | |
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.
| -rw-r--r-- | lisp/term.el | 7 | ||||
| -rw-r--r-- | lisp/term/xterm.el | 88 |
2 files changed, 86 insertions, 9 deletions
diff --git a/lisp/term.el b/lisp/term.el index 87f600cdf72..1adeae24098 100644 --- a/lisp/term.el +++ b/lisp/term.el | |||
| @@ -1243,6 +1243,11 @@ intervention from Emacs, except for the escape character (usually C-c)." | |||
| 1243 | (end-of-line) | 1243 | (end-of-line) |
| 1244 | (term-send-input)) | 1244 | (term-send-input)) |
| 1245 | (setq term-input-sender save-input-sender)))) | 1245 | (setq term-input-sender save-input-sender)))) |
| 1246 | |||
| 1247 | ;; Turn off XTerm bracketed paste (Bug#24639). | ||
| 1248 | (when (fboundp 'xterm-inhibit-bracketed-paste-mode) | ||
| 1249 | (xterm-inhibit-bracketed-paste-mode)) | ||
| 1250 | |||
| 1246 | (term-update-mode-line))) | 1251 | (term-update-mode-line))) |
| 1247 | 1252 | ||
| 1248 | (defun term-line-mode () | 1253 | (defun term-line-mode () |
| @@ -1252,6 +1257,8 @@ you type \\[term-send-input] which sends the current line to the inferior." | |||
| 1252 | (interactive) | 1257 | (interactive) |
| 1253 | (when (term-in-char-mode) | 1258 | (when (term-in-char-mode) |
| 1254 | (use-local-map term-old-mode-map) | 1259 | (use-local-map term-old-mode-map) |
| 1260 | (when (fboundp 'xterm-inhibit-bracketed-paste-mode) | ||
| 1261 | (xterm-inhibit-bracketed-paste-mode 0)) | ||
| 1255 | (term-update-mode-line))) | 1262 | (term-update-mode-line))) |
| 1256 | 1263 | ||
| 1257 | (defun term-update-mode-line () | 1264 | (defun term-update-mode-line () |
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index 01c01130e7c..78646e421c3 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el | |||
| @@ -765,6 +765,78 @@ We run the first FUNCTION whose STRING matches the input events." | |||
| 765 | basemap | 765 | basemap |
| 766 | (make-composed-keymap map (keymap-parent basemap)))) | 766 | (make-composed-keymap map (keymap-parent basemap)))) |
| 767 | 767 | ||
| 768 | (define-minor-mode xterm-inhibit-bracketed-paste-mode | ||
| 769 | "Toggle whether XTerm bracketed paste should be allowed in this bugger. | ||
| 770 | With a prefix argument ARG, forbid bracketed paste if ARG is | ||
| 771 | positive, and allow it otherwise. If called from Lisp, forbid | ||
| 772 | bracketed paste if ARG is omitted or nil, and toggle the state of | ||
| 773 | ARG is `toggle'. If XTerm bracketed paste is allowed (the | ||
| 774 | default), it will be used to paste text from an X selection upon | ||
| 775 | reception of the `xterm-paste' event. Otherwise the selection | ||
| 776 | will be inserted character by character, which is much slower. | ||
| 777 | Therefore, bracketed paste should only be disabled in buffers | ||
| 778 | that can't deal with the `xterm-paste' event, such as terminal | ||
| 779 | emulation buffers." | ||
| 780 | :group xterm | ||
| 781 | ;; Update the bracketed paste flag in all terminals that display the | ||
| 782 | ;; current buffer. | ||
| 783 | (mapc #'xterm--update-bracketed-paste (xterm--buffer-terminals))) | ||
| 784 | |||
| 785 | (defun xterm--buffer-terminals (&optional buffer) | ||
| 786 | "Return all terminals that contain a window that displays BUFFER. | ||
| 787 | BUFFER defaults to the current buffer." | ||
| 788 | (cl-delete-duplicates | ||
| 789 | (cl-loop for window in (get-buffer-window-list buffer nil t) | ||
| 790 | for terminal = (frame-terminal (window-frame window)) | ||
| 791 | collect terminal) | ||
| 792 | :test 'eq)) | ||
| 793 | |||
| 794 | (defun xterm--update-bracketed-paste (&optional terminal) | ||
| 795 | "Enable or disable bracketed paste for TERMINAL. | ||
| 796 | TERMINAL must be a live terminal; it defaults to the terminal | ||
| 797 | displaying the selected frame. If any buffer displayed on the | ||
| 798 | frames of TERMINAL inhibits bracketed paste by enabling | ||
| 799 | `xterm-inhibit-bracketed-paste-mode', disable bracketed paste for | ||
| 800 | TERMINAL. If there is no such buffer, enable bracketed paste." | ||
| 801 | (unless terminal (setq terminal (frame-terminal))) | ||
| 802 | (cl-check-type terminal terminal-live) | ||
| 803 | (when (xterm--is-xterm terminal) | ||
| 804 | (cl-symbol-macrolet | ||
| 805 | ((enabled-param (terminal-parameter terminal 'xterm--bracketed-paste)) | ||
| 806 | (set-strings-param (terminal-parameter terminal 'tty-mode-set-strings)) | ||
| 807 | (reset-strings-param | ||
| 808 | (terminal-parameter terminal 'tty-mode-reset-strings))) | ||
| 809 | (let ((is-enabled enabled-param) | ||
| 810 | (should-enable (xterm--bracketed-paste-possible terminal)) | ||
| 811 | (enable-seq "\e[?2004h") | ||
| 812 | (disable-seq "\e[?2004l")) | ||
| 813 | (cond | ||
| 814 | ;; Unconditionally send terminal sequences: terminals that | ||
| 815 | ;; don't support bracketed paste just ignore the sequences. | ||
| 816 | ((and (not is-enabled) should-enable) | ||
| 817 | (send-string-to-terminal enable-seq terminal) | ||
| 818 | (push disable-seq reset-strings-param) | ||
| 819 | (push enable-seq set-strings-param) | ||
| 820 | (setq enabled-param t)) | ||
| 821 | ((and is-enabled (not should-enable)) | ||
| 822 | (send-string-to-terminal disable-seq) | ||
| 823 | (cl-callf2 delete disable-seq reset-strings-param) | ||
| 824 | (cl-callf2 delete enable-seq set-strings-param) | ||
| 825 | (setq enabled-param nil))))))) | ||
| 826 | |||
| 827 | (defun xterm--bracketed-paste-possible (terminal) | ||
| 828 | "Return non-nil if bracketed paste could be enabled on TERMINAL. | ||
| 829 | If any buffer displayed on the frames of TERMINAL inhibits | ||
| 830 | bracketed paste by enabling `xterm-inhibit-bracketed-paste-mode', | ||
| 831 | return nil. If there is no such buffer, return non-nil." | ||
| 832 | (cl-check-type terminal terminal-live) | ||
| 833 | (cl-loop for frame being the frames | ||
| 834 | if (eq (frame-terminal frame) terminal) | ||
| 835 | always (cl-loop | ||
| 836 | for window being the windows of frame | ||
| 837 | never (buffer-local-value 'xterm-inhibit-bracketed-paste-mode | ||
| 838 | (window-buffer window))))) | ||
| 839 | |||
| 768 | (defun terminal-init-xterm () | 840 | (defun terminal-init-xterm () |
| 769 | "Terminal initialization function for xterm." | 841 | "Terminal initialization function for xterm." |
| 770 | ;; rxvt terminals sometimes set the TERM variable to "xterm", but | 842 | ;; rxvt terminals sometimes set the TERM variable to "xterm", but |
| @@ -802,9 +874,8 @@ We run the first FUNCTION whose STRING matches the input events." | |||
| 802 | (when (memq 'setSelection xterm-extra-capabilities) | 874 | (when (memq 'setSelection xterm-extra-capabilities) |
| 803 | (xterm--init-activate-set-selection))) | 875 | (xterm--init-activate-set-selection))) |
| 804 | 876 | ||
| 805 | ;; Unconditionally enable bracketed paste mode: terminals that don't | 877 | (add-hook 'window-configuration-change-hook #'xterm--update-bracketed-paste) |
| 806 | ;; support it just ignore the sequence. | 878 | (xterm--update-bracketed-paste) |
| 807 | (xterm--init-bracketed-paste-mode) | ||
| 808 | 879 | ||
| 809 | (run-hooks 'terminal-init-xterm-hook)) | 880 | (run-hooks 'terminal-init-xterm-hook)) |
| 810 | 881 | ||
| @@ -814,12 +885,6 @@ We run the first FUNCTION whose STRING matches the input events." | |||
| 814 | (push "\e[>4m" (terminal-parameter nil 'tty-mode-reset-strings)) | 885 | (push "\e[>4m" (terminal-parameter nil 'tty-mode-reset-strings)) |
| 815 | (push "\e[>4;1m" (terminal-parameter nil 'tty-mode-set-strings))) | 886 | (push "\e[>4;1m" (terminal-parameter nil 'tty-mode-set-strings))) |
| 816 | 887 | ||
| 817 | (defun xterm--init-bracketed-paste-mode () | ||
| 818 | "Terminal initialization for bracketed paste mode." | ||
| 819 | (send-string-to-terminal "\e[?2004h") | ||
| 820 | (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings)) | ||
| 821 | (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings))) | ||
| 822 | |||
| 823 | (defun xterm--init-activate-get-selection () | 888 | (defun xterm--init-activate-get-selection () |
| 824 | "Terminal initialization for `gui-get-selection'." | 889 | "Terminal initialization for `gui-get-selection'." |
| 825 | (set-terminal-parameter nil 'xterm--get-selection t)) | 890 | (set-terminal-parameter nil 'xterm--get-selection t)) |
| @@ -1000,6 +1065,11 @@ versions of xterm." | |||
| 1000 | (set-terminal-parameter nil 'background-mode 'dark) | 1065 | (set-terminal-parameter nil 'background-mode 'dark) |
| 1001 | t)) | 1066 | t)) |
| 1002 | 1067 | ||
| 1068 | (defun xterm--is-xterm (&optional terminal) | ||
| 1069 | "Return non-nil if TERMINAL is an XTerm-like terminal. | ||
| 1070 | TERMINAL defaults to the terminal of the selected frame." | ||
| 1071 | (eq (terminal-parameter terminal 'terminal-initted) 'terminal-init-xterm)) | ||
| 1072 | |||
| 1003 | (provide 'xterm) ;Backward compatibility. | 1073 | (provide 'xterm) ;Backward compatibility. |
| 1004 | (provide 'term/xterm) | 1074 | (provide 'term/xterm) |
| 1005 | ;;; xterm.el ends here | 1075 | ;;; xterm.el ends here |