Vim style editor written in Racket
As the backend of https://github.com/BowenFu/drracket-vim-tool.
These are the big Vim features, put generally in the order in which we plan to implement them.
Status |
Command |
[x] |
Normal Mode |
[x] |
Insert Mode |
[x] |
Visual Mode |
[x] |
Visual Line Mode |
[x] |
Number Prefixes |
[x] |
. Operator |
[x] |
Searching with / and ? |
[x] |
Undo/Redo |
[x] |
Marks |
[x] |
Text Objects |
[x] |
Visual Block Mode |
[x] |
Replace Mode |
[x] |
Macros |
[ ] |
Buffer/Window/Tab |
[ ] |
Command Remapping |
Now follows an exhaustive list of every known Vim command that we could find.
Status |
Command |
Description |
[x] |
🔢 h |
left (also: CTRL-H, BS, or Left key) |
[x] |
🔢 l |
right (also: Space or Right key) |
[x] |
0 |
to first character in the line (also: Home key) |
[x] |
^ |
to first non-blank character in the line |
[x] |
🔢 $ |
to the last character in the line (N-1 lines lower) (also: End key) |
[x] |
🔢 | |
to column N (default: 1) |
[x] |
🔢 f{char} |
to the Nth occurrence of {char} to the right |
[x] |
🔢 F{char} |
to the Nth occurrence of {char} to the left |
[x] |
🔢 t{char} |
till before the Nth occurrence of {char} to the right |
[x] |
🔢 T{char} |
till before the Nth occurrence of {char} to the left |
[x] |
🔢 ; |
repeat the last "f", "F", "t", or "T" N times |
[x] |
🔢 , |
repeat the last "f", "F", "t", or "T" N times in opposite direction |
[ ] |
g0 |
to first character in screen line (differs from "0" when lines wrap) |
[ ] |
g^ |
to first non-blank character in screen line (differs from "^" when lines wrap) |
[ ] |
🔢 g$ |
to last character in screen line (differs from "$" when lines wrap) |
[ ] |
gm |
to middle of the screen line |
Status |
Command |
Description |
[x] |
🔢 k |
up N lines (also: CTRL-P and Up) |
[x] |
🔢 j |
down N lines (also: CTRL-J, CTRL-N, NL, and Down) |
[x] |
🔢 G |
goto line N (default: last line), on the first non-blank character |
[x] |
🔢 gg |
goto line N (default: first line), on the first non-blank character |
[x] |
🔢 % |
goto line N percentage down in the file; N must be given, otherwise it is the % command |
[ ] |
🔢 gk |
up N screen lines (differs from "k" when line wraps) |
[ ] |
🔢 gj |
down N screen lines (differs from "j" when line wraps) |
[ ] |
🔢 - |
up N lines, on the first non-blank character |
[ ] |
🔢 + |
down N lines, on the first non-blank character (also: CTRL-M and CR) |
[ ] |
🔢 _ |
down N-1 lines, on the first non-blank character |
Status |
Command |
Description |
[x] |
🔢 w |
N words forward |
[x] |
🔢 W |
N blank-separated WORDs forward |
[x] |
🔢 e |
N words forward to the end of the Nth word |
[x] |
🔢 E |
N words forward to the end of the Nth blank-separated WORD |
[x] |
🔢 b |
N words backward |
[x] |
🔢 B |
N blank-separated WORDs backward |
[ ] |
🔢 ge |
N words backward to the end of the Nth word |
[ ] |
🔢 gE |
N words backward to the end of the Nth blank-separated WORD |
[ ] |
🔢 ) |
N sentences forward |
[ ] |
🔢 ( |
N sentences backward |
[ ] |
🔢 } |
N paragraphs forward |
[ ] |
🔢 { |
N paragraphs backward |
[ ] |
🔢 ]] |
N sections forward, at start of section |
[ ] |
🔢 [[ |
N sections backward, at start of section |
[ ] |
🔢 ][ |
N sections forward, at end of section |
[ ] |
🔢 [] |
N sections backward, at end of section |
[ ] |
🔢 [( |
N times back to unclosed '(' |
[ ] |
🔢 [{ |
N times back to unclosed '{' |
[ ] |
🔢 ]) |
N times forward to unclosed ')' |
[ ] |
🔢 ]} |
N times forward to unclosed '}' |
Status |
Command |
Description |
[x] |
🔢 /{pattern}[/[offset]]<CR> |
search forward for the Nth occurrence of {pattern} |
[x] |
🔢 ?{pattern}[?[offset]]<CR> |
search backward for the Nth occurrence of {pattern} |
[x] |
🔢 /<CR> |
repeat last search, in the forward direction |
[x] |
🔢 ?<CR> |
repeat last search, in the backward direction |
[x] |
🔢 n |
repeat last search |
[x] |
🔢 N |
repeat last search, in opposite direction |
[x] |
🔢 * |
search forward for the identifier under the cursor |
[x] |
🔢 # |
search backward for the identifier under the cursor |
[ ] |
🔢 g* |
like "*", but also find partial matches |
[ ] |
🔢 g# |
like "#", but also find partial matches |
[ ] |
gd |
goto local declaration of identifier under the cursor |
[ ] |
gD |
goto global declaration of identifier under the cursor |
Status |
Command |
Description |
[x] |
m{a-zA-Z} |
mark current position with mark {a-zA-Z} |
[x] |
`{a-z} |
go to mark {a-z} within current file |
[x] |
`{A-Z} |
go to mark {A-Z} in any file |
[ ] |
`{0-9} |
go to the position where Vim was previously exited |
[ ] |
`` |
go to the position before the last jump |
[ ] |
`" |
go to the position when last editing this file |
[ ] |
`[ |
go to the start of the previously operated or put text |
[ ] |
'[ |
go to the start of the previously operated or put text |
[ ] |
`] |
go to the end of the previously operated or put text |
[ ] |
'] |
go to the end of the previously operated or put text |
[x] |
`< |
go to the start of the (previous) Visual area |
[x] |
`> |
go to the end of the (previous) Visual area |
[ ] |
`. |
go to the position of the last change in this file |
[ ] |
'. |
go to the position of the last change in this file |
[x] |
'{a-zA-Z0-9[]'"<>.} |
same as `, but on the first non-blank in the line |
[ ] |
:marks |
print the active marks |
[ ] |
🔢 CTRL-O |
go to Nth older position in jump list |
[ ] |
🔢 CTRL-I |
go to Nth newer position in jump list |
[ ] |
:ju[mps] |
print the jump list |
Status |
Command |
Description |
[x] |
% |
find the next brace, bracket and go to its match |
[ ] |
🔢 H |
go to the Nth line in the window, on the first non-blank |
[ ] |
M |
go to the middle line in the window, on the first non-blank |
[ ] |
🔢 L |
go to the Nth line from the bottom, on the first non-blank |
[ ] |
🔢 go |
go to Nth byte in the buffer |
[ ] |
:[range]go[to][off] |
go to [off] byte in the buffer |
Status |
Command |
Description |
[ ] |
🔢 CTRL-E |
window N lines downwards (default: 1) |
[ ] |
🔢 CTRL-D |
window N lines Downwards (default: 1/2 window) |
[ ] |
🔢 CTRL-F |
window N pages Forwards (downwards) |
[ ] |
🔢 CTRL-Y |
window N lines upwards (default: 1) |
[ ] |
🔢 CTRL-U |
window N lines Upwards (default: 1/2 window) |
[ ] |
🔢 CTRL-B |
window N pages Backwards (upwards) |
[ ] |
z CR or zt |
redraw, current line at top of window |
[ ] |
z. or zz |
redraw, current line at center of window |
[ ] |
z- or zb |
redraw, current line at bottom of window |
Status |
Command |
Description |
[x] |
🔢 a |
append text after the cursor (N times) |
[x] |
🔢 A |
append text at the end of the line (N times) |
[x] |
🔢 i |
insert text before the cursor (N times) (also: Insert) |
[x] |
🔢 I |
insert text before the first non-blank in the line (N times) |
[ ] |
🔢 gI |
insert text in column 1 (N times) |
[ ] |
gi |
insert at the end of the last change |
[x] |
🔢 o |
open a new line below the current line, append text (N times) |
[x] |
🔢 O |
open a new line above the current line, append text (N times) |
in Visual block mode:
Status |
Command |
Description |
[x] |
I |
insert the same text in front of all the selected lines |
[x] |
A |
append the same text after all the selected lines |
leaving Insert mode:
Status |
Command |
Description |
[x] |
Esc |
end Insert mode, back to Normal mode |
[ ] |
CTRL-C |
like Esc, but do not use an abbreviation |
[ ] |
CTRL-O {command} |
execute {command} and return to Insert mode |
moving around:
Status |
Command |
Description |
[x] |
cursor keys |
move cursor left/right/up/down |
[ ] |
shift-left/right |
one word left/right |
[ ] |
shift-up/down |
one screenful backward/forward |
[ ] |
End |
cursor after last character in the line |
[ ] |
Home |
cursor to first character in the line |
Special keys in Insert mode
Status |
Command |
Description |
[*] |
NL or CR or CTRL-M or CTRL-J |
begin new line |
[x] |
BS or CTRL-H |
delete the character before the cursor |
[ ] |
CTRL-V {char}.. |
insert character literally, or enter decimal byte value |
[ ] |
CTRL-E |
insert the character from below the cursor |
[ ] |
CTRL-Y |
insert the character from above the cursor |
[ ] |
CTRL-A |
insert previously inserted text |
[ ] |
CTRL-@ |
insert previously inserted text and stop Insert mode |
[ ] |
CTRL-R {0-9a-z%#:.-="} |
insert the contents of a register |
[ ] |
CTRL-N |
insert next match of identifier before the cursor |
[ ] |
CTRL-P |
insert previous match of identifier before the cursor |
[ ] |
CTRL-X ... |
complete the word before the cursor in various ways |
[ ] |
Del |
delete the character under the cursor |
[ ] |
CTRL-W |
delete word before the cursor |
[ ] |
CTRL-U |
delete all entered characters in the current line |
[ ] |
CTRL-T |
insert one shiftwidth of indent in front of the current line |
[ ] |
CTRL-D |
delete one shiftwidth of indent in front of the current line |
[ ] |
0 CTRL-D |
delete all indent in the current line |
[ ] |
^ CTRL-D |
delete all indent in the current line, restore indent in next line |
Status |
Command |
Description |
[ ] |
:r [file] |
insert the contents of [file] below the cursor |
[ ] |
:r! {command} |
insert the standard output of {command} below the cursor |
Status |
Command |
Description |
[x] |
🔢 x |
delete N characters under and after the cursor |
[x] |
🔢 X |
delete N characters before the cursor |
[x] |
🔢 d{motion} |
delete the text that is moved over with {motion} |
[x] |
{visual}d |
delete the highlighted text |
[x] |
🔢 dd |
delete N lines |
[ ] |
🔢 D |
delete to the end of the line (and N-1 more lines) |
[ ] |
🔢 Del |
delete N characters under and after the cursor |
[ ] |
🔢 J |
join N-1 lines (delete EOLs) |
[ ] |
{visual}J |
join the highlighted lines |
[ ] |
🔢 gJ |
like "J", but without inserting spaces |
[ ] |
{visual}gJ |
like "{visual}J", but without inserting spaces |
[ ] |
:[range]d [x] |
delete [range] lines [into register x] |
Status |
Command |
Description |
[ ] |
"{char} |
use register {char} for the next delete, yank, or put |
[ ] |
"* |
use register * to access system clipboard |
[ ] |
:reg |
show the contents of all registers |
[ ] |
:reg {arg} |
show the contents of registers mentioned in {arg} |
[x] |
🔢 y{motion} |
yank the text moved over with {motion} into a register |
[x] |
{visual}y |
yank the highlighted text into a register |
[x] |
🔢 yy |
yank N lines into a register |
[ ] |
🔢 Y |
yank N lines into a register |
[x] |
🔢 p |
put a register after the cursor position (N times) |
[x] |
🔢 P |
put a register before the cursor position (N times) |
[ ] |
🔢 ]p |
like p, but adjust indent to current line |
[ ] |
🔢 [p |
like P, but adjust indent to current line |
[ ] |
🔢 gp |
like p, but leave cursor after the new text |
[ ] |
🔢 gP |
like P, but leave cursor after the new text |
Status |
Command |
Description |
[x] |
🔢 r{char} |
replace N characters with {char} |
[x] |
{visual}r{char} |
in Visual block, visual, or visual line modes: Replace each char of the selected text with {char} |
[x] |
🔢 R |
enter Replace mode (repeat the entered text N times) |
[ ] |
🔢 gr{char} |
replace N characters without affecting layout |
[ ] |
🔢 gR |
enter virtual Replace mode: Like Replace mode but without affecting layout |
(change = delete text and enter Insert mode)
Status |
Command |
Description |
[x] |
🔢 c{motion} |
change the text that is moved over with {motion} |
[x] |
{visual}c |
change the highlighted text |
[x] |
🔢 cc |
change N lines |
[x] |
🔢 S |
change N lines |
[x] |
🔢 C |
change to the end of the line (and N-1 more lines) |
[x] |
🔢 s |
change N characters |
[x] |
{visual}c |
in Visual block mode: Change each of the selected lines with the entered text |
[ ] |
{visual}C |
in Visual block mode: Change each of the selected lines until end-of-line with the entered text |
[x] |
{visual}~ |
switch case for highlighted text |
[x] |
{visual}u |
make highlighted text lowercase |
[x] |
{visual}U |
make highlighted text uppercase |
[x] |
g~{motion} |
switch case for the text that is moved over with {motion} |
[x] |
gu{motion} |
make the text that is moved over with {motion} lowercase |
[x] |
gU{motion} |
make the text that is moved over with {motion} uppercase |
[ ] |
{visual}g? |
perform rot13 encoding on highlighted text |
[ ] |
g?{motion} |
perform rot13 encoding on the text that is moved over with {motion} |
[x] |
🔢 <{motion} |
move the lines that are moved over with {motion} one shiftwidth left |
[x] |
🔢 << |
move N lines one shiftwidth left |
[x] |
🔢 >{motion} |
move the lines that are moved over with {motion} one shiftwidth right |
[x] |
🔢 >> |
move N lines one shiftwidth right |
[ ] |
🔢 CTRL-A |
add N to the number at or after the cursor |
[ ] |
🔢 CTRL-X |
subtract N from the number at or after the cursor |
[ ] |
🔢 gq{motion} |
format the lines that are moved over with {motion} to 'textwidth' length |
[ ] |
:[range]ce[nter][width] |
center the lines in [range] |
[ ] |
:[range]le[ft][indent] |
left-align the lines in [range] (with [indent]) |
[ ] |
:[ranee]ri[ght][width] |
right-align the lines in [range] |
Status |
Command |
Description |
[x] |
:[range]s[ubstitute]/{pattern}/{string}/[g][c] |
substitute {pattern} by {string} in [range] lines; with [g], replace all occurrences of {pattern}; with [c], confirm each replacement |
[ ] |
:[range]s[ubstitute][g][c] |
repeat previous ":s" with new range and options |
[ ] |
& |
Repeat previous ":s" on current line without options |
[ ] |
🔢 !{motion}{command}<CR> |
filter the lines that are moved over through {command} |
[ ] |
🔢 !!{command}<CR> |
filter N lines through {command} |
[ ] |
{visual}!{command}<CR> |
filter the highlighted lines through {command} |
[ ] |
:[range]! {command}<CR> |
filter [range] lines through {command} |
[ ] |
🔢 ={motion} |
filter the lines that are moved over through 'equalprg' |
[ ] |
🔢 == |
filter N lines through 'equalprg' |
[ ] |
{visual}= |
filter the highlighted lines through 'equalprg' |
[ ] |
:[range]ret[ab][!] [tabstop] |
set 'tabstop' to new value and adjust white space accordingly |
Status |
Command |
Description |
[x] |
v |
start highlighting characters or stop highlighting |
[x] |
V |
start highlighting linewise or stop highlighting |
[x] |
CTRL-V |
start highlighting blockwise or stop highlighting |
[x] |
o |
exchange cursor position with start of highlighting |
[ ] |
gv |
start highlighting on previous visual area |
Text objects (only in Visual mode or after an operator)
Status |
Command |
Description |
[x] |
🔢 aw |
Select "a word" |
[x] |
🔢 iw |
Select "inner word" |
[x] |
🔢 aW |
Select "a WORD" |
[x] |
🔢 iW |
Select "inner WORD" |
[ ] |
🔢 as |
Select "a sentence" |
[ ] |
🔢 is |
Select "inner sentence" |
[ ] |
🔢 ap |
Select "a paragraph" |
[ ] |
🔢 ip |
Select "inner paragraph" |
[x] |
🔢 a], a[ |
select '[' ']' blocks |
[x] |
🔢 i], i[ |
select inner '[' ']' blocks |
[x] |
🔢 ab, a(, a) |
Select "a block" (from "[(" to "])") |
[x] |
🔢 ib, i), i( |
Select "inner block" (from "[(" to "])") |
[x] |
🔢 a>, a< |
Select "a <> block" |
[x] |
🔢 i>, i< |
Select "inner <> block" |
[x] |
🔢 aB, a{, a} |
Select "a Block" (from "[{" to "]}") |
[x] |
🔢 iB, i{, i} |
Select "inner Block" (from "[{" to "]}") |
[ ] |
🔢 at |
Select "a tag block" (from <aaa> to </aaa>) |
[ ] |
🔢 it |
Select "inner tag block" (from <aaa> to </aaa>) |
[ ] |
🔢 a' |
Select "a single quoted string" |
[ ] |
🔢 i' |
Select "inner single quoted string" |
[ ] |
🔢 a" |
Select "a double quoted string" |
[ ] |
🔢 i" |
Select "inner double quoted string" |
[ ] |
🔢 a` |
Select "a backward quoted string" |
[ ] |
🔢 i` |
Select "inner backward quoted string" |
Status |
Command |
Description |
[x] |
🔢 . |
repeat last change (with count replaced with N) |
[x] |
q{a-z} |
record typed characters into register {a-z} |
[ ] |
q{A-Z} |
record typed characters, appended to register {a-z} |
[x] |
q |
stop recording |
[x] |
🔢 @{a-z} |
execute the contents of register {a-z} (N times) |
[x] |
🔢 @@ |
repeat previous @{a-z} (N times) |
[ ] |
:@{a-z} |
execute the contents of register {a-z} as an Ex command |
[ ] |
:@@ |
repeat previous :@{a-z} |
[ ] |
:[range]g[lobal]/{pattern}/[cmd] |
execute Ex command cmd on the lines within [range] where {pattern} matches |
[ ] |
:[range]g[lobal]!/{pattern}/[cmd] |
execute Ex command cmd on the lines within [range] where {pattern} does NOT match |
[ ] |
:so[urce] {file} |
read Ex commands from {file} |
[ ] |
:so[urce]! {file} |
read Vim commands from {file} |
[ ] |
:sl[eep][sec] |
don't do anything for [sec] seconds |
[ ] |
🔢 gs |
goto Sleep for N seconds |
Status |
Command |
Description |
Note |
[x] |
🔢 u |
undo last N changes |
Current implementation may not cover every case perfectly. |
[x] |
🔢 CTRL-R |
redo last N undone changes |
As above. |
[ ] |
U |
restore last changed line |
|
Status |
Command |
Description |
[x] |
, |
separates two line numbers |
[ ] |
; |
idem, set cursor to the first line number before interpreting the second one |
[x] |
{number} |
an absolute line number |
[x] |
. |
the current line |
[x] |
$ |
the last line in the file |
[x] |
% |
equal to 1,$ (the entire file) |
[ ] |
* |
equal to '<,'> (visual area) |
[*] |
't |
position of mark t |
[*] |
/{pattern}[/] |
the next line where {pattern} matches |
[*] |
?{pattern}[?] |
the previous line where {pattern} matches |
[ ] |
+[num] |
add [num] to the preceding line number (default: 1) |
[ ] |
-[num] |
subtract [num] from the preceding line number (default: 1) |
Status |
Command |
Description |
[ ] |
:e[dit] {file} |
Edit {file}. |
Status |
Command |
Description |
[ ] |
:e[dit] {file} |
Edit {file}. |
[ ] |
<ctrl-w> hl |
Switching between windows. |
[ ] |
:sp {file} |
Split current window in two. |
[ ] |
:vsp {file} |
Split vertically current window in two. |
[ ] |
<ctrl-w> s |
Split current window in two. |
[ ] |
<ctrl-w> v |
Split vertically current window in two. |
[ ] |
<ctrl-w> o |
Close other editor groups. |
[ ] |
:new |
Create a new window horizontally and start editing an empty file in it. |
[ ] |
:vne[w] |
Create a new window vertically and start editing an empty file in it. |