Adds vim bindings to nodejs readline.
npm install readline-vim
Repl Example:
var rlv = require('readline-vim')
, repl = require('repl');
var r = repl.start({
prompt: "vim repl > ",
input: process.stdin,
output: process.stdout
});
// pass the readline component of the repl in order to add vim bindings to it
var vim = rlv(r.rli)
, map = vim.map;
// Add mappings
// [insert mode] allow switching to normal mode by typing 'jk' quickly
map.insert('jk', 'esc');
// [insert mode] go backward in history via 'ctrl-k'
map.insert('ctrl-k', 'ctrl-p');
// [insert mode] go backward in history via 'ctrl-k'
map.insert('ctrl-space', 'ctrl-n');
// [normal mode] go backward in history via space bar
map.normal('space', 'k');
// [normal mode] go forward in history via space bar when ctrl is pressed
map.normal('ctrl-space', 'j');
Run it via: npm run demo
Table of Contents generated with DocToc
A subset of vim keybindings is supported by readline-vim
:
Esc
,Ctrl-[
: normal mode
i
,I
,a
,A
: insert mode with the expected side effects
h
cursor leftl
cursor rightw
word rightb
word left0
beginning of line$
end of linef
,F
,t
,T
followed by letter moves cursor to or up to the given letter
-
cb
: change word left -
cw
: change word right -
ch
: change left -
cl
: change right -
cc
: change line -
C
: change line right -
db
: delete word left -
dw
: delete word right -
dh
: delete left -
dl
: delete right -
dd
: delete line -
D
: delete line right -
x
delete right -
X
delete left
r
followed by letter replaces letter under the cursor with the given letter (i.e.rx
)
k
go back in historyj
go forward in history
Immediate mappings execute immediately whe a key (possibly with modifiers) is pressed.
They can be applied in insert and normal mode.
Assuming we defined vim
and map
as outlined in the usage examle.
// emit [esc] when [ctrl-space] is pressed to switch to normal mode
map.insert('ctrl-space', 'esc');
// emit [k] when [space] is pressed to go backward in history
map.normal('space', 'k');
Sequence mappings are a number of keys without modifiers pressed quickly after another.
They can be applied to insert mode only.
Assuming we defined vim
and map
as outlined in the usage examle.
// map [jk] pressed in quick succession to [esc] to switch to normal mode
map.insert('jk', 'esc');
The interval allowed between keys in order to count as a sequence can be configured by setting vim.threshold
, the
default is 200 milliseconds
.
You can inspect your mappings by navigating/printing the vim.map.mappings
object.
The following events are emitted to allow reacting to state changes:
normal
when mode changes to normalinsert
when mode changes to insertwrite
when a key is written to the underlyingreadline
(i.e. it wasn't handled byreadline-vim
and therefore passed through
These events are exposed via vim.events
, so to subscribe to normal mode changes you would do:
vim.events.on('normal', function () {
// do something here to react
});
You can cause the readline
to change to a particular mode and pass a Boolean
to indicate if that mode change should
be kept a secret (i.e. no event is emitted).
vim.forceInsert(); // changes mode to insert and emits 'insert' event
vim.forceNormal(true); // changes mode to normal, but emits no event