Glide Browser features a powerful modal editing system inspired by Vim, allowing you to navigate and interact with web pages using keyboard-driven workflows. The browser operates in different modes, each optimized for specific tasks.
Available Modes
Glide supports six distinct modes:
Normal Mode The default mode for navigation and issuing commands. Most keybindings are available in this mode.
Insert Mode For interacting with form inputs and editable elements. Similar to how a traditional browser works.
Visual Mode For selecting and manipulating text within editable elements.
Operator-Pending Mode A temporary mode activated when waiting for a motion after an operator (like d for delete).
Command Mode For executing ex commands through the command line interface.
Ignore Mode Passes all key inputs directly to the web page, bypassing Glide’s keybindings.
Switching Between Modes
You can switch modes using the mode_change ex command or the built-in keybindings:
From Normal Mode
// Enter insert mode
glide . keymaps . set ( "normal" , "i" , "mode_change insert --automove=left" );
glide . keymaps . set ( "normal" , "a" , "mode_change insert" );
glide . keymaps . set ( "normal" , "A" , "mode_change insert --automove=endline" );
// Enter visual mode
glide . keymaps . set ( "normal" , "v" , "motion v" );
// Enter ignore mode
glide . keymaps . set ([ "normal" , "insert" , "visual" ], "<S-Esc>" , "mode_change ignore" );
Returning to Normal Mode
// From insert, visual, or operator-pending mode
glide . keymaps . set ([ "insert" , "visual" , "op-pending" ], "<Esc>" , "mode_change normal" );
glide . keymaps . set ([ "insert" , "visual" , "op-pending" ], "<C-[>" , "mode_change normal" );
// From ignore mode
glide . keymaps . set ( "ignore" , "<S-Esc>" , "mode_change normal" );
Mode-Specific Behavior
Normal Mode
Normal mode is optimized for navigation and issuing commands:
Navigation motions : h, j, k, l for character-level movement
Word motions : w, W, e, b, B for word-based navigation
Line motions : 0, ^, $ for line navigation
Scrolling : gg, G, <C-d>, <C-u> for page scrolling
Operators : d, c, r for editing operations
Insert Mode
Insert mode allows direct interaction with input fields and editable content:
Most keybindings are disabled to allow normal text entry
Tab navigation and history controls remain active
Exit with <Esc> or <C-[>
Visual Mode
Visual mode enables text selection and manipulation:
// Visual mode motions
glide . keymaps . set ( "visual" , "h" , "motion vh" );
glide . keymaps . set ( "visual" , "l" , "motion vl" );
glide . keymaps . set ( "visual" , "d" , "motion vd" );
glide . keymaps . set ( "visual" , "c" , "motion vc" );
glide . keymaps . set ( "visual" , "y" , "visual_selection_copy" );
Operator-Pending Mode
This mode is automatically entered when you press an operator key (like d or c):
// Define operators
glide . keymaps . set ( "normal" , "d" , "mode_change op-pending --operator=d" );
glide . keymaps . set ( "normal" , "c" , "mode_change op-pending --operator=c" );
// Execute motion after operator
glide . keymaps . set ( "op-pending" , "w" , "execute_motion" ); // delete word: dw
glide . keymaps . set ( "op-pending" , "$" , "execute_motion" ); // delete to end: d$
Mode Change Options
The mode_change command supports several options:
Auto-move Cursor
When entering insert mode, you can automatically move the cursor:
// Move cursor left before entering insert (like 'i' in Vim)
glide . excmds . execute ( "mode_change insert --automove=left" );
// Move cursor to end of line (like 'A' in Vim)
glide . excmds . execute ( "mode_change insert --automove=endline" );
Operator Mode
Specify which operator to use in operator-pending mode:
// Delete operator
glide . excmds . execute ( "mode_change op-pending --operator=d" );
// Change operator
glide . excmds . execute ( "mode_change op-pending --operator=c" );
// Replace operator
glide . excmds . execute ( "mode_change op-pending --operator=r" );
Monitoring Mode Changes
You can react to mode changes using autocmds:
// Listen for any mode change
glide . autocmds . create ( "ModeChanged" , "*" , ({ old_mode , new_mode }) => {
console . log ( `Mode changed from ${ old_mode } to ${ new_mode } ` );
});
// Listen for entering visual mode
glide . autocmds . create ( "ModeChanged" , "*:visual" , ({ new_mode }) => {
console . log ( "Entered visual mode" );
});
// Listen for leaving insert mode
glide . autocmds . create ( "ModeChanged" , "insert:*" , ({ old_mode , new_mode }) => {
console . log ( `Left insert mode, now in ${ new_mode } ` );
});
Current Mode
You can check the current mode in your config:
// Access current mode
const currentMode = glide . ctx . mode ;
// Use in conditional logic
if ( glide . ctx . mode === "normal" ) {
// Do something only in normal mode
}
Custom Mode-Specific Keybindings
Define keybindings that work across multiple modes:
// Tab navigation works in both normal and insert modes
glide . keymaps . set ([ "normal" , "insert" ], "<C-j>" , "tab_next" );
glide . keymaps . set ([ "normal" , "insert" ], "<C-k>" , "tab_prev" );
// History navigation
if ( glide . ctx . os === "macosx" ) {
glide . keymaps . set ([ "normal" , "insert" ], "<C-h>" , "back" );
glide . keymaps . set ([ "normal" , "insert" ], "<C-l>" , "forward" );
} else {
glide . keymaps . set ([ "normal" , "insert" ], "<A-h>" , "back" );
glide . keymaps . set ([ "normal" , "insert" ], "<A-l>" , "forward" );
}
:mode_change <mode> - Switch to the specified mode
:blur - Blur the active element and return to normal mode
:focusinput last - Focus the last input element on the page
The mode system is defined in browser-excmds-registry.mts:47-56 with available modes: normal, insert, visual, op-pending, ignore, command, and hint.