Hello, Thank you both for the feedback. Attached is an updated version.
A few replies: On Fri 06 Sep 2024 at 04:32pm GMT, Philip Kaludercic wrote: > Won't there be an error here if the command is invoked with a negative > argument? Do you mean that you think there should be an error? I don't see any need for that. On Sat 07 Sep 2024 at 12:52pm +03, Eli Zaretskii wrote: > I again ask whether we need this command. It is okay to have a > function (perhaps even an internal one) to move by Unix-words, but > what are the use cases for such a command? That's fine. I've turned it back into a function. > Should we also treat a backslash as delimiter, for MS-Windows? Good idea. That's more useful. -- Sean Whitton
>From 9163f6ab16816702f8bc6acb6f22734eb57acfc7 Mon Sep 17 00:00:00 2001 From: Sean Whitton <spwhit...@spwhitton.name> Date: Fri, 6 Sep 2024 11:35:46 +0100 Subject: [PATCH v3] New commands for moving and killing unix-words * lisp/simple.el (forward-unix-word): New function. (unix-word-rubout, unix-filename-rubout): New commands. * etc/NEWS: Announce the new commands. --- etc/NEWS | 6 ++++++ lisp/simple.el | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index f3e719a34d3..104941425c2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -123,6 +123,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 2453a129d0a..1b910b0ed22 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 (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 (and delim (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 `/' as delimiting words. +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 treated as +a word delimiter. 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