xterm.el: Implement OSC-52 functionality for setting the X selection
* lisp/term/xterm.el (xterm-max-cut-length): New var. (xterm--set-selection, terminal-init-xterm-activate-set-selection): New funs. (terminal-init-xterm, xterm--version-handler): Use them.
This commit is contained in:
committed by
Stefan Monnier
parent
a2f9da45c4
commit
2b2fd3965f
@@ -37,7 +37,8 @@ If a list, assume that the listed features are supported, without checking.
|
||||
|
||||
The relevant features are:
|
||||
modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\")
|
||||
reportBackground -- if supported, Xterm reports its background color"
|
||||
reportBackground -- if supported, Xterm reports its background color
|
||||
setSelection -- if supported, Xterm saves yanked text to the X selection"
|
||||
:version "24.1"
|
||||
:group 'xterm
|
||||
:type '(choice (const :tag "No" nil)
|
||||
@@ -45,7 +46,24 @@ The relevant features are:
|
||||
;; NOTE: If you add entries here, make sure to update
|
||||
;; `terminal-init-xterm' as well.
|
||||
(set (const :tag "modifyOtherKeys support" modifyOtherKeys)
|
||||
(const :tag "report background" reportBackground))))
|
||||
(const :tag "report background" reportBackground)
|
||||
(const :tag "set X selection" setSelection))))
|
||||
|
||||
(defcustom xterm-max-cut-length 100000
|
||||
"Maximum number of bytes to cut into xterm using the OSC 52 sequence.
|
||||
|
||||
The OSC 52 sequence requires a terminator byte. Some terminals will ignore or
|
||||
mistreat a terminated sequence that is longer than a certain size, usually to
|
||||
protect users from runaway sequences.
|
||||
|
||||
This variable allows you to tweak the maximum number of bytes that will be sent
|
||||
using the OSC 52 sequence.
|
||||
|
||||
If you select a region larger than this size, it won't be copied to your system
|
||||
clipboard. Since clipboard data is base 64 encoded, the actual number of
|
||||
string bytes that can be copied is 3/4 of this value."
|
||||
:group 'xterm
|
||||
:type 'integer)
|
||||
|
||||
(defconst xterm-paste-ending-sequence "\e[201~"
|
||||
"Characters send by the terminal to end a bracketed paste.")
|
||||
@@ -620,7 +638,13 @@ The relevant features are:
|
||||
;; introduced) or higher, initialize the
|
||||
;; modifyOtherKeys support.
|
||||
(when (>= version 216)
|
||||
(terminal-init-xterm-modify-other-keys))))))
|
||||
(terminal-init-xterm-modify-other-keys))
|
||||
;; In version 203 support for accessing the X selection was
|
||||
;; added. Hterm reports itself as version 256 and supports it
|
||||
;; as well. gnome-terminal doesn't and is excluded by this
|
||||
;; test.
|
||||
(when (>= version 203)
|
||||
(terminal-init-xterm-activate-set-selection))))))
|
||||
|
||||
(defun xterm--query (query handlers)
|
||||
"Send QUERY string to the terminal and watch for a response.
|
||||
@@ -699,7 +723,10 @@ We run the first FUNCTION whose STRING matches the input events."
|
||||
'(("\e]11;" . xterm--report-background-handler))))
|
||||
|
||||
(when (memq 'modifyOtherKeys xterm-extra-capabilities)
|
||||
(terminal-init-xterm-modify-other-keys)))
|
||||
(terminal-init-xterm-modify-other-keys))
|
||||
|
||||
(when (memq 'setSelection xterm-extra-capabilities)
|
||||
(terminal-init-xterm-activate-set-selection)))
|
||||
|
||||
;; Unconditionally enable bracketed paste mode: terminals that don't
|
||||
;; support it just ignore the sequence.
|
||||
@@ -719,6 +746,64 @@ We run the first FUNCTION whose STRING matches the input events."
|
||||
(push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings))
|
||||
(push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings)))
|
||||
|
||||
(defun terminal-init-xterm-activate-set-selection ()
|
||||
"Terminal initialization for `gui-set-selection'."
|
||||
;; All text terminals are represented by the nil GUI type. We need
|
||||
;; to detect XTerm again in `xterm--set-selection' using the
|
||||
;; terminal parameters.
|
||||
(gui-method-define gui-set-selection nil #'xterm--set-selection))
|
||||
|
||||
(defun xterm--set-selection (type data)
|
||||
"Copy DATA to the X selection using the OSC 52 escape sequence.
|
||||
|
||||
TYPE specifies which selection to set; it must be either
|
||||
`PRIMARY' or `CLIPBOARD'. DATA must be a string.
|
||||
|
||||
This can be used as a `gui-set-selection' method for
|
||||
xterm-compatible terminal emulators. Then your system clipboard
|
||||
will be updated whenever you copy a region of text in Emacs.
|
||||
|
||||
If the resulting OSC 52 sequence would be longer than
|
||||
`xterm-max-cut-length', then the TEXT is not sent to the system
|
||||
clipboard.
|
||||
|
||||
This function either sends a raw OSC 52 sequence or wraps the OSC
|
||||
52 in a Device Control String sequence. This way, it will work
|
||||
on a bare terminal emulators as well as inside the screen
|
||||
program. When inside the screen program, this function also
|
||||
chops long DCS sequences into multiple smaller ones to avoid
|
||||
hitting screen's max DCS length."
|
||||
(let* ((init-function (terminal-parameter nil 'terminal-initted))
|
||||
(xterm (eq init-function 'terminal-init-xterm))
|
||||
(screen (eq init-function 'terminal-init-screen)))
|
||||
;; Only do something if the current terminal is actually an XTerm
|
||||
;; or screen.
|
||||
(when (or xterm screen)
|
||||
(let* ((bytes (encode-coding-string data 'utf-8-unix))
|
||||
(base-64 (if screen
|
||||
(replace-regexp-in-string
|
||||
"\n" "\e\\\eP"
|
||||
(base64-encode-string bytes)
|
||||
:fixedcase :literal)
|
||||
(base64-encode-string bytes :no-line-break)))
|
||||
(length (string-bytes base-64)))
|
||||
(if (> length xterm-max-cut-length)
|
||||
(progn
|
||||
(warn "Selection too long to send to terminal: %d bytes" length)
|
||||
(sit-for 2))
|
||||
(send-string-to-terminal
|
||||
(concat
|
||||
(when screen "\eP")
|
||||
"\e]52;"
|
||||
(cond
|
||||
((eq type 'PRIMARY) "p")
|
||||
((eq type 'CLIPBOARD) "c")
|
||||
(t (error "Invalid type %S" type)))
|
||||
";"
|
||||
base-64
|
||||
"\a"
|
||||
(when screen "\e\\"))))))))
|
||||
|
||||
;; Set up colors, for those versions of xterm that support it.
|
||||
(defvar xterm-standard-colors
|
||||
;; The names in the comments taken from XTerm-col.ad in the xterm
|
||||
|
||||
Reference in New Issue
Block a user