aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/term
diff options
context:
space:
mode:
authorPhilipp Stephani2015-04-13 10:48:47 -0400
committerStefan Monnier2015-04-13 10:48:47 -0400
commit2b2fd3965f8c096b39de7e0418d37433269a1dce (patch)
tree4fda6dc694a67326b5d671fe6d4e4925ad8cfb9c /lisp/term
parenta2f9da45c4f49918d100627ce0198cd593a0bf15 (diff)
downloademacs-2b2fd3965f8c096b39de7e0418d37433269a1dce.tar.gz
emacs-2b2fd3965f8c096b39de7e0418d37433269a1dce.zip
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.
Diffstat (limited to 'lisp/term')
-rw-r--r--lisp/term/xterm.el93
1 files changed, 89 insertions, 4 deletions
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 519f6918565..f4d1a8406cd 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -37,7 +37,8 @@ If a list, assume that the listed features are supported, without checking.
37 37
38The relevant features are: 38The relevant features are:
39 modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\") 39 modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\")
40 reportBackground -- if supported, Xterm reports its background color" 40 reportBackground -- if supported, Xterm reports its background color
41 setSelection -- if supported, Xterm saves yanked text to the X selection"
41 :version "24.1" 42 :version "24.1"
42 :group 'xterm 43 :group 'xterm
43 :type '(choice (const :tag "No" nil) 44 :type '(choice (const :tag "No" nil)
@@ -45,7 +46,24 @@ The relevant features are:
45 ;; NOTE: If you add entries here, make sure to update 46 ;; NOTE: If you add entries here, make sure to update
46 ;; `terminal-init-xterm' as well. 47 ;; `terminal-init-xterm' as well.
47 (set (const :tag "modifyOtherKeys support" modifyOtherKeys) 48 (set (const :tag "modifyOtherKeys support" modifyOtherKeys)
48 (const :tag "report background" reportBackground)))) 49 (const :tag "report background" reportBackground)
50 (const :tag "set X selection" setSelection))))
51
52(defcustom xterm-max-cut-length 100000
53 "Maximum number of bytes to cut into xterm using the OSC 52 sequence.
54
55The OSC 52 sequence requires a terminator byte. Some terminals will ignore or
56mistreat a terminated sequence that is longer than a certain size, usually to
57protect users from runaway sequences.
58
59This variable allows you to tweak the maximum number of bytes that will be sent
60using the OSC 52 sequence.
61
62If you select a region larger than this size, it won't be copied to your system
63clipboard. Since clipboard data is base 64 encoded, the actual number of
64string bytes that can be copied is 3/4 of this value."
65 :group 'xterm
66 :type 'integer)
49 67
50(defconst xterm-paste-ending-sequence "\e[201~" 68(defconst xterm-paste-ending-sequence "\e[201~"
51 "Characters send by the terminal to end a bracketed paste.") 69 "Characters send by the terminal to end a bracketed paste.")
@@ -620,7 +638,13 @@ The relevant features are:
620 ;; introduced) or higher, initialize the 638 ;; introduced) or higher, initialize the
621 ;; modifyOtherKeys support. 639 ;; modifyOtherKeys support.
622 (when (>= version 216) 640 (when (>= version 216)
623 (terminal-init-xterm-modify-other-keys)))))) 641 (terminal-init-xterm-modify-other-keys))
642 ;; In version 203 support for accessing the X selection was
643 ;; added. Hterm reports itself as version 256 and supports it
644 ;; as well. gnome-terminal doesn't and is excluded by this
645 ;; test.
646 (when (>= version 203)
647 (terminal-init-xterm-activate-set-selection))))))
624 648
625(defun xterm--query (query handlers) 649(defun xterm--query (query handlers)
626 "Send QUERY string to the terminal and watch for a response. 650 "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."
699 '(("\e]11;" . xterm--report-background-handler)))) 723 '(("\e]11;" . xterm--report-background-handler))))
700 724
701 (when (memq 'modifyOtherKeys xterm-extra-capabilities) 725 (when (memq 'modifyOtherKeys xterm-extra-capabilities)
702 (terminal-init-xterm-modify-other-keys))) 726 (terminal-init-xterm-modify-other-keys))
727
728 (when (memq 'setSelection xterm-extra-capabilities)
729 (terminal-init-xterm-activate-set-selection)))
703 730
704 ;; Unconditionally enable bracketed paste mode: terminals that don't 731 ;; Unconditionally enable bracketed paste mode: terminals that don't
705 ;; support it just ignore the sequence. 732 ;; support it just ignore the sequence.
@@ -719,6 +746,64 @@ We run the first FUNCTION whose STRING matches the input events."
719 (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings)) 746 (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings))
720 (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings))) 747 (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings)))
721 748
749(defun terminal-init-xterm-activate-set-selection ()
750 "Terminal initialization for `gui-set-selection'."
751 ;; All text terminals are represented by the nil GUI type. We need
752 ;; to detect XTerm again in `xterm--set-selection' using the
753 ;; terminal parameters.
754 (gui-method-define gui-set-selection nil #'xterm--set-selection))
755
756(defun xterm--set-selection (type data)
757 "Copy DATA to the X selection using the OSC 52 escape sequence.
758
759TYPE specifies which selection to set; it must be either
760`PRIMARY' or `CLIPBOARD'. DATA must be a string.
761
762This can be used as a `gui-set-selection' method for
763xterm-compatible terminal emulators. Then your system clipboard
764will be updated whenever you copy a region of text in Emacs.
765
766If the resulting OSC 52 sequence would be longer than
767`xterm-max-cut-length', then the TEXT is not sent to the system
768clipboard.
769
770This function either sends a raw OSC 52 sequence or wraps the OSC
77152 in a Device Control String sequence. This way, it will work
772on a bare terminal emulators as well as inside the screen
773program. When inside the screen program, this function also
774chops long DCS sequences into multiple smaller ones to avoid
775hitting screen's max DCS length."
776 (let* ((init-function (terminal-parameter nil 'terminal-initted))
777 (xterm (eq init-function 'terminal-init-xterm))
778 (screen (eq init-function 'terminal-init-screen)))
779 ;; Only do something if the current terminal is actually an XTerm
780 ;; or screen.
781 (when (or xterm screen)
782 (let* ((bytes (encode-coding-string data 'utf-8-unix))
783 (base-64 (if screen
784 (replace-regexp-in-string
785 "\n" "\e\\\eP"
786 (base64-encode-string bytes)
787 :fixedcase :literal)
788 (base64-encode-string bytes :no-line-break)))
789 (length (string-bytes base-64)))
790 (if (> length xterm-max-cut-length)
791 (progn
792 (warn "Selection too long to send to terminal: %d bytes" length)
793 (sit-for 2))
794 (send-string-to-terminal
795 (concat
796 (when screen "\eP")
797 "\e]52;"
798 (cond
799 ((eq type 'PRIMARY) "p")
800 ((eq type 'CLIPBOARD) "c")
801 (t (error "Invalid type %S" type)))
802 ";"
803 base-64
804 "\a"
805 (when screen "\e\\"))))))))
806
722;; Set up colors, for those versions of xterm that support it. 807;; Set up colors, for those versions of xterm that support it.
723(defvar xterm-standard-colors 808(defvar xterm-standard-colors
724 ;; The names in the comments taken from XTerm-col.ad in the xterm 809 ;; The names in the comments taken from XTerm-col.ad in the xterm