diff options
| author | Philipp Stephani | 2015-04-13 10:48:47 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2015-04-13 10:48:47 -0400 |
| commit | 2b2fd3965f8c096b39de7e0418d37433269a1dce (patch) | |
| tree | 4fda6dc694a67326b5d671fe6d4e4925ad8cfb9c /lisp/term | |
| parent | a2f9da45c4f49918d100627ce0198cd593a0bf15 (diff) | |
| download | emacs-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.el | 93 |
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 | ||
| 38 | The relevant features are: | 38 | The 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 | |||
| 55 | The OSC 52 sequence requires a terminator byte. Some terminals will ignore or | ||
| 56 | mistreat a terminated sequence that is longer than a certain size, usually to | ||
| 57 | protect users from runaway sequences. | ||
| 58 | |||
| 59 | This variable allows you to tweak the maximum number of bytes that will be sent | ||
| 60 | using the OSC 52 sequence. | ||
| 61 | |||
| 62 | If you select a region larger than this size, it won't be copied to your system | ||
| 63 | clipboard. Since clipboard data is base 64 encoded, the actual number of | ||
| 64 | string 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 | |||
| 759 | TYPE specifies which selection to set; it must be either | ||
| 760 | `PRIMARY' or `CLIPBOARD'. DATA must be a string. | ||
| 761 | |||
| 762 | This can be used as a `gui-set-selection' method for | ||
| 763 | xterm-compatible terminal emulators. Then your system clipboard | ||
| 764 | will be updated whenever you copy a region of text in Emacs. | ||
| 765 | |||
| 766 | If the resulting OSC 52 sequence would be longer than | ||
| 767 | `xterm-max-cut-length', then the TEXT is not sent to the system | ||
| 768 | clipboard. | ||
| 769 | |||
| 770 | This function either sends a raw OSC 52 sequence or wraps the OSC | ||
| 771 | 52 in a Device Control String sequence. This way, it will work | ||
| 772 | on a bare terminal emulators as well as inside the screen | ||
| 773 | program. When inside the screen program, this function also | ||
| 774 | chops long DCS sequences into multiple smaller ones to avoid | ||
| 775 | hitting 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 |