Issue #187 wontfix

The 'evil-word' variable is not used for moving

Sebastien Mondet
created an issue

The movements with 'e', 'w', 'b', ... do not use the evil-word command (they just follow the emacs syntax-table). This is not consistent with Vim.

Comments (8)

  1. Sebastien Mondet reporter

    My current hack around this looks like:

    ;; Add '_' to the meaning of ":word:" everytime a buffer is loaded:
    (add-hook 'after-change-major-mode-hook
              '(lambda () (modify-syntax-entry ?_ "w")))
    
  2. Frank Fischer repo owner

    That's right, evil-word is not used anymore for word motions (and should be removed completely). Instead we rely on Emacs's own abilities to define what character belongs to a word, which is more consistent within Emacs itself. This allows us to use Emacs own functions for word motions without hacking around our own definition of "word". So I assume that your hack is indeed the correct way to go.

  3. rfflrccrd

    Hence, Evil deviates from Vim here, right? Because for instance, while editing Emacs Lisp code, in Vim the "w" command makes the cursor move by symbols, thus skipping other graphic characters besides "_". Considering that each programming language has a different character set available for symbols, is it possible to make Sebastien's proposed work for the general case? Thanks.

  4. Frank Fischer repo owner

    Well, I would say Emacs deviates from Vim here. The definition of a "word" is mode-specific, buy just not the same as in Vim.

    Given that each programming language has a different character set available for symbols, it is virtually impossible for evil to give the correct definition for each mode. Instead is should rely on Emacs to define what a word is in the current language.

    However, Emacs knows another class of characters known as 'symbols', and this is probably closer to what you want (e.g. a "-" is a symbol in lisp but not in C). Currently evil only supports symbol text-objects (in the master-branch bound to "io" and "ao") but no elementary motions. It should not be too difficult to define motions that work on symbol instead of word characters analogously to word motions. Then a user could decide which set of motions should be used.

    It may not be so easy to just change a certain regexp because other functions that rely on the definition of a word may also be used, e.g. forward-word. I'm not sure if Evil uses only regexps.

    Furthermore it may be useful to have both sets of motions, for word and symbol, available. I think the best approach is to define a new set of motions for symbols. The user could then replace the existing key-bindings (there could also be a convenient function that updates all bindings in Evil's keymaps).

    Anyway, we need someone who implements these motions ... ;)

  5. rfflrccrd

    IMO, having a different set of motions would be overkill. In a natural language a word is a word, in a programming language a token is a word. By making two separate sets of functions available, we would be making the user work instead of the computer. Sure, having specific commands may be useful in corner cases, but a software ought to handle the general case in a reasonable manner. The general case is that programmers want to move by tokens. Still, trying to define what a token is, that would open a can of worms. Apparently, Vim makes a reasonable choice by defining as a word either a symbol or a sequence of non-symbol characters. I don't know whether that would be feasible in Evil. I haven't done serious coding in Emacs Lisp for a long time, hence I can't look into it right now. However, `modify-syntax-entry' at least allows us to define a symbol as a word without messing with regexps, and it could be customized for every programming language by means of its major mode hook, like this:

    (defun evil-add-word-constituents (char-string)
      "Add characters in CHAR-STRING as word constituents in the current buffer,
    by modifying its syntax table."
      (dolist (char (string-to-list char-string))
        (modify-syntax-entry char "w")))
    
    (defun c-mode-hook ()
      (evil-add-word-constituents "_"))
    
    (add-hook 'c-mode-hook #'c-mode-hook)
    

    A better solution would allow to undo such a customization, but as said, my Emacs Lisp coding skills are rusty, and I have to postpone a complete solution.

    Anyway, thank you guys for your great work with Evil.

    Cheers.

  6. Log in to comment