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 |
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 |
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. |