Smart Tab Navigation
VMark's Tab and Shift+Tab keys are context-aware — they help you navigate efficiently through formatted text, brackets, and links without reaching for arrow keys.
With the experimental workspace rail, tab cycling and the tab strip cover only the active workspace's tabs.
Quick Overview
| Context | Tab Action | Shift+Tab Action |
|---|---|---|
Inside brackets () [] {} | Jump past closing bracket | Jump before opening bracket |
Inside quotes "" '' | Jump past closing quote | Jump before opening quote |
Inside CJK brackets 「」 『』 | Jump past closing bracket | Jump before opening bracket |
Inside bold, italic, code, | Jump after the formatting | Jump before the formatting |
| Inside a link | Jump after the link | Jump before the link |
| In a table cell | Move to next cell | Move to previous cell |
| In a list item | Indent the item | Outdent the item (stops at the outermost level) |
Bracket & Quote Escape
When your cursor is right before a closing bracket or quote, pressing Tab jumps over it. When your cursor is right after an opening bracket or quote, pressing Shift+Tab jumps back before it.
Supported Characters
Standard brackets and quotes:
- Parentheses:
( ) - Square brackets:
[ ] - Curly braces:
{ } - Double quotes:
" " - Single quotes:
' ' - Backticks:
`
CJK brackets:
- Fullwidth parentheses:
( ) - Lenticular brackets:
【 】 - Corner brackets:
「 」 - White corner brackets:
『 』 - Double angle brackets:
《 》 - Angle brackets:
〈 〉
Curly quotes:
- Double curly quotes:
" " - Single curly quotes:
' '
How It Works
function hello(world|)
↑ cursor before )Press Tab:
function hello(world)|
↑ cursor after )This works with nested brackets too — Tab jumps over the immediately adjacent closing character.
Press Shift+Tab reverses the action — if cursor is right after an opening character:
function hello(|world)
↑ cursor after (Press Shift+Tab:
function hello|(world)
↑ cursor before (CJK Example
这是「测试|」文字
↑ cursor before 」Press Tab:
这是「测试」|文字
↑ cursor after 」Formatting Escape (WYSIWYG Mode)
In WYSIWYG mode, Tab and Shift+Tab can escape from inline formatting marks.
Supported Formats
- Bold text
- Italic text
Inline codeStrikethrough- Links
How It Works
When your cursor is anywhere inside formatted text:
This is **bold te|xt** here
↑ cursor inside boldPress Tab:
This is **bold text**| here
↑ cursor after boldShift+Tab works in reverse — it jumps to the start of the formatting:
This is **bold te|xt** here
↑ cursor inside boldPress Shift+Tab:
This is |**bold text** here
↑ cursor before boldLink Escape
Tab and Shift+Tab also escape from links:
Check out [VMark|](https://vmark.app)
↑ cursor inside link textPress Tab:
Check out [VMark](https://vmark.app)| and...
↑ cursor after linkPress Shift+Tab inside a link moves to the start:
Check out |[VMark](https://vmark.app) and...
↑ cursor before linkLink Navigation (Source Mode)
In Source mode, Tab provides smart navigation within Markdown link syntax.
Nested and Escaped Brackets
VMark handles complex link syntax correctly:
[text [with nested] brackets](url) ✓ Works
[text \[escaped\] brackets](url) ✓ Works
[link](https://example.com/page(1)) ✓ WorksTab navigation correctly identifies link boundaries even with nested or escaped brackets.
Standard Links
[link text|](url)
↑ cursor in textPress Tab → cursor moves to URL:
[link text](|url)
↑ cursor in URLPress Tab again → cursor exits the link:
[link text](url)|
↑ cursor after linkWiki Links
[[page name|]]
↑ cursor in linkPress Tab:
[[page name]]|
↑ cursor after linkSource Mode: Markdown Character Escape
In Source mode, Tab also jumps over Markdown formatting characters:
| Characters | Used For |
|---|---|
* | Bold/italic |
_ | Bold/italic |
^ | Superscript |
~~ | Strikethrough (jumped as a unit) |
== | Highlight (jumped as a unit) |
Example
This is **bold|** text
↑ cursor before **Press Tab:
This is **bold**| text
↑ cursor after **INFO
Source mode does not have Shift+Tab escape for markdown characters — Shift+Tab only outdents (removes leading spaces).
Source Mode: Auto-Pair
In Source mode, typing a formatting character auto-inserts its closing pair:
| Character | Pairing | Behavior |
|---|---|---|
* | *|* or **|** | Delay-based — waits 150ms to detect single vs double |
~ | ~|~ or ~~|~~ | Delay-based |
_ | _|_ or __|__ | Delay-based |
= | ==|== | Always pairs as double |
` | `|` | Single backtick pairs after delay |
``` | Code fence | Triple backtick at line start creates a fenced code block |
Auto-pairing is disabled inside fenced code blocks — typing * in a code block inserts a literal * without pairing.
Backspace between a pair deletes both halves: *\|* → Backspace → empty.
Table Navigation
When cursor is inside a table:
| Action | Key |
|---|---|
| Next cell | Tab |
| Previous cell | Shift + Tab |
| Add row (at last cell) | Tab |
Tab at the last cell of the last row automatically adds a new row.
List Indentation
When cursor is in a list item:
| Action | Key |
|---|---|
| Indent item | Tab |
| Outdent item | Shift + Tab |
Outdent removes one level of nesting and stops at the outermost level — it will not lift an item out of the list. To leave a list entirely, use Remove List, or press the list button again to toggle it off.
Settings
Tab escape behavior can be customized in Settings → Editor:
| Setting | Effect |
|---|---|
| Auto-pair Brackets | Enable/disable bracket pairing and Tab escape |
| CJK Brackets | Include CJK bracket pairs |
| Curly Quotes | Include curly quote pairs ("" '') |
TIP
If Tab escape conflicts with your workflow, you can disable auto-pair brackets entirely. Tab will then insert spaces (or indent in lists/tables) as normal.
Comparison: WYSIWYG vs Source Mode
| Feature | Tab (WYSIWYG) | Shift+Tab (WYSIWYG) | Tab (Source) | Shift+Tab (Source) |
|---|---|---|---|---|
| Bracket escape | ✓ | ✓ | ✓ | — |
| CJK bracket escape | ✓ | ✓ | ✓ | — |
| Curly quote escape | ✓ | ✓ | ✓ | — |
| Mark escape (bold, etc.) | ✓ | ✓ | N/A | N/A |
| Link escape | ✓ | ✓ | ✓ (field navigation) | — |
Markdown char escape (*, _, ~~, ==) | N/A | N/A | ✓ | — |
Markdown auto-pair (*, ~, _, =) | N/A | N/A | ✓ (delay-based) | N/A |
| Table navigation | Next cell | Previous cell | N/A | N/A |
| List indentation | Indent | Outdent | Indent | Outdent |
| Multi-cursor support | ✓ | ✓ | ✓ | — |
| Skipped inside code blocks | ✓ | ✓ | ✓ | N/A |
Multi-Cursor Support
Tab escape works with multiple cursors — each cursor is processed independently.
How It Works
When you have multiple cursors and press Tab or Shift+Tab:
- Tab: Cursors inside formatting escape to the end; cursors before closing brackets jump over them
- Shift+Tab: Cursors inside formatting escape to the start; cursors after opening brackets jump before them
- Cursors in plain text stay in place
Example
**bold|** and [link|](url) and plain|
^1 ^2 ^3Press Tab:
**bold**| and [link](url)| and plain|
^1 ^2 ^3Each cursor escapes independently based on its context.
TIP
This is particularly powerful for bulk editing — select multiple occurrences with Mod + D, then use Tab to escape from all of them at once.
Priority & Code Block Behavior
Escape Priority
When multiple escape targets overlap, Tab processes them innermost-first:
**bold text(|)** here
↑ Tab jumps ) first (bracket is innermost)Press Tab again:
**bold text()**| here
↑ Tab escapes bold markThis means bracket jump always fires before mark escape — you can rely on Tab to exit brackets first, then formatting.
Code Block Guard
Tab and Shift+Tab bracket jumps are disabled inside code blocks — both code_block nodes and inline code spans. This prevents Tab from jumping over brackets in code, where brackets are literal syntax:
`array[index|]`
↑ Tab does NOT jump ] in inline code — inserts spaces insteadAuto-pair insertion is also disabled inside code blocks for both WYSIWYG and Source modes.
Tips
Muscle memory — Once you get used to Tab escape, you'll find yourself navigating much faster without arrow keys.
Works with auto-pair — When you type
(, VMark auto-inserts). After typing inside, just Tab to jump out.Nested structures — Tab escapes one level at a time. For
((nested)), you need two Tabs to fully exit.Shift + Tab — The mirror of Tab. Escapes backward from marks, links, and opening brackets. In tables, moves to the previous cell. In lists, outdents the item.
Multi-cursor — Tab escape works with all your cursors simultaneously, making bulk edits even faster.