As the title says, how does one change the behaviour of emacs forward-word function? For example, suppose [] is the cursor. Then:
my $abs_target_path[]= abs_path($target);
<M-f>
my $abs_target_path = abs[_]path($target);
I know I could just use M-f M-b but as far as I'm concerned, that shouldn't be necessary and I'd like to change it. In particular, I want two things:
- When I press M-f, I want to go to the first character of the next word regardless of whether the point is within a word, within a group of spaces or somewhere else.
- Customize word-characters on a mode-by-mode basis. After all, moving around in CPerl mode is different than, say, TeX mode.
So, in the above example, item 1 would have the cursor would move to the 'a' (and the point to it's left) after hitting M-f. Item 2 would allow me to define underscores and sigils as word characters.
Try:
(require 'misc)
Then use M-x forward-to-word
and see if it does what you want. You can then rebind M-f
, etc.
To make the _
not a word separator (i.e. make it a word constituent) for C & C++ mode, you would do this:
(modify-syntax-entry ?_ "w" c-mode-syntax-table)
(modify-syntax-entry ?_ "w" c++-mode-syntax-table)
For more information on syntax tables, read this wiki page. Syntax tables are generally named like tex-mode-syntax-table
and cperl-mode-syntax-table
.
See forward-same-syntax function also. probably this is you needed to base on.
I have a minor mode that changes word-based commands to operate on syntax changes (and also CamelCaseSubwords). It may be a bit too fine-grained for some tastes, but I find I basically ever use single character movement anymore.
I wanted to copy the behavior of my previous editor thus needed a bit more control, so here's my take on it:
(defun my-syntax-class (char)
"Return ?s, ?w or ?p depending or whether CHAR is a white-space, word or punctuation character."
(pcase (char-syntax char)
(`?\s ?s)
(`?w ?w)
(`?_ ?w)
(_ ?p)))
(defun my-forward-word (&optional arg)
"Move point forward a word (simulate behavior of Far Manager's editor).
With prefix argument ARG, do it ARG times if positive, or move backwards ARG times if negative."
(interactive "^p")
(or arg (setq arg 1))
(let* ((backward (< arg 0))
(count (abs arg))
(char-next
(if backward 'char-before 'char-after))
(skip-syntax
(if backward 'skip-syntax-backward 'skip-syntax-forward))
(skip-char
(if backward 'backward-char 'forward-char))
prev-char next-char)
(while (> count 0)
(setq next-char (funcall char-next))
(loop
(if (or ; skip one char at a time for whitespace,
(eql next-char ?\n) ; in order to stop on newlines
(eql (char-syntax next-char) ?\s))
(funcall skip-char)
(funcall skip-syntax (char-to-string (char-syntax next-char))))
(setq prev-char next-char)
(setq next-char (funcall char-next))
;; (message (format "Prev: %c %c %c Next: %c %c %c"
;; prev-char (char-syntax prev-char) (my-syntax-class prev-char)
;; next-char (char-syntax next-char) (my-syntax-class next-char)))
(when
(or
(eql prev-char ?\n) ; stop on newlines
(eql next-char ?\n)
(and ; stop on word -> punctuation
(eql (my-syntax-class prev-char) ?w)
(eql (my-syntax-class next-char) ?p))
(and ; stop on word -> whitespace
this-command-keys-shift-translated ; when selecting
(eql (my-syntax-class prev-char) ?w)
(eql (my-syntax-class next-char) ?s))
(and ; stop on whitespace -> non-whitespace
(not backward) ; when going forward
(not this-command-keys-shift-translated) ; and not selecting
(eql (my-syntax-class prev-char) ?s)
(not (eql (my-syntax-class next-char) ?s)))
(and ; stop on non-whitespace -> whitespace
backward ; when going backward
(not this-command-keys-shift-translated) ; and not selecting
(not (eql (my-syntax-class prev-char) ?s))
(eql (my-syntax-class next-char) ?s))
)
(return))
)
(setq count (1- count)))))
(defun delete-word (&optional arg)
"Delete characters forward until encountering the end of a word.
With argument ARG, do this that many times."
(interactive "p")
(delete-region (point) (progn (my-forward-word arg) (point))))
(defun backward-delete-word (arg)
"Delete characters backward until encountering the beginning of a word.
With argument ARG, do this that many times."
(interactive "p")
(delete-word (- arg)))
(defun my-backward-word (&optional arg)
(interactive "^p")
(or arg (setq arg 1))
(my-forward-word (- arg)))
(global-set-key (kbd "C-<left>") 'my-backward-word)
(global-set-key (kbd "C-<right>") 'my-forward-word)
(global-set-key (kbd "C-<delete>") 'delete-word)
(global-set-key (kbd "C-<backspace>") 'backward-delete-word)
来源:https://stackoverflow.com/questions/1771102/changing-emacs-forward-word-behaviour