This document describes the vi key binding support implemented in BBEdit, starting with version 16.0.
It is a reference for the current implementation, not a promise of complete vi/vim
compatibility.
| Area |
Current behavior |
| Feature switch |
Vi handling is active only when the global key binding emulation is set to vi in BBEdit’s Keyboard preferences. |
| Initial enabled state |
The first vi-handled key changes Disabled to Normal. |
| Host shortcuts |
Cmd modified keystrokes bypass vi handling. |
| Host key bindings |
Default key binding selectors and normal menu commands are separate from the vi parser; this table focuses on vi-parsed input. |
| Control keys |
In command modes, control keys bypass vi handling except Esc/Ctrl-[, Ctrl-R, and Ctrl-V. |
| Counts |
Digits build a command count. 0 is a motion when there is no pending count/operator; otherwise it extends the count. |
| Unknown command |
Beeps and resets pending vi input/state. |
| Repeat model |
. replays the stored repeatable vi input sequence. This is simpler than full Vim repeat semantics. |
| Mode |
Entered by |
Leaves by |
Caret kind |
| Normal |
Esc from insert/visual/replace, or vi initialization |
i, a, I, A, o, O, R, v, V, Ctrl-V, :, /, ? |
Block |
| Insert |
i, a, I, A, o, O, c/visual change, C, cc |
Esc or Ctrl-[ |
Insertion point |
| Replace |
R |
Esc or Ctrl-[ |
Underline |
| Visual |
v |
v, Esc, visual operation, mode switch |
Block |
| Visual Line |
V |
V, Esc, visual operation, mode switch |
Block |
| Visual Block |
Ctrl-V |
Ctrl-V, Esc, visual operation, mode switch |
Block |
| Command-line |
:, /, ? |
Return/Enter to execute, Esc to cancel |
Existing mode caret |
Most motions accept a count. In Visual modes, the same motion subset extends or
adjusts the active visual selection.
| Key |
Action |
h, Left Arrow |
Move left one character. |
j, Down Arrow |
Move down one line. |
k, Up Arrow |
Move up one line. |
l, Right Arrow |
Move right one character. |
w |
Move forward by word using the host Option-Right behavior. |
b |
Move backward by word using the host Option-Left behavior. |
e |
Move to the end of the current/next word. |
0 |
Move to hard line start. |
^ |
Move to first non-blank character on the hard line. |
$ |
Move to hard line end. |
gg |
Move to the first line, or to [count] line. |
G |
Move to the last line when no count is supplied, or to [count] line. |
( |
Move to previous sentence start using BBEdit’s vi sentence heuristic. |
) |
Move to next sentence start using BBEdit’s vi sentence heuristic. |
% |
Jump to a matching delimiter for (), [], {}, curly quotes, and single curly quotes. |
| Key or command |
Action |
f<char> |
Find <char> forward on the current hard line. |
F<char> |
Find <char> backward on the current hard line. |
t<char> |
Find forward until just before <char> on the current hard line. |
T<char> |
Find backward until just after <char> on the current hard line. |
; |
Repeat the last f/F/t/T in the same direction. |
, |
Repeat the last f/F/t/T in the opposite direction. |
/pattern<Return> |
Run a forward literal find through BBEdit’s find system. |
?pattern<Return> |
Run a backward literal find through BBEdit’s find system. |
n |
Find again. |
N |
Find again backwards. |
| Key |
Action |
i |
Enter Insert mode at the current caret. |
a |
Move right one character, then enter Insert mode. |
I |
Move to first non-blank on the hard line, then enter Insert mode. |
A |
Move to hard line end, then enter Insert mode. |
o |
Move to hard line end, insert a line break below, then enter Insert mode. |
O |
Move to hard line start, insert a line break above, then enter Insert mode. |
R |
Enter Replace mode. |
x |
Forward delete, repeated by count. |
X |
Backspace/delete backward, repeated by count. |
r<char> |
Replace up to count non-line-ending characters with <char>. |
p |
Paste, repeated by count. |
P |
Move left, then paste, repeated by count. |
J |
Join lines when count is greater than one. Plain J is currently accepted but does not join. |
u |
Undo through BBEdit’s undo command. |
Ctrl-R |
Redo through BBEdit’s redo command. |
. |
Replay the last stored repeatable vi input sequence. |
| Operator |
With motion |
Repeated key form |
Visual selection form |
d |
Cut text covered by the motion. Examples: dw, d$, dG, dg. |
dd cuts current line, repeated by count. |
d cuts selection and returns to Normal. |
c |
Cut text covered by the motion, then enter Insert. Examples: cw, c$, cG, cg. |
cc cuts current line, then enters Insert. |
c cuts selection, then enters Insert. |
y |
Copy text covered by the motion. Examples: yw, y$, yG, yg. |
yy copies current line, repeated by count. |
y copies selection and returns to Normal. |
> |
Shift right/indent text covered by the motion. |
>> shifts current line/right selection, repeated by count. |
> shifts selection right. |
< |
Shift left/outdent text covered by the motion. |
<< shifts current line/left selection, repeated by count. |
< shifts selection left. |
| Key |
Visual |
Visual Line |
Visual Block |
Esc, Ctrl-[ |
Return to Normal and collapse selection. |
Same. |
Same. |
v |
Toggle back to Normal. |
Switch to characterwise Visual. |
Switch to characterwise Visual. |
V |
Switch to Visual Line. |
Toggle back to Normal. |
Switch to Visual Line. |
Ctrl-V |
Switch to Visual Block. |
Switch to Visual Block. |
Toggle back to Normal. |
| Motions |
Characterwise selection. |
Whole hard-line selection. |
Rectangular selection range. |
d |
Cut selection, return to Normal. |
Same. |
Same, using rectangular selection ranges. |
c |
Cut selection, enter Insert. |
Same. |
Same, using rectangular selection ranges. |
y |
Copy selection, return to Normal. |
Same. |
Same, using rectangular selection ranges. |
> |
Shift selection right. |
Same. |
Same command on active selection. |
< |
Shift selection left. |
Same. |
Same command on active selection. |
p, P |
Paste over selection, return to Normal. |
Same. |
Same command on active selection. |
| Form |
Current behavior |
[count]motion |
Repeats the motion or uses the count as a line number for G/gg. |
[count]edit |
Repeats simple edits such as x, X, p, P, and .. |
[count]operator motion |
The pending operator uses the stored count when no separate motion count is present. |
operator [motion-count] motion |
Digits after an operator and are used by the motion/operator. |
| Missing count |
Most commands normalize missing count to 1; G motions preserve missing count as “last line”. |
Operator g |
In operator-pending mode, a single g is the first-line motion. Normal mode still requires gg. |