aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Stephani2015-05-25 17:03:50 -0400
committerStefan Monnier2015-05-25 17:03:50 -0400
commit816a2b369d0490e67fd5a57c9f18bb2c533e80e4 (patch)
tree72c6dfa080468e1edcbf8b169577ee8136764a30
parent49c8458d7b7194a7b6f347bf4a730391df74df2b (diff)
downloademacs-816a2b369d0490e67fd5a57c9f18bb2c533e80e4.tar.gz
emacs-816a2b369d0490e67fd5a57c9f18bb2c533e80e4.zip
* lisp/term/xterm.el: Add gui-get-selection support via OSC-52
(xterm--extra-capabilities-type): Add `getSelection'. (xterm--query): Add `no-async' argument. (xterm--init-activate-get-selection): New function. (terminal-init-xterm): Use it. (xterm--init-modify-other-keys): Rename from terminal-init-xterm-modify-other-keys. (xterm--init-bracketed-paste-mode): Rename from terminal-init-xterm-bracketed-paste-mode. (xterm--init-activate-set-selection): Rename from terminal-init-xterm-activate-set-selection. (xterm--selection-char): New function. (gui-backend-set-selection): Use it. Use the &context to only apply this method in terminals where we enabled the feature. (gui-backend-get-selection): New method.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/term/xterm.el117
2 files changed, 79 insertions, 42 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 9f861b29393..1cccc317ab5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -271,6 +271,10 @@ in the surrounding GUI (using the OSC-52 escape sequence). This only works
271if your xterm supports it and enables the `allowWindowOps' options (disabled 271if your xterm supports it and enables the `allowWindowOps' options (disabled
272by default at least in Debian, for security reasons). 272by default at least in Debian, for security reasons).
273 273
274Similarly, you can yank the CLIPBOARD/PRIMARY selection (using the OSC-52
275escape sequence) if your xterm has the feature enabled but for that you
276additionally need to add `getSelection' to `xterm-extra-capabilities'.
277
274** xterm-mouse-mode now supports mouse-tracking (if your xterm supports it). 278** xterm-mouse-mode now supports mouse-tracking (if your xterm supports it).
275 279
276** package.el 280** package.el
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 4e48e80e4e9..f7f80073cd7 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -34,6 +34,7 @@
34 ;; `terminal-init-xterm' as well. 34 ;; `terminal-init-xterm' as well.
35 '(set (const :tag "modifyOtherKeys support" modifyOtherKeys) 35 '(set (const :tag "modifyOtherKeys support" modifyOtherKeys)
36 (const :tag "report background" reportBackground) 36 (const :tag "report background" reportBackground)
37 (const :tag "get X selection" getSelection)
37 (const :tag "set X selection" setSelection))) 38 (const :tag "set X selection" setSelection)))
38 39
39(defcustom xterm-extra-capabilities 'check 40(defcustom xterm-extra-capabilities 'check
@@ -45,7 +46,8 @@ If a list, assume that the listed features are supported, without checking.
45The relevant features are: 46The relevant features are:
46 modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\") 47 modifyOtherKeys -- if supported, more key bindings work (e.g., \"\\C-,\")
47 reportBackground -- if supported, Xterm reports its background color 48 reportBackground -- if supported, Xterm reports its background color
48 setSelection -- if supported, Xterm saves yanked text to the X selection" 49 getSelection -- if supported, Xterm yanks text from the X selection
50 setSelection -- if supported, Xterm saves killed text to the X selection"
49 :version "24.1" 51 :version "24.1"
50 :type `(choice (const :tag "Check" check) 52 :type `(choice (const :tag "Check" check)
51 ,xterm--extra-capabilities-type)) 53 ,xterm--extra-capabilities-type))
@@ -674,15 +676,19 @@ string bytes that can be copied is 3/4 of this value."
674 ;; introduced) or higher, initialize the 676 ;; introduced) or higher, initialize the
675 ;; modifyOtherKeys support. 677 ;; modifyOtherKeys support.
676 (when (>= version 216) 678 (when (>= version 216)
677 (terminal-init-xterm-modify-other-keys)) 679 (xterm--init-modify-other-keys))
678 ;; In version 203 support for accessing the X selection was 680 ;; In version 203 support for accessing the X selection was
679 ;; added. Hterm reports itself as version 256 and supports it 681 ;; added. Hterm reports itself as version 256 and supports it
680 ;; as well. gnome-terminal doesn't and is excluded by this 682 ;; as well. gnome-terminal doesn't and is excluded by this
681 ;; test. 683 ;; test.
682 (when (>= version 203) 684 (when (>= version 203)
683 (terminal-init-xterm-activate-set-selection)))))) 685 ;; Most xterms seem to have it disabled by default, and if it's
686 ;; disabled, C-y will incur a timeout, so we only use it if the user
687 ;; explicitly requests it.
688 ;;(xterm--init-activate-get-selection)
689 (xterm--init-activate-set-selection))))))
684 690
685(defun xterm--query (query handlers) 691(defun xterm--query (query handlers &optional no-async)
686 "Send QUERY string to the terminal and watch for a response. 692 "Send QUERY string to the terminal and watch for a response.
687HANDLERS is an alist with elements of the form (STRING . FUNCTION). 693HANDLERS is an alist with elements of the form (STRING . FUNCTION).
688We run the first FUNCTION whose STRING matches the input events." 694We run the first FUNCTION whose STRING matches the input events."
@@ -690,7 +696,7 @@ We run the first FUNCTION whose STRING matches the input events."
690 ;; rather annoying (bug#6758). Maybe we could always use the asynchronous 696 ;; rather annoying (bug#6758). Maybe we could always use the asynchronous
691 ;; approach, but it's less tested. 697 ;; approach, but it's less tested.
692 ;; FIXME: Merge the two branches. 698 ;; FIXME: Merge the two branches.
693 (if (input-pending-p) 699 (if (and (input-pending-p) (not no-async))
694 (progn 700 (progn
695 (dolist (handler handlers) 701 (dolist (handler handlers)
696 (define-key input-decode-map (car handler) 702 (define-key input-decode-map (car handler)
@@ -758,36 +764,73 @@ We run the first FUNCTION whose STRING matches the input events."
758 '(("\e]11;" . xterm--report-background-handler)))) 764 '(("\e]11;" . xterm--report-background-handler))))
759 765
760 (when (memq 'modifyOtherKeys xterm-extra-capabilities) 766 (when (memq 'modifyOtherKeys xterm-extra-capabilities)
761 (terminal-init-xterm-modify-other-keys)) 767 (xterm--init-modify-other-keys))
762 768
769 (when (memq 'getSelection xterm-extra-capabilities)
770 (xterm--init-activate-get-selection))
763 (when (memq 'setSelection xterm-extra-capabilities) 771 (when (memq 'setSelection xterm-extra-capabilities)
764 (terminal-init-xterm-activate-set-selection))) 772 (xterm--init-activate-set-selection)))
765 773
766 ;; Unconditionally enable bracketed paste mode: terminals that don't 774 ;; Unconditionally enable bracketed paste mode: terminals that don't
767 ;; support it just ignore the sequence. 775 ;; support it just ignore the sequence.
768 (terminal-init-xterm-bracketed-paste-mode) 776 (xterm--init-bracketed-paste-mode)
769 777
770 (run-hooks 'terminal-init-xterm-hook)) 778 (run-hooks 'terminal-init-xterm-hook))
771 779
772(defun terminal-init-xterm-modify-other-keys () 780(defun xterm--init-modify-other-keys ()
773 "Terminal initialization for xterm's modifyOtherKeys support." 781 "Terminal initialization for xterm's modifyOtherKeys support."
774 (send-string-to-terminal "\e[>4;1m") 782 (send-string-to-terminal "\e[>4;1m")
775 (push "\e[>4m" (terminal-parameter nil 'tty-mode-reset-strings)) 783 (push "\e[>4m" (terminal-parameter nil 'tty-mode-reset-strings))
776 (push "\e[>4;1m" (terminal-parameter nil 'tty-mode-set-strings))) 784 (push "\e[>4;1m" (terminal-parameter nil 'tty-mode-set-strings)))
777 785
778(defun terminal-init-xterm-bracketed-paste-mode () 786(defun xterm--init-bracketed-paste-mode ()
779 "Terminal initialization for bracketed paste mode." 787 "Terminal initialization for bracketed paste mode."
780 (send-string-to-terminal "\e[?2004h") 788 (send-string-to-terminal "\e[?2004h")
781 (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings)) 789 (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings))
782 (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings))) 790 (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings)))
783 791
784(defun terminal-init-xterm-activate-set-selection () 792(defun xterm--init-activate-get-selection ()
793 "Terminal initialization for `gui-get-selection'."
794 (set-terminal-parameter nil 'xterm--get-selection t))
795
796(defun xterm--init-activate-set-selection ()
785 "Terminal initialization for `gui-set-selection'." 797 "Terminal initialization for `gui-set-selection'."
786 (set-terminal-parameter nil 'xterm--set-selection t)) 798 (set-terminal-parameter nil 'xterm--set-selection t))
787 799
788;; FIXME: This defines the gui method for all terminals, even tho it only 800(defun xterm--selection-char (type)
789;; supports a subset of them. 801 (pcase type
790(cl-defmethod gui-backend-set-selection (type data &context (window-system (eql nil))) 802 ('PRIMARY "p")
803 ('CLIPBOARD "c")
804 (_ (error "Invalid selection type: %S" type))))
805
806(cl-defmethod gui-backend-get-selection
807 (type data-type
808 &context (window-system (eql nil))
809 ;; Only applies to terminals which have it enabled.
810 ((terminal-parameter nil 'xterm--get-selection) (eql t)))
811 (unless (eq data-type 'STRING)
812 (error "Unsupported data type %S" data-type))
813 (let* ((screen (eq (terminal-parameter nil 'terminal-initted)
814 'terminal-init-screen))
815 (query (concat "\e]52;" (xterm--selection-char type) ";")))
816 (with-temp-buffer
817 (set-buffer-multibyte nil)
818 (xterm--query
819 (concat (when screen "\eP") query "?\a" (when screen "\e\\"))
820 (list (cons query (lambda ()
821 (while (let ((char (read-char)))
822 (unless (eq char ?\a)
823 (insert char)
824 t))))))
825 'no-async)
826 (base64-decode-region (point-min) (point-max))
827 (decode-coding-region (point-min) (point-max) 'utf-8-unix t))))
828
829(cl-defmethod gui-backend-set-selection
830 (type data
831 &context (window-system (eql nil))
832 ;; Only applies to terminals which have it enabled.
833 ((terminal-parameter nil 'xterm--set-selection) (eql t)))
791 "Copy DATA to the X selection using the OSC 52 escape sequence. 834 "Copy DATA to the X selection using the OSC 52 escape sequence.
792 835
793TYPE specifies which selection to set; it must be either 836TYPE specifies which selection to set; it must be either
@@ -808,34 +851,24 @@ program. When inside the screen program, this function also
808chops long DCS sequences into multiple smaller ones to avoid 851chops long DCS sequences into multiple smaller ones to avoid
809hitting screen's max DCS length." 852hitting screen's max DCS length."
810 (let* ((screen (eq (terminal-parameter nil 'terminal-initted) 853 (let* ((screen (eq (terminal-parameter nil 'terminal-initted)
811 'terminal-init-screen))) 854 'terminal-init-screen))
812 ;; Only do something if the current terminal is actually an XTerm 855 (bytes (encode-coding-string data 'utf-8-unix))
813 ;; or screen. 856 (base-64 (if screen
814 (when (terminal-parameter nil 'xterm--set-selection) 857 (replace-regexp-in-string
815 (let* ((bytes (encode-coding-string data 'utf-8-unix)) 858 "\n" "\e\\\eP"
816 (base-64 (if screen 859 (base64-encode-string bytes)
817 (replace-regexp-in-string 860 :fixedcase :literal)
818 "\n" "\e\\\eP" 861 (base64-encode-string bytes :no-line-break)))
819 (base64-encode-string bytes) 862 (length (length base-64)))
820 :fixedcase :literal) 863 (if (> length xterm-max-cut-length)
821 (base64-encode-string bytes :no-line-break))) 864 (progn
822 (length (length base-64))) 865 (warn "Selection too long to send to terminal: %d bytes" length)
823 (if (> length xterm-max-cut-length) 866 (sit-for 2))
824 (progn 867 (send-string-to-terminal
825 (warn "Selection too long to send to terminal: %d bytes" length) 868 (concat
826 (sit-for 2)) 869 (when screen "\eP")
827 (send-string-to-terminal 870 "\e]52;" (xterm--selection-char type) ";" base-64 "\a"
828 (concat 871 (when screen "\e\\"))))))
829 (when screen "\eP")
830 "\e]52;"
831 (pcase type
832 ('PRIMARY "p")
833 ('CLIPBOARD "c")
834 (_ (error "Invalid selection type: %S" type)))
835 ";"
836 base-64
837 "\a"
838 (when screen "\e\\"))))))))
839 872
840(defun xterm-rgb-convert-to-16bit (prim) 873(defun xterm-rgb-convert-to-16bit (prim)
841 "Convert an 8-bit primary color value PRIM to a corresponding 16-bit value." 874 "Convert an 8-bit primary color value PRIM to a corresponding 16-bit value."