Editing Fortran in Emacs with f90-mode, I would like the “word commands” M-b, M-f, M-d, M-DEL and so on to act on “words” as separated by underscores. On the other hand, for the syntax highlighting, commands like C-M-f, and so on, the underscores obviously must not break apart identifiers.

subword-mode partially does this: M-f and M-d act like I want, but M-b and M-DEL still treat the whole identifier as one word. To illustrate: if point is after some_thing, M-b (subword-backward) will move it to s; after that, M-f (subword-forward) will move point to _.

In f90-mode, _ has syntax class "w" (word). If I change it to "_" (symbol) or "." (punctuation), I get the desired behavior, but then some_thing will also be two words to font lock and completion. E.g., program my_prog; end will be completed only to end my, and write_me would be incorrectly fontified (write as a keyword).

How do I get both things at once?

PS: This is GNU Emacs 24.

EDIT: Here is the complete code I ended up using, building on cadrians answer (thanks!)

(let ((adv (cons 'advice
                 (lambda ()
                   (let ((os (char-syntax ?_)))
                     (modify-syntax-entry ?_ "_")
                     (modify-syntax-entry ?_ (string os))))))
      (fun '(subword-forward subword-kill subword-backward
             subword-backward-kill subword-downcase subword-upcase
  (dolist (f fun)
    (ad-add-advice f (list 'underscore-wrap nil t adv)
                   'around 'last)
    (ad-activate f)))

I added a let so as not to change the syntax permanently, and used ad-add-advice to be able to put it in a loop.


One solution is to use defadvice:

(defadvice forward-word (around eif-forward-word activate)
  "forward-word, with the underscore not being a letter"
  (interactive "p")
  (modify-syntax-entry ?_  "_")
  (modify-syntax-entry ?_  "w"))

Modify forward-word, backword-word, left-word, and right-word.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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