aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2021-06-30 15:55:50 +0200
committerLars Ingebrigtsen2021-06-30 15:55:50 +0200
commitbb56f6c768acc070a8058bc8e7c91d5ee069ef7f (patch)
treefa9e62911c4722fa6e227e5300c53b6b20648364
parent46a66c6248be20c7c3ef7f57a8f25af39b975eb6 (diff)
downloademacs-bb56f6c768acc070a8058bc8e7c91d5ee069ef7f.tar.gz
emacs-bb56f6c768acc070a8058bc8e7c91d5ee069ef7f.zip
Add new user option to transform kill ring contents
* doc/emacs/killing.texi (Kill Options): Document it. * lisp/simple.el (kill-new): Use it. (kill-transform-function): New user option (bug#29013).
-rw-r--r--doc/emacs/killing.texi15
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/simple.el77
3 files changed, 65 insertions, 32 deletions
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 4291afec56f..6e4fd77e8b9 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -269,6 +269,21 @@ happens. But if you set the variable @code{kill-read-only-ok} to a
269non-@code{nil} value, they just print a message in the echo area to 269non-@code{nil} value, they just print a message in the echo area to
270explain why the text has not been erased. 270explain why the text has not been erased.
271 271
272@vindex kill-transform-function
273 Before saving the kill to the kill ring, you can transform the
274string using @code{kill-transform-function}. It's called with the
275string to be killed, and it should return the string you want to be
276saved. It can also return @code{nil}, in which case the string won't
277be saved to the kill ring. For instance, if you never want to save
278a pure white space string to the kill ring, you can say:
279
280@lisp
281(setq kill-transform-function
282 (lambda (string)
283 (and (not (string-blank-p string))
284 string)))
285@end lisp
286
272@vindex kill-do-not-save-duplicates 287@vindex kill-do-not-save-duplicates
273 If you change the variable @code{kill-do-not-save-duplicates} to a 288 If you change the variable @code{kill-do-not-save-duplicates} to a
274non-@code{nil} value, identical subsequent kills yield a single 289non-@code{nil} value, identical subsequent kills yield a single
diff --git a/etc/NEWS b/etc/NEWS
index 701b9a73a8f..55e8b6a7c24 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2142,6 +2142,11 @@ summaries will include the failing condition.
2142 2142
2143** Miscellaneous 2143** Miscellaneous
2144 2144
2145+++
2146*** New user option 'kill-transform-function'.
2147This can be used to transform (and suppress) strings from entering the
2148kill ring.
2149
2145--- 2150---
2146*** `C-u M-x dig' will now prompt for a query type to use. 2151*** `C-u M-x dig' will now prompt for a query type to use.
2147 2152
diff --git a/lisp/simple.el b/lisp/simple.el
index 71db7ffe5d1..f746d738a62 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5060,6 +5060,16 @@ The comparison is done using `equal-including-properties'."
5060 :group 'killing 5060 :group 'killing
5061 :version "23.2") 5061 :version "23.2")
5062 5062
5063(defcustom kill-transform-function nil
5064 "Function to call to transform a string before it's put on the kill ring.
5065The function is called with one parameter (the string that's to
5066be put on the kill ring). It should return a string or nil. If
5067the latter, the string is not put on the kill ring."
5068 :type '(choice (const :tag "No transform" nil)
5069 function)
5070 :group 'killing
5071 :version "28.1")
5072
5063(defun kill-new (string &optional replace) 5073(defun kill-new (string &optional replace)
5064 "Make STRING the latest kill in the kill ring. 5074 "Make STRING the latest kill in the kill ring.
5065Set `kill-ring-yank-pointer' to point to it. 5075Set `kill-ring-yank-pointer' to point to it.
@@ -5075,38 +5085,41 @@ When the yank handler has a non-nil PARAM element, the original STRING
5075argument is not used by `insert-for-yank'. However, since Lisp code 5085argument is not used by `insert-for-yank'. However, since Lisp code
5076may access and use elements from the kill ring directly, the STRING 5086may access and use elements from the kill ring directly, the STRING
5077argument should still be a \"useful\" string for such uses." 5087argument should still be a \"useful\" string for such uses."
5078 (unless (and kill-do-not-save-duplicates 5088 ;; Allow the user to transform or ignore the string.
5079 ;; Due to text properties such as 'yank-handler that 5089 (when (or (not kill-transform-function)
5080 ;; can alter the contents to yank, comparison using 5090 (setq string (funcall kill-transform-function string)))
5081 ;; `equal' is unsafe. 5091 (unless (and kill-do-not-save-duplicates
5082 (equal-including-properties string (car kill-ring))) 5092 ;; Due to text properties such as 'yank-handler that
5083 (if (fboundp 'menu-bar-update-yank-menu) 5093 ;; can alter the contents to yank, comparison using
5084 (menu-bar-update-yank-menu string (and replace (car kill-ring))))) 5094 ;; `equal' is unsafe.
5085 (when save-interprogram-paste-before-kill 5095 (equal-including-properties string (car kill-ring)))
5086 (let ((interprogram-paste (and interprogram-paste-function 5096 (if (fboundp 'menu-bar-update-yank-menu)
5087 (funcall interprogram-paste-function)))) 5097 (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
5088 (when interprogram-paste 5098 (when save-interprogram-paste-before-kill
5089 (setq interprogram-paste 5099 (let ((interprogram-paste (and interprogram-paste-function
5090 (if (listp interprogram-paste) 5100 (funcall interprogram-paste-function))))
5091 ;; Use `reverse' to avoid modifying external data. 5101 (when interprogram-paste
5092 (reverse interprogram-paste) 5102 (setq interprogram-paste
5093 (list interprogram-paste))) 5103 (if (listp interprogram-paste)
5094 (when (or (not (numberp save-interprogram-paste-before-kill)) 5104 ;; Use `reverse' to avoid modifying external data.
5095 (< (seq-reduce #'+ (mapcar #'length interprogram-paste) 0) 5105 (reverse interprogram-paste)
5096 save-interprogram-paste-before-kill)) 5106 (list interprogram-paste)))
5097 (dolist (s interprogram-paste) 5107 (when (or (not (numberp save-interprogram-paste-before-kill))
5098 (unless (and kill-do-not-save-duplicates 5108 (< (seq-reduce #'+ (mapcar #'length interprogram-paste) 0)
5099 (equal-including-properties s (car kill-ring))) 5109 save-interprogram-paste-before-kill))
5100 (push s kill-ring))))))) 5110 (dolist (s interprogram-paste)
5101 (unless (and kill-do-not-save-duplicates 5111 (unless (and kill-do-not-save-duplicates
5102 (equal-including-properties string (car kill-ring))) 5112 (equal-including-properties s (car kill-ring)))
5103 (if (and replace kill-ring) 5113 (push s kill-ring)))))))
5104 (setcar kill-ring string) 5114 (unless (and kill-do-not-save-duplicates
5105 (let ((history-delete-duplicates nil)) 5115 (equal-including-properties string (car kill-ring)))
5106 (add-to-history 'kill-ring string kill-ring-max t)))) 5116 (if (and replace kill-ring)
5107 (setq kill-ring-yank-pointer kill-ring) 5117 (setcar kill-ring string)
5108 (if interprogram-cut-function 5118 (let ((history-delete-duplicates nil))
5109 (funcall interprogram-cut-function string))) 5119 (add-to-history 'kill-ring string kill-ring-max t))))
5120 (setq kill-ring-yank-pointer kill-ring)
5121 (if interprogram-cut-function
5122 (funcall interprogram-cut-function string))))
5110 5123
5111;; It has been argued that this should work like `self-insert-command' 5124;; It has been argued that this should work like `self-insert-command'
5112;; which merges insertions in `buffer-undo-list' in groups of 20 5125;; which merges insertions in `buffer-undo-list' in groups of 20