Jump and SelectJump/move the cursor to the next or previous occurrence of some typed character or group of characters (in a keybinding). Notable Changes in v0.6.0Deprecated : The settings
are all deprecated. They still work in your
Notable Changes in v0.5.0
See Using regular expressions in a keybinding.
See the GitHub Discussions to provide input on new features. How It WorksChoose one of your keybindings, say Alt+f to jump forward.
Using
|
Setting | options | Default |
---|---|---|
restrictSearch | document/line | document |
putCursorForwardJump | beforeCharacter/afterCharacter | beforeCharacter |
putCursorForwardSelect | beforeCharacter/afterCharacter | afterCharacter |
putCursorBackwardJump | beforeCharacter/afterCharacter | beforeCharacter |
putCursorBackwardSelect | beforeCharacter/afterCharacte | beforeCharacter |
restrictSearch
"line"
: Move the cursor or select within the current line only
"document
: Move the cursor or select within the entire document
putCursorForwardJump
: cursor is moving forward or down in the document
"beforeCharacter"
: Move the cursor to before the next chosen character
"afterCharacter"
: Move the cursor to after the next chosen character
putCursorForwardSelect
: cursor and selection is moving forward or down in the document
"beforeCharacter"
: Select to before the previous chosen character
"afterCharacter"
: Select to after the previous chosen character
putCursorBackwardJump
: cursor is moving backward or up in the document
"beforeCharacter"
: Move the cursor to before the next chosen character
"afterCharacter"
: Move the cursor to after the next chosen character
putCursorBackwardSelect
: cursor and selection is moving backward or up in the document
"beforeCharacter"
: Select to before the previous chosen character
"afterCharacter"
: Select to after the previous chosen character
Examples:
"putCursorForwardJump": "beforeCharacter"
if text is |abcde|f
jumping forward from a
to f
would put the cursor before f
.
"putCursorForwardJump": "afterCharacter"
if text is |abcdef|
jumping forward from a
to f
would put the cursor after f
.
Selections will act the same way: either the selection will not include the chosen character (the one you type) or the selection will include that character.
Example of modified settings (in settings.json
) after setting the values in the Settings UI (search for "jump"):
"jump-and-select.defaults": {
"putCursorOnForwardSelect": "beforeCharacter",
"putCursorOnBackwardJump": "afterCharacter"
}
- Note:
beforeCharacter
should really bebeforeQuery
andafterCharacter
should beafterQuery
. The original names are from a time when you could only input one typed character at a time. But in the keybindingstext
argument you can have multiple characters likehowdy
orabc\\$
and the cursor will go before or after that entire query. So think of them asbeforeQuery
andafterQuery
- which may be a single or multiple characters.
There is a precedence to the option values. Any option set in a keybinding takes precedence over the jump-and-select.defaults
setting which takes precedence over the deprecated settings mentioned above.
Extension Commands
jump-and-select.jumpForward
: Move to the next occurrence of the character. Alt+fjump-and-select.jumpForwardSelect
: Select from the cursor to the next occurrence of the character. Shift+Alt+fjump-and-select.jumpBackward
: Move to the previous occurrence of the character. Alt+bjump-and-select.jumpBackwardSelect
: Select from the cursor to the previous occurrence of the character. Shift+Alt+bjump-and-select.abortMultiMode
: Abort or leavemultiMode
- to return to regular text entry. No default keybinding. Appears in the Command Palette (or Keyboard Shortcuts) asJump-Select: Abort MultiMode
whenmultimode
is active.
When you trigger one of these commands, you will not see the next character you type - instead that character will trigger a search for that character. A space is considered a character (but oddly tabs are not?), as well as the regular expression characters ^
and $
.
Example Keybindings
You can change the default arguments, like restrictSearch/putCursorForwardJump/putCursorBackwardJump
/etc , in your Settings UI
. Search for jump-and-select
and you should see these options.
You can set the command arguments like this in your keybindings.json
and these will override the settings defaults for these keybindings:
{
"key": "alt+f", // <== change this to whatever you want
"command": "jump-and-select.jumpForward"
// "when": "editorTextFocus && editorLangId == javascript" // for example
}
{
"key": "alt+r",
"command": "jump-and-select.jumpBackwardSelect",
"args": {
// the args that can be used in a keybinding
"text": "hello", // no default
// "putCursorForwardJump" is used if the command is 'jumpForward' or 'jumpForwardMultiMode'
// "putCursorForwardSelect" is used if the command is 'jumpForwardSelect' or 'jumpForwardSelectMultiMode'
// "putCursorBackwardJump" is used if the command is 'jumpBackward' or 'jumpBackwardMultiMode'
"putCursorBackwardSelect": "beforeCharacter", // or "afterCharacter"
"restrictSearch": "document" // or "line" to search in the current line only
}
}
In this last example, you would use putCursorBackwardSelect
and not putCursorForwardSelect
because the command jumpBackwardSelect
is jumping backward and thus putCursorForwardSelect
is an error. For commands that are jumping forward use putCursorForwardJump
or putCursorForwardSelect
.
For more on using keybindings and macros.
Multimode Commands
What is MultiMode
? It means you can trigger the command ONCE and then move/select as many times as you want.
A clickable button appears in the Status Bar to indicate that to exit/stop the command and get back to normal text insertion/deletion you can exit multiMode
by hitting the Return (unfortunately Escape will not work). That Status Bar reminder will hide when you do exit the command successfully and reappear the next time you invoke a MultiMode command.
You can also exit multiMode
by clicking on the StatusBarItem or by invoking the command Jump-Select: Abort MultiMode
(jump-and-select.abortMultiMode
) either from a keybinding you set up or through the Command Palette.
jump-and-select.jumpForwardMultiMode
: Move to the next occurrence of the character. Alt+m Alt+fjump-and-select.jumpForwardSelectMultiMode
: Select from the cursor to the next occurrence of the character. Shift+Alt+m Shift+Alt+fjump-and-select.jumpBackwardMultiMode
: Move to the previous occurrence of the character. Alt+m Alt+bjump-and-select.jumpBackwardSelectMultiMode
: Select from the cursor to the previous occurrence of the character. Shift+Alt+m Shift+Alt+b
To trigger Alt+m Alt+f you can hold down the Alt key and then hit m and then f and release and MultiMode is running. These are just suggested keybindings, use whatever you want. Think of Alt+m as standing for MultiMode.
Once you are in multiMode
you can move the cursor anywhere you want and continue to jump from that new position.
Expanding the Selection
If you already have a selection or create one with one of the 'Select' commands (jumpForwardSelect
, jumpForwardSelectMultiMode
, jumpBackwardSelect
, or jumpBackwardSelectMultiMode
) and do another 'select' command that pre-existing selection will be expanded.
The selection can be expanded forward with either the jumpForwardSelect
or jumpForwardSelectMultiMode
command.
The selection can be expanded backward with either the jumpBackwardSelect
or jumpBackwardSelectMultiMode
command.
This can be done either by triggering the default commands or by triggering a keybinding.
The below demo shows creating a backwards selection to the (
and then a forwards expansion of that selection to the )
.
Here is a single keybinding combining the two operations from above.
{
"key": "alt+t",
"command": "runCommands",
"args": {
"commands": [
{
"command": "jump-and-select.jumpBackwardSelect",
"args": {
"text": "(",
"putCursorBackwardSelect": "afterCharacter"
}
},
{
"command": "jump-and-select.jumpForwardSelect",
"args": {
"text": ")",
"putCursorForwardSelect": "beforeCharacter"
}
}
]
},
// "when": "editorTextFocus && !editorReadonly && editorLangId == rust"
// "when": "editorTextFocus && !editorReadonly && resourceExtname =~ /\\.(js|ts)/"
}
Another example, using a combination of jump-and-select.jumpBackwardSelectMultiMode
and then this keybinding:
{
"key": "alt+p",
"command": "jump-and-select.jumpForwardSelect",
"args": {
"text": "^$" // select to next empty line
},
}
Using regular expressions in a keybinding
With a "text": ""
argument in a keybinding, you can only use these regular expression patterns: ^
, $
, or ^$
. Those will always be evaluated as regular expressions, never as literals. For example,
{
"key": "alt+p",
"command": "jump-and-select.jumpForward",
"args": {
"text": "^", // go to start of line
// "text": "$", // go to end of line
// "text": "^$", // go to next/previous empty line
// "restrictSearch": "line" // or document
},
}
- Note, you can also use
^
and$
as key inputs to any of the commands outside of a keybinding - they will also be interpreted as regular expression characters.
If you want to jump to a literal ^
or $
, you will need to put them into a keybinding and double-escape them like so:
{
"key": "alt+p",
"command": "jump-and-select.jumpForward",
"args": {
"text": "howdy\\$", // "123\\^" or "\\^\\$" also work,
}
}
You can have any number of double-escaped \\^
and \\$
mixed with other text and it will all be treated as literal (non-regular expression) characters.
A. With one of the jumpForward...
commands:
"restrictSearch": "document"
or no restrictSearch
argument (document
is the default):
- "^" : the cursor would go to the start of the next line - that is forwards. If the cursor is already at the start of a line: it will go to the start of the next line.
- "$" : the cursor would go to the end of the current line. If the cursor is already at the end of a line: it will go to the end of the next line.
- "^$" : the cursor would go to the next empty line.
"restrictSearch": "line"
:
- "^" : nothing would happen. Can't go forward to the start of the same line.
- "$" : the cursor will go to the end of the current line.
- "^$" : nothing would happen. Never leave the current line.
2. With one of the jumpBackward...
commands:
"restrictSearch": "document"
or no restrictSearch
argument (document
is the default):
- "^" : the cursor would go to the start of the current line - that is backwards. If the cursor is already at the start of a line: it will go to the start of the previous line.
- "$" : the cursor would go to the end of the current line. If the cursor is already at the end of a line: it will go to the end of the previous line.
- "^$" : the cursor would go to the previous empty line.
"restrictSearch": "line"
:
- "^" : the cursor will go to the start of the current line - that is backwards.
- "$" : nothing would happen. Can't go backward to the end of the same line.
- "^$" : nothing would happen. Never leave the current line.
- Note:
^
or$
or^$
also work to expand existing selections. It is easiest to set up a simple keybinding like
{
"key": "alt+p",
"command": "jump-and-select.jumpForwardSelect", // and try the other commands
"args": {
"text": "^",
// "text": "$",
// "text": "^$",
"restrictSearch": "document" // the default so not necessary
// "restrictSearch": "line"
},
// "when": ""
}
to see how they work in action.
StatusBar colors
Color options for the StatusBarItem are very limited. Right now these are the settings you can modify:
"workbench.colorCustomizations": {
// errorBackground and warningBackground are the only background colors supported by vscode for statusBarItems
// this extension uses the errorBackground (warning was not originally supported)
"statusBarItem.errorBackground": "#fff", // default is red
"statusBarItem.errorForeground": "#000", // default is white
"statusBarItem.errorHoverBackground": "#000", // affects the error statusBarItems only
"statusBarItem.errorHoverForeground": "#ff0000", // affects the error statusBarItems only
// or
"statusBarItem.hoverBackground": "#000", // affects all statusBarItems
"statusBarItem.hoverForeground": "#fff", // affects all statusBarItems
}
The errorBackground
default is #f00
or red. Changing it will change the errorBackground color for all extensions or vscode itself that provide a StatusBarItem that needs an errorBackground. In this demo I left the settings at their default values.
If you see this error message you may have forgotten to exit (via the Enter) the MultiMode and tried to initiate some other jump-and-select
command:
"restrictSearch": "line"
option and selections
If you have "restrictSearch": "line"
and have an existing selection in the code and then trigger one of the commands, what exactly is considered to be the 'line'?
The one 'line' will be where the cursor is - this is known as the active
end of the selection. So if you make a multiline selection first, the one 'line' will be where the end of the selection is that has the active cursor.
Also, when this selection searches forward on a line, it will do so FROM the cursor. Likewise, if it is searching backward on a 'line' with a selection, it will search backwards from the position of the active cursor.
A note on the precedence of the options.
We have seen that there are three possibilities for the options (like "restrictSearch"
for example):
- options in a keybinding;
- options in settings;
- and options in the deprecated settings;
- no options in (1), (2) or (3).
The options take precedence in that order: 1 > 2 > 3 > 4. All the options have defaults, so even in case (4) the default values will be applied.
1. If after triggering one of the commands you decide you don't want to move the cursor after all, Enter will exit the command and you can resume typing.
2. If after triggering one of the commands you decide you want to move the cursor first, left/rightArrow keys or clicking in the file elsewhere will move the cursor without exiting the command. You can then type a chosen character to move/select from the new cursor position.
3. If the next or previous jump would be out of the editor's viewport, it will be revealed. For multiple selections, the first selection made (which could appear after other selections) will be revealed.
Known Issues
This extension may not play well with vim or neovim or similar due to registering the same 'type'
command as those extensions do. However, this extension disposes of that binding immediately after typing one character so it may not be an issue...
For some unknown reason, tabs (\t
) are not considered a typed character and don't work. Spaces do work though.
TODO
[ ] - Explore allowing input via 'paste' as well.
[ ] - Consider adding a setting to make queries be interpreted as regex's in keybindings.
[ ] - Consider cancelling multiMode if change editor.
[ ] - Should there be a notification for no match on a query?
Release Notes
0.0.1 Initial release of
jump-and-select
extension.0.0.2 Change behavior of go to previous character, put cursor before the character.
0.0.41 Added setting to restrict movement/selection to current line or full document.
Added setting to move/select before or after the chosen character.
Separated settings to put cursor before/after the chosen character for both forward/backward.
Added support for keybindings and all args therein.
Added support for regular expressions in keybindings and macros.
Renamed torestrictSearch
setting andargs
option.
Added intellisense/completions for keybindings, includingargs
options.0.5.0 Removed regex interpretation of keybinding queries.
Selections are continuous - extending each current selection, even with^/$/^$
.
Make all jumps reveal - at bottom.
Fix putCursorForward/Backward if next to a match.
Make the StatusBarItem show immediately.
AddAbort MultiMode
command. In Command Palette and clicking the StatusBarItem.
Prevent multiple StatusBarItems.
Swapped JSON Schemakeybindings.schema.jsonc
instead of CompletionProvider.
Better^
,$
, and^$
selecting in keybindings.
Enable literal\\^
and\\$
in keybindings.
Simplified the QueryObject and made a default noMatch.
Use EOL length for forward ^/$ for multi-OS lengths.
Made a Discussions item for new features.
0.5.2 Fix backwards bug not using start of first line.
0.5.3 empty line (^$) jumps work in files that DON'T normalize \n to \r\n - specific settings-type files.
0.5.4 empty line (^$) "fix" - just check for existence of \r\n in tthe file to set which regex to use.0.6.0 Deprecated all previous settings in favor of one
defaults
.
Added a jump and a select version of each option.
For "^$" just use /(?<=\r?\n)\r?\n/g)/ regex.
Use more "editor.document.eol" for match and query lengths.
Added configs.js withdefaults.restrictSearch ?? depRestrictSearch ?? "document"
, for example.