diff options
| author | Lars Ingebrigtsen | 2019-10-14 05:09:32 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2019-10-14 05:09:32 +0200 |
| commit | a590a8058d52c1cbe0f80b7ed0d8b0abed7bf7ef (patch) | |
| tree | f2f2a95e13206870428c0ab4c3ff609985bec3f6 | |
| parent | f0f2a53b27187903c86189bd03f072ac6ddaba9c (diff) | |
| download | emacs-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.texi | 5 | ||||
| -rw-r--r-- | etc/NEWS | 10 | ||||
| -rw-r--r-- | lisp/simple.el | 70 |
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}). | |||
| 244 | searching: it reads a character and kills from point up to (and | 244 | searching: it reads a character and kills from point up to (and |
| 245 | including) the next occurrence of that character in the buffer. A | 245 | including) the next occurrence of that character in the buffer. A |
| 246 | numeric argument acts as a repeat count; a negative argument means to | 246 | numeric argument acts as a repeat count; a negative argument means to |
| 247 | search backward and kill text before point. | 247 | search backward and kill text before point. A history of previously |
| 248 | used characters is maintained and can be accessed via the | ||
| 249 | @kbd{M-p}/@kbd{M-n} keystrokes. This is mainly useful if the | ||
| 250 | character 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 |
| @@ -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 | ||
| 458 | navigating through the history of characters that have been input. | ||
| 459 | This is mostly useful for characters that have complex input methods | ||
| 460 | where 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 |
| 458 | exit the command and switch to the buffer currently being asked about. | 464 | exit 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 |
| 2380 | makes the syntax more like 'setq'. | 2390 | makes 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. | ||
| 5168 | HISTORY is like HIST in `read-from-minibuffer'. | ||
| 5169 | |||
| 5170 | The navigation commands are `M-p' and `M-n', with `RET' to select | ||
| 5171 | a 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. |
| 5164 | Case is ignored if `case-fold-search' is non-nil in the current buffer. | 5232 | Case is ignored if `case-fold-search' is non-nil in the current buffer. |
| 5165 | Goes backward if ARG is negative; error if CHAR not found." | 5233 | Goes 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) |