Hello, On Thu 05 Sep 2024 at 02:38pm GMT, Philip Kaludercic wrote:
> In that case, it would be difficult to use it directly in this > implementation, as kill-region needs a command that just moves the > point. I guess it would be possible to hack something together with > atomic change groups, but the cleanest strategy would probably be to > have a unix-word-forward command that goes in both directions, and use > that both in a standalone unix-word-rubout and this patch. But we can > do that after merging this patch -- assuming there are no more blocking > issues with the latest version: I think you're right, but I would like to commit my function first, so that I get attribution (it did take me some time to figure out what was useful in this area), and because I think it should be rewritten in terms of fields. Please take a look at the attached. unix-word-rubout to follow. -- Sean Whitton
>From 4cb701150976cdb91658a1c82edd6e8270fd26c8 Mon Sep 17 00:00:00 2001 From: Sean Whitton <spwhit...@spwhitton.name> Date: Fri, 6 Sep 2024 11:35:46 +0100 Subject: [PATCH] New command forward-unix-word * lisp/simple.el (forward-unix-word): New command. * doc/lispref/positions.texi (Word Motion): * etc/NEWS: Document it. --- doc/lispref/positions.texi | 13 +++++++++++++ etc/NEWS | 5 +++++ lisp/simple.el | 30 ++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index 37cfe264157..b576df82382 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -275,6 +275,19 @@ Word Motion syntax tables. @end defun +@deffn Command forward-unix-word &optional arg delim +This function is like @code{forward-word}, except that words are always +delimited by whitespace, regardless of the buffer's syntax table. This +emulates how @kbd{C-w} at the Unix terminal or shell identifies words. +See the @code{unix-word-rubout} command in @xref{(readline)Commands For +Killing}. + +Lisp programs can pass the @var{delim} argument to specify the notion of +whitespace. This argument is a string listing the characters considered +whitespace, as might be passed to @code{skip-chars-forward}. The +default is @code{[:space:]\n}. Do not prefix a `^' character. +@end deffn + @node Buffer End Motion @subsection Motion to an End of the Buffer @cindex move to beginning or end of buffer diff --git a/etc/NEWS b/etc/NEWS index f3e719a34d3..8037fcfd1af 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -123,6 +123,11 @@ 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 command 'forward-unix-word'. +This command is like 'forward-word', except it always considers words to +be delimited by whitespace, regardless of the buffer's syntax table. +It thus emulates how C-w at the Unix terminal or shell identifies words. * Changes in Specialized Modes and Packages in Emacs 31.1 diff --git a/lisp/simple.el b/lisp/simple.el index 2453a129d0a..f34eef9ac25 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -8892,6 +8892,36 @@ 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 (&optional arg delim) + "Move forward to the end of the next whitespace-delimited word. +With argument ARG, do this that many times; the default is once. +With negative ARG, go backwards to the beginning of whitespace-delimited +words. +DELIM is a string specifying what characters are considered whitespace, +as might be passed to `skip-chars-forward'. +The default is \"[:space:]\\n\". Do not prefix a `^' character. + +This command is like `forward-word' except that words are always +delimited by whitespace, regardless of the buffer's syntax table. +Like `forward-word', this command respects fields. + +This emulates how C-w at the Unix terminal or shell identifies words. +See the `unix-word-rubout' command in Info node `(readline)Commands For +Killing'." + (interactive "^p") + (unless (zerop arg) + ;; We do skip over \n by default because `backward-word' does. + (let* ((delim (or delim "[:space:]\n")) + (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)))) (defcustom fill-prefix nil "String for filling to insert at front of new line, or nil for none." -- 2.39.2