12

There are a number of commands in Emacs which apply to "words." Examples include forward-word, kill-word, upcase-word, mark-word, transpose-words, etc. The definition of "word" seems to vary a bit between the commands. For example, forward-word will stop at an underscore within a word (e.g. foo_bar) but mark-word does not stop at the underscore.

Is it possible to change the definition of "word" when I am in a prog mode so that Emacs will use the appropriate word boundaries for the syntax of the current language?

When I am in c-mode I want forward-word to skip over underscores, and when I am in lisp-mode I want forward-word to skip over both hyphens and underscores, etc.

3 Answers 3

4

Emacs should already use "the appropriate word boundaries for the syntax of the current language". If it does not then file a bug for the major mode for that language.

But maybe you don't really mean words. Maybe you mean symbol syntax, not word syntax. Emacs distinguishes the two.

For symbol syntax, use symbol commands, not word commands: forward-symbol, etc. From your description, this is what you really want.

If you feel you really want to use a word function on a symbol, you can change the syntax category of particular characters to have word-constituent syntax instead of symbol-constituent syntax. But generally this is not what you want to do and you should not need to do it.

See the Elisp manual for info about character syntax. And see the Emacs manual and the Elisp manual for commands and other functions that operate on symbols (not Lisp symbols, but text with symbol syntax, in whatever language).

And keep in mind that operations on sexps are often useful also for acting on symbols: C-M-f (forward-sexp), C-M-t (transpose-sexps), etc.

8
  • C-M-f is bound to forward-sexp and behaves nothing like what you describe. You are right that what I want is to navigate by symbols, but I don't see that option.
    – nispio
    Commented Oct 9, 2014 at 23:08
  • @nispio forward sexp is essentially forward-symbol most of the time, with the added versatility of also going over matching braces. You should give it a chance.
    – Malabarba
    Commented Oct 10, 2014 at 0:39
  • @Malabarba I strongly disagree that forward-sexp is a close approximation of forward-symbol. For starters, it can confusingly jump you over entire functions, landing you hundreds of lines from where you started. It also jumps over argument lists, etc. And try this: given the following lisp code (global-set-key [remap list-buffers] 'ibuffer) place your cursor in the middle of the word remap and run forward-sexp a few times. It raises an error when it reaches the closing ]. No thanks.
    – nispio
    Commented Oct 10, 2014 at 0:55
  • @nispio I always use a combination of sexp and word navigation. That way I can avoid any of these problems, while having the versatility of both. But it's all a matter of preference. ;-) If you know you'll never miss word navigation, superword-mode might be your guy.
    – Malabarba
    Commented Oct 10, 2014 at 1:01
  • Sorry, I should not have suggested that C-M-f and C-M-t act on symbols (they act on sexps). I will edit to correct that impression. But you can certainly bind forward-symbol to any key you like, if you find it particularly useful. There is no transpose-symbols, but you can write one, again, if you think it is useful.
    – Drew
    Commented Oct 10, 2014 at 1:37
11

Take a look at superword-mode and subword-mode. Superword treats underscores as part of a word instead of a boundary, so foo_bar would be treated as a single word.
Subword does the opposite but for camelCase, so fooBar is treated as two words instead of one.

It sounds like the behavior you want is for cc-mode to use superword-mode.

(add-hook 'c-mode-common-hook 'superword-mode)

I would recommend reading over the source for subword-mode, as even if those two modes are not doing exactly what you want, they should show you how to change the word detection behavior.

Longer discussion on emacsredux, and ergomacs.

4
  • Is it possible to make superword-mode play nice with paredit? For example, paredit-forward-kill-word does not delete the whole word (containing underscores) when superword-mode is enabled. Commented Oct 10, 2014 at 4:21
  • It's changing the definition of a word, and paredit is respecting that, so I think it's doing what is asked of it.
    – dgtized
    Commented Oct 10, 2014 at 15:38
  • The thing is that paredit is not respecting that. paredit-forward-kill-word does not kill the same word defined by superword-mode. Commented Oct 10, 2014 at 20:01
  • Oh I misread. Hmm. Just took a look at paredit-forward-kill-word and it looks like it's doing it's own parsing. So might be able to swap that out, but probably not.
    – dgtized
    Commented Oct 10, 2014 at 20:21
3

If I understood your question, you could modify the language syntax table, e.g. For c++:

(modify-syntax-entry ?_ "w" c++-mode-syntax-table)

M-x apropos then look up of syntax-table should help you too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.