Does operatorPendingModeKeyBindings work with visual selections?
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.2k
- Forks
- 1.5k
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 6
Description
This might be me doing something dumb here but I'm trying to get operatorPendingModeKeyBindings to work with a visual selection, ie move, visually select text. This works in normal vim through various trickery like normal! but that doesn't seem to apply here and I'm not sure if I'm doing something wrong or it's a bug as it seems to do something not quite correct.
with this setup:
"vim.visualModeKeyBindings": [
{
"before": ["i", "l"],
"after": ["^", "v", "g", "_"]
},
],
"vim.operatorPendingModeKeyBindings": [
{
"before": ["i", "l"],
"after": ["^", "v", "g", "_"]
},
],
I am trying to delete/copy/yank an "inner line", ie. all text in the line but excluding whitespace on either end. There is no text object for this in vim so accomplishing via visual mode is a common setup. I move to beginning of the line, go into visual mode, and move to end of line (whitespace exclusive). The result is this:
https://user-images.githubusercontent.com/74646/132302452-caf2a393-67fa-4324-a492-358a7da4aa6d.mov
Compare this to vim which deletes the entire line but leaves the whitespace:
https://user-images.githubusercontent.com/74646/132302515-9b2a1937-d379-4739-9942-6f01c009446a.mov
It seems that the initial ^ is respected as part of a range but going into visual mode aborts the operation.
Am I setting this up wrong? Note that the original vim setup is this:
vmap il :<C-U>silent! normal! ^vg_<CR>
omap il :normal ^vg_<CR>
I dug through the code a bit to know that normal! isn't supported (yet) so the <CR> shouldn't be required and silent! is ignored.
Debug logs on init are (note it doesn't seem to log pending operation remaps):
[Extension Host] Configuration: debug: 0 errors found with vim configuration
workbench.desktop.main.js:sourcemap:71 [Extension Host] Extension Startup: debug: Start
workbench.desktop.main.js:sourcemap:71 [Extension Host] vscode-context: debug: Setting key='vim.mode' to value='Normal'
workbench.desktop.main.js:sourcemap:71 [Extension Host] vscode-context: debug: Setting key='listAutomaticKeyboardNavigation' to value='false'
workbench.desktop.main.js:sourcemap:71 [Extension Host] vscode-context: debug: Setting key='vim.active' to value='true'
workbench.desktop.main.js:sourcemap:71 [Extension Host] ModeHandler: debug: handling key=<extensionenable>.
workbench.desktop.main.js:sourcemap:71 [Extension Host] Remapper: debug: trying to find matching remap. keys=<ExtensionEnable>. mode=Normal. keybindings=normalModeKeyBindingsMap.
workbench.desktop.main.js:sourcemap:71 [Extension Host] ModeHandler: debug: handleKeyEvent('<extensionenable>') took 6ms
workbench.desktop.main.js:sourcemap:71 [Extension Host] Extension Startup: debug: Finish.
And during the operation:
[Extension Host] ModeHandler: debug: handling key=d.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=d. mode=Normal. keybindings=normalModeKeyBindingsMap.
console.ts:137 [Extension Host] Remapper: debug: normalModeKeyBindingsMap. potential remap found. waiting for other key or timeout to finish.
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('d') took 0ms
console.ts:137 [Extension Host] ModeHandler: debug: handling key=i.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=d,i. mode=Normal. keybindings=normalModeKeyBindingsMap.
console.ts:137 [Extension Host] Remapper: verbose: key=d,i. keySlice=di.
console.ts:137 [Extension Host] Remapper: debug: normalModeKeyBindingsMap. potential remap broken. resending keys without allowing a potential remap on first key. keys=d,i
console.ts:137 [Extension Host] ModeHandler: debug: handling key=d.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=d. mode=Normal. keybindings=normalModeKeyBindingsMap.
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('d') took 3ms
console.ts:137 [Extension Host] ModeHandler: debug: handling key=i.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=i. mode=Normal. keybindings=operatorPendingModeKeyBindingsMap.
console.ts:137 [Extension Host] Remapper: debug: operatorPendingModeKeyBindingsMap. potential remap found. waiting for other key or timeout to finish.
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('i') took 1ms
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('i') took 4ms
console.ts:137 [Extension Host] ModeHandler: debug: handling key=l.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=i,l. mode=Normal. keybindings=operatorPendingModeKeyBindingsMap.
console.ts:137 [Extension Host] Remapper: verbose: key=i,l. keySlice=il.
console.ts:137 [Extension Host] Remapper: debug: operatorPendingModeKeyBindingsMap. match found. before=i,l. after=^,v,g,_. command=undefined. remainingKeys=. mapDepth=1.
console.ts:137 [Extension Host] ModeHandler: debug: handling key=^.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=^. mode=Normal. keybindings=operatorPendingModeKeyBindingsMap.
console.ts:137 [Extension Host] Transformer: debug: Adding Transformation {"type":"deleteRange","range":[{"line":10,"character":4},{"line":10,"character":28}]}
console.ts:137 [Extension Host] Extension Startup: debug: Selections: ignoring intermediate selection change: [10, 4; 10, 4]
console.ts:137 [Extension Host] HistoryTracker: debug: Set nextStepStartPosition to [10, 28]
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('^') took 19ms
console.ts:137 [Extension Host] ModeHandler: debug: handling key=v.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=v. mode=Normal. keybindings=normalModeKeyBindingsMap.
console.ts:137 [Extension Host] ModeHandler: debug: Selections: Adding Selection Change to be Ignored! Hash: [10, 4; 10, 5], Selections: [10, 4], [10, 5]
console.ts:137 [Extension Host] vscode-context: debug: Setting key='vim.mode' to value='Visual'
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('v') took 2ms
console.ts:137 [Extension Host] ModeHandler: debug: handling key=g.
console.ts:137 [Extension Host] Remapper: debug: trying to find matching remap. keys=g. mode=Visual. keybindings=visualModeKeyBindingsMap.
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('g') took 3ms
console.ts:137 [Extension Host] ModeHandler: debug: handling key=_.
console.ts:137 [Extension Host] Extension Startup: debug: Selections: Ignoring selection: [10, 4; 10, 5], Count left: 0
console.ts:137 [Extension Host] Extension Startup: debug: Selections: ignoring intermediate selection change: [10, 4; 10, 4]
console.ts:137 [Extension Host] Extension Startup: debug: Selections: ignoring intermediate selection change: [10, 4; 10, 19]
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('_') took 25ms
console.ts:137 [Extension Host] HistoryTracker: debug: Finished history step with 1 change(s)
console.ts:137 [Extension Host] ModeHandler: debug: handleKeyEvent('l') took 51ms
Thanks for any help!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the shown vim.visualModeKeyBindings and vim.operatorPendingModeKeyBindings settings, using the operator-pending debug trace as the starting point. Trace the remap through the ^, v, g, _ sequence and confirm that the visual selection completes the delete, copy, or yank with the intended whitespace boundaries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 42/100