aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-10-14 05:09:32 +0200
committerLars Ingebrigtsen2019-10-14 05:09:32 +0200
commita590a8058d52c1cbe0f80b7ed0d8b0abed7bf7ef (patch)
treef2f2a95e13206870428c0ab4c3ff609985bec3f6
parentf0f2a53b27187903c86189bd03f072ac6ddaba9c (diff)
downloademacs-a590a8058d52c1cbe0f80b7ed0d8b0abed7bf7ef.tar.gz
emacs-a590a8058d52c1cbe0f80b7ed0d8b0abed7bf7ef.zip
Allow zap-to-char to use a history
* doc/emacs/killing.texi (Other Kill Commands): Document it. * lisp/simple.el (read-char-with-history): New function (bug#10477). (zap-to-char): Use it to have a history.
-rw-r--r--doc/emacs/killing.texi5
-rw-r--r--etc/NEWS10
-rw-r--r--lisp/simple.el70
3 files changed, 83 insertions, 2 deletions
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index c554d2e2839..80e2868908a 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -244,7 +244,10 @@ with @kbd{C-x @key{DEL}} and @kbd{M-k} (@pxref{Sentences}).
244searching: it reads a character and kills from point up to (and 244searching: it reads a character and kills from point up to (and
245including) the next occurrence of that character in the buffer. A 245including) the next occurrence of that character in the buffer. A
246numeric argument acts as a repeat count; a negative argument means to 246numeric argument acts as a repeat count; a negative argument means to
247search backward and kill text before point. 247search backward and kill text before point. A history of previously
248used characters is maintained and can be accessed via the
249@kbd{M-p}/@kbd{M-n} keystrokes. This is mainly useful if the
250character to be used has to be entered via a complicated input method.
248 251
249@node Kill Options 252@node Kill Options
250@subsection Options for Killing 253@subsection Options for Killing
diff --git a/etc/NEWS b/etc/NEWS
index 4e62627f907..8f95496705f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -454,6 +454,12 @@ Note that this key binding will not work on MS-Windows systems if
454* Editing Changes in Emacs 27.1 454* Editing Changes in Emacs 27.1
455 455
456+++ 456+++
457** 'zap-to-char' uses the new 'read-char-with-history' function to allow
458navigating through the history of characters that have been input.
459This is mostly useful for characters that have complex input methods
460where inputting the character again may involve many keystrokes.
461
462+++
457** 'save-some-buffers' now has a new action in the prompt: 'C-f' will 463** 'save-some-buffers' now has a new action in the prompt: 'C-f' will
458exit the command and switch to the buffer currently being asked about. 464exit the command and switch to the buffer currently being asked about.
459 465
@@ -2376,6 +2382,10 @@ scrolling.
2376 2382
2377* Lisp Changes in Emacs 27.1 2383* Lisp Changes in Emacs 27.1
2378 2384
2385** There is a new function 'read-char-with-history' that works like
2386'read-char', but maintains a history that can be navigated via the
2387'M-p'/'M-n' keystrokes.
2388
2379** 'setq-local' can now set an arbitrary number of variables, which 2389** 'setq-local' can now set an arbitrary number of variables, which
2380makes the syntax more like 'setq'. 2390makes the syntax more like 'setq'.
2381 2391
diff --git a/lisp/simple.el b/lisp/simple.el
index 4d80c4c1b4d..2add2669604 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5159,12 +5159,80 @@ and KILLP is t if a prefix arg was specified."
5159 ;; Avoid warning about delete-backward-char 5159 ;; Avoid warning about delete-backward-char
5160 (with-no-warnings (delete-backward-char n killp)))) 5160 (with-no-warnings (delete-backward-char n killp))))
5161 5161
5162(defvar read-char-with-history--history nil
5163 "The default history for `read-char-with-history'.")
5164
5165(defun read-char-with-history (prompt &optional inherit-input-method seconds
5166 history)
5167 "Like `read-char', but allows navigating in a history.
5168HISTORY is like HIST in `read-from-minibuffer'.
5169
5170The navigation commands are `M-p' and `M-n', with `RET' to select
5171a character from history."
5172 (let* ((result nil)
5173 (real-prompt prompt)
5174 (hist-format
5175 (lambda (char)
5176 (if (string-match ": *\\'" real-prompt)
5177 (format "%s (default %c): "
5178 (substring real-prompt 0 (match-beginning 0))
5179 char)
5180 (format "%s (default %c) " real-prompt char))))
5181 (index 0)
5182 histvar)
5183 ;; Use the same history interface as `read-from-minibuffer'.
5184 (cond
5185 ((null history)
5186 (setq histvar 'read-char-with-history--history))
5187 ((consp history)
5188 (setq histvar (car history)
5189 index (cdr history)))
5190 ((symbolp history)
5191 (setq histvar history))
5192 (t
5193 (error "Invalid history: %s" history)))
5194 (while (not result)
5195 (setq result (read-char prompt inherit-input-method seconds))
5196 ;; Go back in history.
5197 (cond
5198 ((eq result ?\M-p)
5199 (if (>= index (length (symbol-value histvar)))
5200 (progn
5201 (message "Beginning of history; no preceding item")
5202 (ding)
5203 (sit-for 2))
5204 (setq index (1+ index)
5205 prompt (funcall hist-format
5206 (elt (symbol-value histvar) (1- index)))))
5207 (setq result nil))
5208 ;; Go forward in history.
5209 ((eq result ?\M-n)
5210 (if (zerop index)
5211 (progn
5212 (message "End of history; no next item")
5213 (ding)
5214 (sit-for 2))
5215 (setq index (1- index)
5216 prompt (if (zerop index)
5217 real-prompt
5218 (funcall hist-format
5219 (elt (symbol-value histvar) (1- index))))))
5220 (setq result nil))
5221 ;; The user hits RET to either select a history item or to
5222 ;; return RET.
5223 ((eq result ?\r)
5224 (unless (zerop index)
5225 (setq result (elt (symbol-value histvar) (1- index)))))))
5226 ;; Record the chosen key.
5227 (set histvar (cons result (symbol-value histvar)))
5228 result))
5229
5162(defun zap-to-char (arg char) 5230(defun zap-to-char (arg char)
5163 "Kill up to and including ARGth occurrence of CHAR. 5231 "Kill up to and including ARGth occurrence of CHAR.
5164Case is ignored if `case-fold-search' is non-nil in the current buffer. 5232Case is ignored if `case-fold-search' is non-nil in the current buffer.
5165Goes backward if ARG is negative; error if CHAR not found." 5233Goes backward if ARG is negative; error if CHAR not found."
5166 (interactive (list (prefix-numeric-value current-prefix-arg) 5234 (interactive (list (prefix-numeric-value current-prefix-arg)
5167 (read-char "Zap to char: " t))) 5235 (read-char-with-history "Zap to char: " t)))
5168 ;; Avoid "obsolete" warnings for translation-table-for-input. 5236 ;; Avoid "obsolete" warnings for translation-table-for-input.
5169 (with-no-warnings 5237 (with-no-warnings
5170 (if (char-table-p translation-table-for-input) 5238 (if (char-table-p translation-table-for-input)