From cd0fc9a4c3995e78150e22e01be9b2f2456402c9 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Fri, 6 Sep 2024 11:35:46 +0100 Subject: [PATCH] New commands unix-word-rubout, unix-filename-rubout * lisp/simple.el (forward-unix-word): New function. (unix-word-rubout, unix-filename-rubout): New commands. * etc/NEWS: Announce the new commands. (cherry picked from commit f6417ba91b3fdffc5af43bc4a7ad0b7ed007f442) --- etc/NEWS | 6 ++++++ lisp/simple.el | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index 6cbd3c712e1..d679b16cfb0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -105,6 +105,12 @@ 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 'unix-word-rubout' and 'unix-filename-rubout'. +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 '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 a375e9deb1a..a2d6ec21250 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -8763,6 +8763,63 @@ constitute a word." ;; If we found something nonempty, return it as a string. (unless (= start end) (buffer-substring-no-properties start end))))) + +(defun forward-unix-word (n &optional delim) + "Move forward N Unix-words. +A Unix-word is whitespace-delimited. +A negative N 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 function +emulates how C-w at the Unix terminal or shell identifies words. + +Optional argument DELIM specifies what characters are considered +whitespace. It is a string as might be passed to `skip-chars-forward'. +The default is \"\\s\\f\\n\\r\\t\\v\". Do not prefix a `^' character." + (when (string-prefix-p "^" delim) + (error "DELIM argument must not begin with `^'")) + (unless (zerop n) + ;; We do skip over newlines by default because `backward-word' does. + (let* ((delim (or delim "\s\f\n\r\t\v")) + (ndelim (format "^%s" delim)) + (start (point)) + (fun (if (> n 0) + #'skip-chars-forward + #'skip-chars-backward))) + (dotimes (_ (abs n)) + (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. +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 slashes as word delimiters. +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 `/' and `\\' are also +treated as delimiting words. See this command's namesake in Info node +`(readline)Commands For Killing'." + (interactive "^p") + (let ((start (point))) + (forward-unix-word (- arg) "\\\\/\s\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