Add arch taglines
[bpt/emacs.git] / lisp / select.el
index b27287e..01b227d 100644 (file)
@@ -1,5 +1,6 @@
-;;; select.el --- lisp portion of standard selection support.
+;;; select.el --- lisp portion of standard selection support
 
+;; Maintainer: FSF
 ;; Keywords: internal
 
 ;; Copyright (c) 1993, 1994 Free Software Foundation, Inc.
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
+;;; Commentary:
+
 ;;; Code:
 
 ;; This is for temporary compatibility with pre-release Emacs 19.
 (defalias 'x-selection 'x-get-selection)
 (defun x-get-selection (&optional type data-type)
   "Return the value of an X Windows selection.
-The argument TYPE (default `PRIMARY') says which selection, 
+The argument TYPE (default `PRIMARY') says which selection,
 and the argument DATA-TYPE (default `STRING') says
-how to convert the data."
-  (x-get-selection-internal (or type 'PRIMARY) (or data-type 'STRING)))
+how to convert the data.
+
+TYPE may be `SECONDARY' or `CLIPBOARD', in addition to `PRIMARY'.
+DATA-TYPE is usually `STRING', but can also be one of the symbols
+in `selection-converter-alist', which see."
+  (let ((data (x-get-selection-internal (or type 'PRIMARY)
+                                       (or data-type 'STRING)))
+       coding)
+    (when (and (stringp data)
+              (setq data-type (get-text-property 0 'foreign-selection data)))
+      (setq coding (if (eq data-type 'UTF8_STRING)
+                      'utf-8
+                    (or next-selection-coding-system
+                        selection-coding-system))
+           data (decode-coding-string data coding))
+      (put-text-property 0 (length data) 'foreign-selection data-type data))
+    data))
 
 (defun x-get-clipboard ()
   "Return text pasted to the clipboard."
@@ -39,12 +57,12 @@ how to convert the data."
 
 (defun x-set-selection (type data)
   "Make an X Windows selection of type TYPE and value DATA.
-The argument TYPE (default `PRIMARY') says which selection, 
+The argument TYPE (default `PRIMARY') says which selection,
 and DATA specifies the contents.  DATA may be a string,
 a symbol, an integer (or a cons of two integers or list of two integers).
 
 The selection may also be a cons of two markers pointing to the same buffer,
-or an overlay.  In these cases, the selection is considered to be the text 
+or an overlay.  In these cases, the selection is considered to be the text
 between the markers *at whatever time the selection is examined*.
 Thus, editing done in the buffer after you specify the selection
 can alter the effective value of the selection.
@@ -98,8 +116,8 @@ if the prefix arg is set."
 ;;; Cut Buffer support
 
 (defun x-get-cut-buffer (&optional which-one)
-  "Returns the value of one of the 8 X server cut-buffers.  Optional arg
-WHICH-ONE should be a number from 0 to 7, defaulting to 0.
+  "Returns the value of one of the 8 X server cut-buffers.
+Optional arg WHICH-ONE should be a number from 0 to 7, defaulting to 0.
 Cut buffers are considered obsolete; you should use selections instead."
   (x-get-cut-buffer-internal
    (if which-one
@@ -111,11 +129,10 @@ Cut buffers are considered obsolete; you should use selections instead."
 (defun x-set-cut-buffer (string &optional push)
   "Store STRING into the X server's primary cut buffer.
 If PUSH is non-nil, also rotate the cut buffers:
-this means the previous value of the primary cut buffer moves the second
+this means the previous value of the primary cut buffer moves to the second
 cut buffer, and the second to the third, and so on (there are 8 buffers.)
 Cut buffers are considered obsolete; you should use selections instead."
-  ;; Check the data type of STRING.
-  (substring string 0 0)
+  (or (stringp string) (signal 'wrong-type-argument (list 'string string)))
   (if push
       (x-rotate-cut-buffers-internal 1))
   (x-store-cut-buffer-internal 'CUT_BUFFER0 string))
@@ -126,27 +143,84 @@ Cut buffers are considered obsolete; you should use selections instead."
 ;;; for TIMESTAMP, which is a special case.
 
 (defun xselect-convert-to-string (selection type value)
-  (cond ((stringp value)
-        value)
-       ((overlayp value)
-        (save-excursion
-          (or (buffer-name (overlay-buffer value))
-              (error "selection is in a killed buffer"))
-          (set-buffer (overlay-buffer value))
-          (buffer-substring (overlay-start value)
-                            (overlay-end value))))
-       ((and (consp value)
-             (markerp (car value))
-             (markerp (cdr value)))
-        (or (eq (marker-buffer (car value)) (marker-buffer (cdr value)))
-            (signal 'error
-                    (list "markers must be in the same buffer"
-                          (car value) (cdr value))))
-        (save-excursion
-          (set-buffer (or (marker-buffer (car value))
-                          (error "selection is in a killed buffer")))
-          (buffer-substring (car value) (cdr value))))
-       (t nil)))
+  (let (str coding)
+    ;; Get the actual string from VALUE.
+    (cond ((stringp value)
+          (setq str value))
+
+         ((overlayp value)
+          (save-excursion
+            (or (buffer-name (overlay-buffer value))
+                (error "selection is in a killed buffer"))
+            (set-buffer (overlay-buffer value))
+            (setq str (buffer-substring (overlay-start value)
+                                        (overlay-end value)))))
+         ((and (consp value)
+               (markerp (car value))
+               (markerp (cdr value)))
+          (or (eq (marker-buffer (car value)) (marker-buffer (cdr value)))
+              (signal 'error
+                      (list "markers must be in the same buffer"
+                            (car value) (cdr value))))
+          (save-excursion
+            (set-buffer (or (marker-buffer (car value))
+                            (error "selection is in a killed buffer")))
+            (setq str (buffer-substring (car value) (cdr value))))))
+
+    (when str
+      ;; If TYPE is nil, this is a local request, thus return STR as
+      ;; is.  Otherwise, encode STR.
+      (if (not type)
+         str
+       (setq coding (or next-selection-coding-system selection-coding-system))
+       (if coding
+           (setq coding (coding-system-base coding))
+         (setq coding 'raw-text))
+       ;; Suppress producing escape sequences for compositions.
+       (remove-text-properties 0 (length str) '(composition nil) str)
+       (cond
+        ((eq type 'TEXT)
+         (if (not (multibyte-string-p str))
+             ;; Don't have to encode unibyte string.
+             (setq type 'STRING)
+           ;; If STR contains only ASCII, Latin-1, and raw bytes,
+           ;; encode STR by iso-latin-1, and return it as type
+           ;; `STRING'.  Otherwise, encode STR by CODING.  In that
+           ;; case, the returing type depends on CODING.
+           (let ((charsets (find-charset-string str)))
+             (setq charsets
+                   (delq 'ascii
+                         (delq 'latin-iso8859-1
+                               (delq 'eight-bit-control
+                                     (delq 'eight-bit-graphic charsets)))))
+             (if charsets
+                 (setq str (encode-coding-string str coding)
+                       type (if (memq coding '(compound-text
+                                               compound-text-with-extensions))
+                                'COMPOUND_TEXT
+                              'STRING))
+               (setq type 'STRING
+                     str (encode-coding-string str 'iso-latin-1))))))
+
+        ((eq type 'COMPOUND_TEXT)
+         (setq str (encode-coding-string str coding)))
+
+        ((eq type 'STRING)
+         (if (memq coding '(compound-text
+                            compound-text-with-extensions))
+             (setq str (string-make-unibyte str))
+           (setq str (encode-coding-string str coding))))
+
+        ((eq type 'UTF8_STRING)
+         (setq str (encode-coding-string str 'utf-8)))
+
+        (t
+         (error "Unknow selection type: %S" type))
+        ))
+
+      (setq next-selection-coding-system nil)
+      (cons type str))))
+
 
 (defun xselect-convert-to-length (selection type value)
   (let ((value
@@ -270,11 +344,15 @@ Cut buffers are considered obsolete; you should use selections instead."
   (user-full-name))
 
 (defun xselect-convert-to-class (selection type size)
+  "Convert selection to class.
+This function returns the string \"Emacs\"."
   "Emacs")
 
 ;; We do not try to determine the name Emacs was invoked with,
 ;; because it is not clean for a program's behavior to depend on that.
 (defun xselect-convert-to-name (selection type size)
+  "Convert selection to name.
+This function returns the string \"emacs\"."
   "emacs")
 
 (defun xselect-convert-to-integer (selection type value)
@@ -291,6 +369,7 @@ Cut buffers are considered obsolete; you should use selections instead."
       '((TEXT . xselect-convert-to-string)
        (COMPOUND_TEXT . xselect-convert-to-string)
        (STRING . xselect-convert-to-string)
+       (UTF8_STRING . xselect-convert-to-string)
        (TARGETS . xselect-convert-to-targets)
        (LENGTH . xselect-convert-to-length)
        (DELETE . xselect-convert-to-delete)
@@ -310,4 +389,5 @@ Cut buffers are considered obsolete; you should use selections instead."
 
 (provide 'select)
 
-;;; select.el ends here.
+;;; arch-tag: bb634f97-8a3b-4b0a-b940-f6e09982328c
+;;; select.el ends here