t9md / atom-vim-mode-plus

vim-mode improved
https://atom.io/packages/vim-mode-plus
MIT License
1.4k stars 111 forks source link

Prevent Grammar from changing motions #1043

Closed lydell closed 6 years ago

lydell commented 6 years ago
debug info ```json { "atom": "1.24.1", "platform": "linux", "release": "4.13.0-36-generic", "vmpVersion": "1.30.0", "vmpConfig": { "blackholeRegisteredOperators": [], "startInInsertModeScopes": [], "charactersToAddSpaceOnSurround": [], "highlightSearchExcludeScopes": [], "flashOnOperateBlacklist": [] } } ```

Check list

You have to check all before open issue.

In CSS, w motion does not work as usual. In JSX, % motion does not work as usual.

I want the motions to work the same regardless of current grammar.

Sorry if I’m missing something obvious!

CSS example:

a {
  margin-left: 10px;
}

The cursor is on m and I want to change left to right (because I added the margin on the wrong side). So I press wwceright. However, the result is not as expected:

a {
  margin-left: right;
}

- does not seem to be considered a “word boundary”. This only happens in CSS. If I change the grammar to plain text, it works fine. (Vim does not have this behavior in CSS.)

JSX example

function regular() {
  return div(
    {prop: Math.round(distance / time)}
  )
}

function JSX() {
  return (
    <div prop={Math.round(distance / time)}>
      test
    </div>
  )
}
  1. The cursor is on <div. If I press % the cursor jumps to </div>. This is a good feature. :+1:

  2. The cursor is on M in the JSX example. I want to change the Math.round call into velocity (because I want to move the calculation into a variable). So I press c%velocity. However, the result is not as expected:

    function JSX() {
     return (
       <div prop={velocitydiv>
     }
    }
  3. The cursor is on { (before the M in the previous point) in the JSX example. I want to change the entire prop value to "5". So I press c%"5". Again, the result is not what I wanted:

    function JSX() {
     return (
       <div prop="5"div>
     }
    }

Now try (2) and (3) above on the “regular” example to see how I’m used to % working.

The above happens with and without the language-babel package installed.

Workaround: cf) and cf} work instead of c% in many cases.

Versions

Atom    : 1.24.1
Electron: 1.6.16
Chrome  : 56.0.2924.87
Node    : 7.4.0

vmp: 1.30.0
OS: Ubuntu 17.10

Tested in a clean Atom profile: env ATOM_HOME=$HOME/.atom-test atom . where .atom-test didn’t exist before and I only installed vim-mode-plus (no other changes).

t9md commented 6 years ago

Same as #1008. Currently vmp take regex pattern from cursor.wordRegExp() which return word regex based on current grammar. Some grammars have - pattern in returned regex, but some are not. I understand the motive to make this consistent, regardless of grammar. Will try to fix it. Thanks for feedback.

t9md commented 6 years ago

The cursor is on m and I want to change left to right (because I added the margin on the wrong side). So I press wwceright. However, the result is not as expected:

I can't reproduce this. My grammar scopeName is source.css and I can replace left to right from m char by wwceright. Strange.

t9md commented 6 years ago

The cursor is on M in the JSX example. I want to change the Math.round call into velocity (because I want to move the calculation into a variable). So I press c%velocity. However, the result is not as expected:

I understand why this happens, but this is not same cause I described in first comment. To fix this, special care need to be added for % motion(I remember this also have reported and still opened in other issue).

Anyway in such editing situation, my keystroke always would be c ; then type velocity.

  1. c to change(then enter operator-pending-mode, require target(motion or text-object).
  2. ; is shorthand of inner-any-pair text-object which auto-detect closest enclosed pair range. You can set ; shortcut by yourself or enabling conditional keymap setting in GIF bellow.
settings
lydell commented 6 years ago

Hmm, odd that you couldn't reproduce the CSS case. I'll double check that I didn't mess anything up. EDIT: Double checked in a clean profile, and can still reproduce.

Thanks for the inner-any-pair tip! I already have a mapping for that, and I've noticed that it works better in JSX. However, % sits deep into my fingers :) And it wouldn't help in this case:

function JSX() {
  return (
    <div prop={baseVelocity + Math.round(distance / time)}>
      test
    </div>
  )
}

If I only want to replace Math.round(distance / time) I think the easiest way is to go to M and then do c%.

t9md commented 6 years ago

Hmm, odd that you couldn't reproduce the CSS case. I'll double check that I didn't mess anything up.

Sorry, never mind. I found I can not reproduce issue when I use atom v1.26.0-beta0(I normally use latest beta). Seems something has been changed in this version.

For the situation you mentioned.

If I only want to replace Math.round(distance / time) I think the easiest way is to go to M and then do c%.

My way is

Inner-arguments huristically detect seem-to-be-argument like parameter. Sometime it fail, but works in variety of situation.

Test-case is readable use cases. https://github.com/t9md/atom-vim-mode-plus/blob/master/spec/text-object-spec.coffee#L1824

And GIF when it's released https://twitter.com/t9md/status/852767349941739525

t9md commented 6 years ago

I use some text-objects very frequently. Each have shorthand keymap in operator-pending-mode. So to change one of these targets. Keystroke would be

Plus with I added custom keymap in keymap.cson

'atom-text-editor.vim-mode-plus.operator-pending-mode':
  'u': 'vim-mode-plus:a-indentation'
  "m": "vim-mode-plus:a-any-pair",

Which enable me to type

t9md commented 6 years ago

various-text-objects

lydell commented 6 years ago

Awesome, thanks! I'll play around with those.

I just found a workaround for CSS: Add - to "Non Word Characters" in the language-css package settings. Never knew about that option before. I also did this in language-sass – note that there's two "Non Word Characters" there though: One for Sass syntax and one for SCSS syntax.

I guess you could also consider the CSS case a feature, allowing people to customize the word boundaries per grammar (I think you can do this in Vim too?). If so, it could be helpful to add a tip about this in the FAQ.

t9md commented 6 years ago

I just found a workaround for CSS: Add - to "Non Word Characters" in the language-css package settings. Never knew about that option before. I also did this in language-sass – note that there's two "Non Word Characters" there though: One for Sass syntax and one for SCSS syntax.

I'm now implementing exactly this feature which is just sugar I know. Introducing useLanguageIndependentNonWordCharacters setting and corresponding languageIndependentNonWordCharacters.

lydell commented 6 years ago

Wow, awesome! I'd like that option very much :)

t9md commented 6 years ago

Released vim-mode-plus@v1.31.0 now.

t9md commented 6 years ago

Fixed one issue reported this issue. And remaining issue is % motion which I believe duplicate of #700. If you agree with this my understanding, close this issue then.

lydell commented 6 years ago

Thanks, 1.31.0 does exactly what I want for the CSS case. I also think the % case is a duplicate of #700, so I’m closing this. Thanks for the tip about the arguments text object! I haven’t built an intuition for how it works yet, but I suspect it will replace % for me in many cases after some practice.