From c047e640399bb923728ed9967e8545d53b22ea5c Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Fri, 6 Sep 2024 11:35:46 +0100 Subject: [PATCH] New commands for moving and killing unix-words * lisp/simple.el (forward-unix-word, unix-word-rubout) (unix-filename-rubout): New commands. * etc/NEWS: Document them. --- etc/NEWS | 7 +++++++ lisp/simple.el | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index f3e719a34d3..54cf0a3df52 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -123,6 +123,13 @@ When using 'visual-wrap-prefix-mode' in buffers with variable-pitch fonts, the wrapped text will now be lined up correctly so that it's exactly below the text after the prefix on the first line. +--- +** New commands for moving and killing unix-words. +Unix-words are words separated by whitespace regardless of the buffer's +syntax table. In a Unix terminal or shell, C-w kills by unix-word. +The new commands 'forward-unix-word', 'unix-word-rubout' and +'unix-filename-rubout' allow you to bind keys to operate more similarly +to the terminal. * Changes in Specialized Modes and Packages in Emacs 31.1 diff --git a/lisp/simple.el b/lisp/simple.el index 2453a129d0a..0322ac0cd8c 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -8892,6 +8892,63 @@ current-word ;; If we found something nonempty, return it as a string. (unless (= start end) (buffer-substring-no-properties start end))))) + +(defun forward-unix-word (arg &optional delim) + "Move forward ARG unix-words. +A unix-word is whitespace-delimited. +Interactively, ARG is the numeric prefix argument, defaulting to 1. +A negative ARG means go backwards to the beginning of unix-words. + +Unix-words differ from Emacs words in that they are always delimited by +whitespace, regardless of the buffer's syntax table. This command +emulates how C-w at the Unix terminal or shell identifies words. + +When called from Lisp, DELIM specifies what characters are considered +whitespace. It is a string as might be passed to `skip-chars-forward'. +The default is \" \\f\\n\\r\\t\\v\". Do not prefix a `^' character." + (interactive "^p") + (unless (zerop arg) + ;; We do skip over newlines by default because `backward-word' does. + (let* ((delim (or delim " \f\n\r\t\v")) + (ndelim (format "^%s" delim)) + (start (point)) + (fun (if (> arg 0) + #'skip-chars-forward + #'skip-chars-backward))) + (dotimes (_ (abs arg)) + (funcall fun delim) + (funcall fun ndelim)) + (constrain-to-field nil start)))) + +(defun unix-word-rubout (arg) + "Kill ARG unix-words backwards. +A unix-word is whitespace-delimited. +Interactively, ARG is the numeric prefix argument, defaulting to 1. +A negative ARG means to kill forwards. + +Unix-words differ from Emacs words in that they are always delimited by +whitespace, regardless of the buffer's syntax table. Thus, this command +emulates C-w at the Unix terminal or shell identifies words. +See also this command's nakesake in Info node +`(readline)Commands For Killing'." + (interactive "^p") + (let ((start (point))) + (forward-unix-word (- arg)) + (kill-region start (point)))) + +(defun unix-filename-rubout (arg) + "Kill ARG unix-words backwards, also treating `/' as whitespace. +A unix-word is whitespace-delimited. +Interactively, ARG is the numeric prefix argument, defaulting to 1. +A negative ARG means to kill forwards. + +This is like `unix-word-rubout' (which see), but `/' is also considered +whitespace. See this command's namesake in Info node +`(readline)Commands For Killing'." + (interactive "^p") + (let ((start (point))) + (forward-unix-word (- arg) "/ \f\n\r\t\v") + (kill-region start (point)))) (defcustom fill-prefix nil "String for filling to insert at front of new line, or nil for none." -- 2.39.2