Issue #222 invalid

'w' command is not compatibile with VIM's behaviour

Anonymous created an issue

When editing *.el file in VIM, 'w' is moveing full code identifier at once (with '-' signs). In Evil it is moving cursor to the first letter after '-' sign. This used to work simmillary in Evil prior to: Commit 1ced4581ca7385ea83ec58483313eecca8bc53a9 Use `forward-word' for cjk-motions

Comments (8)

  1. Frank Fischer repo owner

    This is not a bug but a feature ;)

    Evil now uses Emacs' definition of a word to be more compatible with other Emacs word motions, regular expressions and so on. The definition of what is a "word" is mode specific, so it's the easiest to rely on Emacs for this. But of course, the definition of word in Emacs may differ from its definition in Vim for certain modes.

    But you can redefine the definition of a word in each mode using usual Emacs utilities (modify-category-entries and similar functions).

  2. timcharper

    After an update, I began noticing this behavior immediately and traced it to the same commit. I can empathize with the performance concern motivation, but I find the behavior change to be very debilitating. For example, before this change, I could select my_variable with viw, but now I only get the left or right side of the word. Now the operation is much more complex. viW doesn't get me what I want since the left-paren is not considered a word boundary by that command.

      my_function(my_variable, other_parameter)
    

    I'm not a huge fan of modifying Emacs behavior as this is behavior I also have come to rely on. Perhaps I can relearn, but I am just a bit disgruntled about this change :)

    I understand that it is an optimization problem (not just in code speed, but in achieving the end goals), and this often leads to compromises. I wasn't unhappy with the performance of evil-forward-word prior to this change, so in my eyes, it was a net lose.

    An original goal of evil as, I understood it, was to emulate vim in emacs without stomping on emacs functionality (I'm paraphrasing, and maybe I completely misunderstood). Having to change my emacs word boundary list to restore what was previously a sane vim behavior seems to violate that goal.

  3. Frank Fischer repo owner

    IIRC, there was a serious performance problem (I think it came apparent in large latex files that I often work with). But now I'm even convinced that using the Emacs definition of a "word" is better: it is simply more consistent with the rest. For example, the regular expression class [:word:] uses the same definition (and so that the evil shortcut \w). Unfortunately the Emacs "word" often does not include the underline.

  4. timcharper

    I respect that it was a serious performance problem. The idealist in me is sorta-on-board with you on the cleanliness and uniformity argument. The pragmatist, however, counters with the following arguments:

    • I don't like the (modify-syntax-entry ?_ "w") approach as I have to install a hook to enable it for every applicable mode. This is a shotgun-surgery style workaround that affects emacs core commands.
    • I like Emacs behavior for M-d, C-M-h, both deleting up to an underscore.
    • I don't like the new default evil behavior of not respecting _. I have to choose between not liking the viw behavior, or not liking M-d.
    • I don't like mode-specific word boundaries for modal editing. It makes things less predictable and causes my fingers to feel rather clumsy. In fact, I don't really like mode-specific word boundaries at all. Unfortunately, there doesn't appear to be a clean way, in Emacs, to modify the boundaries for all mode syntaxes. This is most unfortunate.
    • The modify-syntax-entry tweak is a work-around to restore a vim behavior which persists after evil-mode is disabled.

    I've come up with the following workaround. It's a much smaller change as much of the code is repeated, but it shows that we can extend emacs forward-word in a way that should be quick and also honor additional vim characters as word boundaries (in this case, the _).

    https://gist.github.com/timcharper/5034251

  5. Frank Fischer repo owner

    In the moment you use [:word:], you will get mode specific word boundaries. Certainly they may be different if you use them in regular expressions together with other characters, but it will still dependent on the definition of a word.

    I prefer to be able to rely in the fact that [:word:] is exactly a word character everywhere in evil.

    In my opinion, it's better to replace the word motions and text-objects by motions that work on symbols than to redefine core functions. For text objects this is already done (currently only in master), they are bound to io and ao. You can bind them to iw and aw if you like. There are currently no basic symbol-motions (like w, e, b and ge), but if you need them and could provide an implementation (based on forward-symbol) I would be happy to integrate them (I think it would be nice to have a complete set of symbol-motions, maybe not bound to any key but ready to be bound if someone prefers them).

    But what should I say. There's probably no perfect solution. We have to find a compromise.

  6. Log in to comment