use utf8;

my @motions = qw(
	g z [ ]
	b B e E f F G ^h h H j ^j k l L M ^m n N ^n ^p t T w W
	0 ` ' # $ % ^ * ( ) { } ; / ? + - _ | ,
);

{
title => 'vi/vim',
version => 1.6,
description => [
	"Interactive cheat sheet for vi text editors, notably Vim,",
	"describing each key in various modes.",
],
keywords => [qw' vi vim nvi '],

mode => {
	''    => "normal mode",
	 g    => "extended commands (g)",
	 Z    => "quit commands",
	 z    => "additional commands (z)",
	'['   => "backward search commands ([)",
	']'   => "forward search commands (])",
	'^w'  => "window commands (ctrl-w)",
	'^wg' => "extended window commands (ctrl-w g)",
	 v    => "visual mode",
	 vg   => "extended visual commands (v g)",
	 va   => "text object selection (v a/i)",
#	 c    => "command-line mode",
	 i    => "insert mode",
	'i^g' => "extended insert commands (i ctrl-g)",
	'i^x' => "insert completion commands (i ctrl-x)",
	 d    => 'delete motions',
},

flag => {
	g1 => ["info", "Info command: shows/does something without altering anything."],
	g2 => ["motion", "Moves the cursor, or defines the range for an operator (<motion>)."],
	g3 => ["positioning", "Other movement (jumps, window (re)positioning)."],
	g4 => ["command", "Direct action command."],
	g6 => ["ins mode", "Enters Insert or Replace mode."],
	g7 => ["mode", "Enters a different mode."],
	g8 => ["vis mode", "Enters Visual or Select mode."],
	g9 => ["key cmd", "Additional key commands (click for overview)."],

	arg => ["key<arg>", "Commands with a dot need a char argument afterwards."],
	motion => ["key<motion>", "Requires a motion afterwards, operates between cursor and destination."],
	'v6 new' => ["vim", "Not in original Vi (assessment incomplete)."],
	'xcommentary xlion xsurround xunimpaired ext' => ["plugin", "Optional features provided by common plugins."],
},

def => {
	'' => {
		'~' => ["g4 undo", "case toggle"],
		'!' => ["g4 argm undo modec", "filt<>er lines"],
		'@' => ["g4 arg undo", "play macro"],
		'#' => ["g2 v6", "rev. find word"],
		'$' => ["g2", "eol"],
		'%' => ["g2", "goto match"],
		'^' => ["g2", '"soft" bol'],
		'&' => ["g4 undo", ":s rep<>eat"],
		'*' => ["g2 v6", "find word"],
		'(' => ['g2', "begin senten<>ce"],
		')' => ['g2', "end senten<>ce"],
		'_' => ["g2", '"soft" bol down'],
		'+' => ["g2", "next line"],
		'`' => ["g2 arg", "goto mark"],
		'0' => ["g2", '"hard" bol'],
		'^^'=> ["g4", "edit alt. file"],
		'-' => ["g2", "prev line"],
		'=' => ['g4 argm undo', "re<>ind<>ent"],
		'?' => ["g2 arg modec", "find rev."],
		';' => ["g2", "repeat t/f/T/F"],
		':' => ["g4 modec", "ex cmd line"],
		"'" => ["g2 arg", "goto mark bol"],
		'"' => ['g4 arg', "use reg<>ister"],
		'\\' => ['g9 arg', "reser<>ved"],
		'^\\' => ["g7 arg", "to mode/<>ext<>ens<>ion<>s"],
		',' => ["g2", "reverse t/T/f/F"],
		'<' => ["g4 argm undo", "un<>ind<>ent"],
		'.' => ["g4 undo", "repeat last cmd"],
		'>' => ["g4 argm undo", "ind<>ent"],
		'/' => ["g2 arg modec", "find"],
		'[' => ["g9 arg mode[", "move back<>ward<>s"],
		'{' => ["g2", "begin parag."],
		']' => ["g9 arg mode]", "move forw<>ard"],
		'}' => ["g2", "end parag."],
		'^]'=> ["g3", "go to tag"],
		'|' => ["g2", "goto (1st) col"],

		'a' => ["g6 undo modei", "app<>end"],
		'A' => ["g6 undo modei", "app<>end to eol"],
		'^a'=> ["g4 undo", "incr<>ement\nAdd one"],
		'b' => ["g2", "prev word\nBack"],
		'B' => ["g2", 'prev <span style="font-variant:small-caps">word</span>'],
		'^b'=> ["g3", "page up"],
		'c' => ["g6 argm undo modei", "chan<>ge"],
		'C' => ["g6 undo modei", "chan<>ge to eol"],
		'^c'=> ["g4", "abort"],
		'd' => ["g4 argm undo moded", "del<>ete"],
		'D' => ["g4 undo", "delete to eol"],
		'^d'=> ["g3", "scroll down"],
		'e' => ["g2", "end word"],
		'E' => ["g2", 'end <span style="font-variant:small-caps">word</span>'],
		'^e'=> ["g3", "window down\nExtra line"],
		'f' => ["g2 arg", "fwd to char"],
		'F' => ["g2 arg", "back<>wd to char"],
		'^f'=> ["g3", "page down\npage Forward"],
		'g' => ["g9 arg modeg", "extra cmds"],
		'G' => ["g2", "eof/<>goto ln"],
		'^g'=> ["g1", ":file (info)"],
		'h' => ["g2", "<left>"],
		'H' => ["g2", "screen top\nHome row"],
		'^h'=> \'h',
		'i' => ["g6 undo modei", "insert mode"],
		'I' => ["g6 undo modei", "insert at bol"],
		'^i'=> ["g2 v6", "jump to newer\nIncrease position"],
		'j' => ["g2", "<down>"],
		'J' => ["g4 undo", "join lines"],
		'^j'=> \'j',
		'k' => ["g2", "<up>"],
		'K' => ["g4", "help\nlooKup Keyword"],
		'l' => ["g2", "<right>"],
		'L' => ["g2", "screen bottom\nLowermost Line"],
		'^l'=> ["g1", "redraw"],
		'm' => ["g4 arg", "set mark"],
		'M' => ["g2", "screen mid<>dle"],
		'^m'=> \'+',
		'n' => ["g2", "next find"],
		'N' => ["g2", "prev find"],
		'^n'=> \'j',
		'o' => ["g6 undo modei", "line below\nOpen"],
		'O' => ["g6 undo modei", "line above"],
		'^o'=> ["g2 v6", "jump to older"],
		'p' => ["g4 undo", "paste after"],
		'P' => ["g4 undo", "paste before"],
		'^p'=> \'k',
		'q' => ["g7 arg", "rec<>ord macro\nQueue seQuence"],
		'Q' => ["g7", "ex mode"],
		'^q'=> ["g1", "(xon)\nQome back"], # or ^v
		'r' => ["g4 arg undo", "repl<>ace char"],
		'R' => ["g6 undo modei", "repl<>ace mode"],
		'^r'=> ["g4 undo v6", "redo"],
		's' => ["g6 undo modei", "subst char"],
		'S' => ["g6 undo modei", "subst line"],
		'^s'=> ["g1", "(xoff)\nStop"],
		't' => ["g2 arg", "till char"],
		'T' => ["g2 arg", "back till char"],
		'^t'=> ["g3", "back tag"], # backtrag :P
		'u' => ["g4 undo", "undo"],
		'U' => ["g4 undo", "undo line"],
		'^u'=> ["g3", "scroll up"],
		'v' => ["g8 modev", "visual mode"],
		'V' => ["g8 modev", "visual lines"],
		'^v'=> ["g8 modev v6", "visual block"],
		'w' => ["g2", "next word"],
		'W' => ["g2", 'next <span style="font-variant:small-caps">word</span>'],
		'^w'=> ["g9 arg mode^w", "win<>dow cmds"],
		'x' => ["g4 undo", "delete char"],
		'X' => ["g4 undo", "back<>space"],
		'^x'=> ["g4 undo", "subs<>tract"],
		'y' => ["g4 argm", "yank\n(copy)"],
		'Y' => ["g4", "yank line"],
		'^y'=> ["g3", "window up\nYield"],
		'z' => ["g9 arg modez", "extra cmds"],
		'Z' => ["g9 arg modeZ", "quit"],
		'^z'=> ["g1", ":sus<>pend\nzzz (as in sleep)"],
	}, # normal mode

	g => {
		lead => "g",

		"\e"=> ["g7 mode", "normal mode"],

		'~' => ["g4 argm v6", "case toggl<>e"],
		'@' => ["g4 v7", "oper<>at<>or<>func"],
		'#' => ["g2 v6", "rev. find string"],
		'$' => ["g2", "virt<>ual eol"],
		'^' => ["g2 v6", qq'"soft" bol v<>irt<>ual'],
		'&' => ["g4", ":s rep<>eat glob<>al<>ly\nGlobal substitute"],
		'*' => ["g2 v6", "find string"],
		'_' => ["g2 v6", qq'"soft" eol'],
		'+' => ["g4 v7", "later undo"],
		'`' => ["g2 v6 arg", "to mark keepj<>umps"],
		'8' => ["g1", "char hex val<>ue<>s"],
		'0' => ["g2 v6", "virtual bol"],
		'-' => ["g4 v7", "earlier undo"],
		'^['=> ["g7 mode"],
		']' => ["g3", "go to tselect"],
		'^]'=> ["g3", "go to tjump"],
		';' => ["g2", "to prev change pos"],
		"'" => ["g2 v6 arg", "to mark keepj<>umps"],
		'<' => ["g4 v7", "see prev cmd output"],
		'?' => ["g4 argm v6", "rot13 encode"],
		',' => ["g2", "to next change pos"],

		'a' => ["g1", "char value\nGet Ascii value"],
		'^a'=> ["g1", "mem usage stats"],
		'd' => ["g2 v6", "local declar<>ation"],
		'D' => ["g2 v6", "global declar<>ation"],
		'e' => ["g2", "back to word end"],
		'E' => ["g2", qq'back to <span style="font-variant:small-caps">word</span> end'],
		'f' => ["g4 v6", "edit file at cur<>sor\nGoto File"],
		'F' => ["g4 v7", "edit file + jump"],
		'g' => ["g2", "first line"],
		'^g'=> ["g1 vim6", "cur<>sor pos info"],
		'h' => ["g8 modev", "select mode\nGet Highlighted"],
		'H' => ["g8 modev", "select lines\nGet Highlighted"],
		'^h'=> ["g8 modev v6", "select block\nGet Highlighted"],
		'i' => ["g6 undo modei", "insert at last pos"],
		'I' => ["g6 undo modei", "insert at soft bol"],
		'j' => ["g2 v6", "<down> screen"],
		'J' => ["g4", "join leave spac<>ing"],
		'k' => ["g2 v6", "<up> screen"],
		'm' => ["g2 v6", "cen<>ter screen"],
		'n' => ["g8 v7 modev", "select next find"],
		'N' => ["g8 v7 modev", "select prev find"],
		'o' => ["g2", ":goto (byte)"],
		'p' => ["g4 undo", "paste still"],
		'P' => ["g4", "paste before still"],
		'q' => ["g4 argm", "for<>mat"],
		'Q' => ["g7 v6", "ex mode manual :"],
		'r' => ["g4 arg", "virt. repl<>ace char"],
		'R' => ["g6 undo modei", "virt. repl<>ace mode"],
		's' => ["g1 v6", "sleep\nGo to Sleep"],
		't' => ["g3 v7", "next tab\nGoto Tab"],
		'T' => ["g3 v7", "tab back"],
		'u' => ["g4 argm v6", "lower<>case"], # XXX undo?
		'U' => ["g4 undo argm v6", "up<>per<>case"],
		'v' => ['g8 modev', "prev<>ious highl<>ight\nprecedinG Visual"],
		'V' => ["g4", "avoid resel<>ect<>ion"],
		'w' => ["g4 argm v7", "for<>mat still"],
		'x' => ["g4 v7 ext", "Netrw<>BrowseX"],

		# plugins
		'c' => ['g4 argm xcommentary', "(un)<>com<>ment\ncommentary or tComment plugin"],
		'l' => ['g3 argm arg xlion', "align to left\nlion plugin, also good for easy-align"],
		'L' => ['g3 argm arg xlion', "align to right\nlion plugin"],
	}, # mode g

	Z => {
		lead => "Z",

		"\e"=> ["g7 mode", "normal mode"],
		'^['=> \"Z\e",

		'Q' => ["g4 v6", " :q! (force)"],
		'Z' => ["g4", " :wq (write)"],
	}, # mode Z

	z => {
		lead => "z",

		"\e"=> ["g7 mode", "normal mode"],

		'^' => ["g3", "page above"],
		'+' => ["g3", "page below"],
		'-' => ["g3", "line at bottom bol\ndon't (-) see any further"],
		'=' => ["g4 v7", "sug<>gest spell<>ing"],
		'.' => ["g3", "line at center bol"],
		'^['=> \"z\e",

		'a' => ["g4 v6 folding", "toggle fold"],
		'A' => ["g4 v6 folding", "toggle fold rec<>urs<>ive<>ly"],
		'b' => ["g3", "line at bot. bol"],
		'c' => ["g4 v6 folding", "close fold"],
		'C' => ["g4 v6 folding", "close folds rec<>curs<>ive<>ly"],
		'd' => ["g4 v6 folding", "delete fold"],
		'D' => ["g4 v6 folding", "delete folds rec<>urs<>ive"],
		'e' => ["g3", "cursor at right side"],
		'E' => ["g4 v6 folding", "elimi<>nate f<>olds"],
		'f' => ["g4 argm v6 folding", "create fold"],
		'F' => ["g4 v6 folding", "fold lines"],
		'g' => ["g4 v7", "add spell<>ing\nGood word"],
		'G' => ["g4 v7", "temp spell<>ing"],
		'h' => ["g3", "scroll <left>"],
		'H' => ["g3", "scroll <left> half scr<>een"],
		'i' => ["g4 v6 folding", "toggle all folds"],
		'j' => ["g2 v6 folding", "next fold start"],
		'k' => ["g2 v6 folding", "prev fold end"],
		'l' => ["g3", "scroll <right>"],
		'L' => ["g3", "scroll <right> half scr<>een"],
		'^m'=> ["g3", "line at top bol"],
		'm' => ["g4 v6 folding", "fold more"],
		'M' => ["g4 v6 folding", "close all folds"],
		'n' => ["g4 v6 folding", "fold none"],
		'N' => ["g4 v6 folding", "fold norm<>al"],
		'o' => ["g4 v6 folding", "open fold"],
		'O' => ["g4 v6 folding", "open folds rec<>urs<>ive<>ly"],
		'r' => ["g4 v6 folding", "reduce folding"],
		'R' => ["g4 v6 folding", "open all folds"],
		's' => ["g3", "cursor at left side"],
		't' => ["g3", "line at top"],
		'u' => ["g4 arg v7", "undo spell<>ing"],
		'v' => ["g4 v6 folding", "unfold cursor line"],
		'w' => ["g4 v7", "add missp<>ell<>ing\nWrong word"],
		'W' => ["g4 v7", "temp missp<>ell<>ing"],
		'x' => ["g4 v6 folding", "update folds"],
		'X' => ["g4 v6 folding", "re<>apply f<>olds"],
		'z' => ["g3", "line at center\nZee Zenter (with a funny accent)"],
	}, # mode z

	'[' => {
		lead => "[",

		"\e"=> ["g7 mode", "normal mode"],

		'`' => ["g2 v6", "previous lc mark"],
		'#' => ["g2", "previous open #if<>/#else"],
		'(' => ["g2", "previous open ("],
		'*' => \'[/',
		'/' => ["g2", "start of C com<>m<>ent"],
		"'" => ["g2 v6", \"0[`^"],
		'{' => ["g2", => "previous open {"],
		'[' => ["g2", "section back<>ward<>s"],
		'^['=> \"[\e",
		']' => ["g2", qq'<span style="font-variant:small-caps">section</span> back<>ward<>s'],

		'c' => ["g2", "start of change backw<>ards"],
		'd' => ["g1", "define line"],
		'D' => ["g4", "defin<>ition"],
		'^d'=> ["g3", "to defin<>it<>ion"],
		'i' => ['g1', "first occur<>renc<>e line"],
		'I' => ['g4', "first occur<>renc<>e"],
		'^i'=> ['g3', "to first occur<>renc<>e"],
		'm' => ["g2", "start of funct<>ion"],
		'p' => ["g4", "P reind<>ent<>ed"],
		'P' => \"[p",
		's' => ["g3 v7", "last missp<>ell<>ing"],
		'S' => ["g3 v7", "last bad word"],
		'z' => ["g2 v6 folding", "start of open fold"],

		# unimpaired
		'a' => ["g3 xunimpaired", "prev<>ious file\nunimpaired map for :prev"],
		'A' => ["g3 xunimpaired", "first file\nunimpaired map for :rew"],
		'b' => ["g3 xunimpaired", "prev<>ious buffer\nunimpaired map for :bp"],
		'B' => ["g3 xunimpaired", "first buffer\nunimpaired map for :br"],
		'e' => ["g4 xunimpaired", "exchange line above\nunimpaired plugin"],
		'f' => \'gf',  # deprecated
		'f' => ["g3 xunimpaired", "preced<>ing file alph<>abet<>ic<>al<>ly\nunimpaired plugin"], # overrides native alias
		'l' => ["g3 xunimpaired", "previous loc<>at<>ion\nunimpaired map for :lp"],
		'L' => ["g3 xunimpaired", "first loc<>ation\nunimpaired map for :lr"],
		'^l'=> ["g3 xunimpaired", "next file in loc<>at<>ions\nunimpaired map for :lpf"],
		'n' => ["g3 xunimpaired", "previous conflict<>/hunk\nunimpaired plugin"],
		'o' => ["g9 arg xunimpaired", "enable option\nunimpaired plugin"],
		#'p' => ["g4 xunimpaired", "linewise paste before"],
		'q' => ["g3 xunimpaired", "previous quickfix\nunimpaired map for :cp"],
		'Q' => ["g3 xunimpaired", "first quickfix\nunimpaired map for :cr"],
		'^q'=> ["g3 xunimpaired", "quickfix file b<>ack\nunimpaired map for :cpf"],
		't' => ["g3 xunimpaired", "previous tag\nunimpaired map for :tp"],
		'T' => ["g3 xunimpaired", "first tag\nunimpaired map for :tr"],
		'u' => ["g4 argm xunimpaired", "url encode\nunimpaired plugin"],
		'x' => ["g4 argm xunimpaired", "xml encode\nunimpaired plugin"],
		'y' => ["g4 argm xunimpaired", "escape c str<>ing\nunimpaired plugin"],
		' ' => ["g4 xunimpaired", 'prepend blank l<>in<>e<>s'],
	}, # mode [

	']' => {
		lead => "]",

		"\e"=> ["g7 mode", "normal mode"],

		'`' => ["g2 v6", "next lc mark"],
		'#' => ["g2", "next open #endif<>/#else"],
		')' => ["g2", "next open )"],
		'*' => \']/',
		"'" => ["g2 v6", \'$]`^'],
		'/' => ["g2", "end of C com<>m<>ent"],
		'[' => ["g2", qq'<span style="font-variant:small-caps">section</span> forw<>ard'],
		'^['=> \"]\e",
		']' => ["g2", "section forw<>ard"],
		'}' => ["g2", "next open }"],

		'c' => ["g2", "start of change forw<>ards"],
		'd' => ["g1", "next define line"],
		'D' => ["g4", "next define"],
		'^d'=> ["g3", "to next define"],
		'f' => \'gf',  # deprecated
		'i' => ["g1", "next occur<>renc<>e line"],
		'I' => ["g4", "next occur<>renc<>e"],
		'^i'=> ["g3", "to occur<>renc<>e"],
		'm' => ["g2", "end of funct<>ion"],
		'p' => ["g4", "p reind<>ent<>ed"],
		'P' => \'[p',
		's' => ["g3 v7", "next missp<>ell<>ing"],
		'S' => ["g3 v7", "next bad word"],
		'z' => ["g2 v6 folding", "end of open fold"],

		# unimpaired
		'a' => ["g3 xunimpaired", "next file\nunimpaired map for :n"],
		'A' => ["g3 xunimpaired", "last file\nunimpaired map for :la"],
		'b' => ["g3 xunimpaired", "next buffer\nunimpaired map for :bn"],
		'B' => ["g3 xunimpaired", "last buffer\nunimpaired map for :bl"],
		'e' => ["g4 xunimpaired", "exchange line belo<>w\nunimpaired plugin"],
		'f' => ["g3 xunimpaired", "next file alph<>abet<>ic<>al<>ly\nunimpaired plugin"], # overrides native alias
		'l' => ["g3 xunimpaired", "next loc<>ation\nunimpaired map for :lne"],
		'L' => ["g3 xunimpaired", "last loc<>ation\nunimpaired map for :lla"],
		'^l'=> ["g3 xunimpaired", "file back in loc<>at<>ions\nunimpaired map for :lnf"],
		'n' => ["g3 xunimpaired", "next confl<>ict<>/hunk\nunimpaired plugin"],
		'o' => ["g9 arg xunimpaired", "disable option\nunimpaired plugin"],
		'q' => ["g3 xunimpaired", "next quickfix error\nunimpaired map for :cn"],
		'Q' => ["g3 xunimpaired", "last quickfix error\nunimpaired map for :cla"],
		'^q'=> ["g3 xunimpaired", "next file in q<>uick<>f<>ix\nunimpaired map for :cnf"],
		't' => ["g3 xunimpaired", "next tag\nunimpaired map for :tn"],
		'T' => ["g3 xunimpaired", "last tag\nunimpaired map for :tl"],
		'u' => ["g4 argm xunimpaired", "url decode\nunimpaired plugin"],
		'x' => ["g4 argm xunimpaired", "xml decode\nunimpaired plugin"],
		'y' => ["g4 argm xunimpaired", "unescap<>e c str<>ing\nunimpaired plugin"],
		' ' => ["g4 xunimpaired", 'add blank l<>in<>e<>s bel<>ow'],
	}, # mode ]

	'^w' => {
		lead => "ŵ",

		"\e"=> ["g7 mode", "normal mode"],

		'<' => ["g3", => "width decr<>ease"],
		'>' => ["g3", => "width incr<>ease"],
		'^' => ["g4", => "split, edit alt file"],
		'_' => ["g3", => "set height"],
		'+' => ["g3", => "height incr<>ease"],
		'-' => ["g3", => "height decr<>ease"],
		'=' => ["g3", => "same height"],
		'^['=> \"^w\e",
		']' => ["g3", => "split, to tag"],
		'}' => ["g3", => "pre<>view tag"],
		'|' => ["g3", => "set width"],

		'b' => ["g3", => "go to bot<>tom"],
		'c' => ["g3", => ":close"],
		'^c'=> ["g7 mode", "abort"],
		'd' => ["g3", => "split, to def<>inition"],
		'f' => ["g4", => "split, file edit"],
		'F' => ["g4 v7", => "^wf, jump to line"],
		'g' => ["g9 arg mode^wg", => "extra cmds"],
		'h' => ["g3", => "go left"],
		'H' => ["g3", => "move far left"],
		'i' => ["g3", => "split, to decl of id<>ent<>ifier"],
		'j' => ["g3", => "go down"],
		'J' => ["g3", => "move to bottom"],
		'k' => ["g3", => "go up"],
		'K' => ["g3", => "move to top"],
		'l' => ["g3", => "go right"],
		'L' => ["g3", => "move far right"],
		'n' => ["g4", => "open new"],
		'o' => ["g3", => ":only current"],
		'p' => ["g3", => "go to prev<>ious"],
		'P' => ["g3", => "go to pre<>view"],
		'q' => ["g4", => ":quit current"],
		'r' => ["g3", => "rotate down<>ward<>s"],
		'R' => ["g3", => "rotate up<>ward<>s"],
		's' => ["g3", => "split horiz<>ont<>al<>ly"],
		'S' => \'^ws',
		't' => ["g3", => "go to top"],
		'T' => ["g3 v7", => "to tab"],
		'v' => ["g3", => "split vert<>ic<>al<>ly"],
		'w' => ["g3", => "go to next\nWrap around"],
		'W' => ["g3", => "go above<>/left"],
		'x' => ["g3", => "ex<>chan<>ge"],
		'z' => ["g3", => "close pre<>view"],
	}, # mode ^w

	'^wg' => {
		lead => "ŵg",

		"\e"=> ["g7 mode", "normal mode"],
		'^['=> \"^wg\e",
		']' => ["g3", => "split, :ts<>elect"],
		'}' => ["g3", => ":ptj<>ump to tag"],
		'^]'=> ["g3", "split, :tj<>ump"],
		'f' => ["g4 v7", => "file in tab"],
		'F' => ["g4 v7", => "^wgf, to line<>nr"],
	}, # mode ^w g

	v => {
		"\e"=> ["g7 mode", "normal mode"],

		'!' => ["g4", "external filter"],
		':' => ["g7 modec", "cmd on range"],
		'<' => ["g4", "un<>indent"],
		'=' => ['g4 undo', "re<>ind<>ent"],
		'>' => ['g4', "ind<>ent"],
		'~' => ["g4 v6", "toggle case"],
		'^['=> \"v\e",
		'^]'=> ["g3", "jump to tag"],
		'^\\'=>\'^\\',

		'a' => ['g9 modeva arg v6', "ex<>tend area"],
		'A' => ['g6 modei v6', "ap<>pend to block"], # block
		'^a'=> ['g4 undo v8', "incr<>ement num<>bers"],
		'c' => ['g6 modei v6', "repl<>ace area"],
		'C' => ['g6 modei v6', "repl<>ace full lines"], # like vS, but blocks are extended until eol
		'^c'=> ["g7 mode", "abort"],
		'd' => ["g4 v6", "delete area"],
		'D' => ["g4 v6", "delete lines"],
		'g' => ["g9 arg modevg", "extra cmds"],
		'^g'=> ["g8", "select mode"],
		'i' => ["g9 modeva arg v6", "extend inner a<>r<>ea"],
		'I' => ["g6 modei v6", "insert to block"], # block
		'J' => ["g4", "join lines"],
		'K' => ['g4', "help sel<>ect<>ion"],
		'o' => ["g2", "to other corner"],
		'O' => ["g2", "to other side"],
		'^o'=> ["g8", "visual once"], # select
		'p' => ['g4', "repl<>ace w/ paste"],
		'P' => ['g4', "repl<>ace w/ paste"],
		'r' => ['g4 arg', "fill up w/ ch<>ar"],
		'R' => \'vS',  # "might change in future"
		's' => \'vc',
		'S' => ['g6 modei v6', "repl<>ace lines"],
		'u' => ["g4 v6", "lower<>case"],
		'U' => ["g4 v6", "upper<>case"],
		'v' => ["g8", "char<>wise"],
		'V' => ["g8", "line<>wise"],
		'^v'=> ["g8 v6", "block<>wise"],
		'x' => \'vd',
		'X' => \'vD',
		'^x'=> ['g4 undo v8', "decr<>ement num<>bers"],
		'y' => ["g4", "yank area"],
		'Y' => ["g4", "yank lines"],

		(map { $_ => \$_ } @motions, qw(
			^b ^d ^e ^f ^i m q ^q ^s ^u ^w ^y z ^z "
		)), # a lot like normal mode TODO
	}, # mode v

	'vg' => {
		lead => "g",

		"\e"=> ["g8 modev", "visual mode"],

		'^['=> \"vg\e",
		'?' => ["g4 v6", => "rot13 encode"],
		'^a'=> ['g4 undo v8', "seq. incr<>ement"],
		'^g' => ["g1 vim6", "count region info"],
		'J' => ['g4 v6', => "join literal<>ly"],
		'q' => ["g4 v6", => "for<>mat"],
		'v' => \'gv',
		'w' => ['g4 v7', => "for<>mat still"],
		'^x'=> ['g4 undo v8', "seq. decr<>ement"],

		# plugins
		'c' => ['g4 xcommentary', => "(un)<>com<>ment\ncommentary or tComment plugin"],
		'l' => ['g3 arg xlion', => "align to left\nlion plugin, also good for easy-align"],
		'L' => ['g3 arg xlion', => "align to right\nlion plugin"],
	}, # mode v g

	va => {
		"\e"=> ["g8 modev", "visual mode"],

		'(' => \'vab',
		')' => \'vab',
		'`' => \"va'",
		"'" => ['g2 v7', "quoted string"],
		'"' => \"va'",
		'<' => ['g2 v6', => "&lt;&gt; block"],
		'>' => \'va<',
		'[' => ['g2 v6', => "[] block"],
		'{' => \'vaB',
		'^['=> \"va\e",
		']' => \'va[',
		'}' => \'vaB',

		'b' => ['g2 v6', => "() block"],
		'B' => ['g2 v6', => "{} Block"],
		'p' => ['g2 v6', => "para<>graph"],
		's' => ['g2 v6', => "senten<>ce"],
		't' => ['g2 v7', => "xml tag block"],
		'w' => ['g2 v6', => "word"],
		'W' => ['g2 v6', => '<span style="font-variant:small-caps">word</span>'],
	}, # mode v a

	#c => {
	#	desc => "command-line mode",
	#
	#	'^_' => \"i^_",
	#	'^^' => \"i^^",
	#	'^\\'=>'^\\',
	#	'^a' => ["", "complete"], #todo
	#	'^b' => ["g3", "bol"],
	#	'^c' => \"i^c",
	#	'^d' => ["", "complete"], #todo
	#	'^e' => ["g3", "eol"],
	#	'^h' => \"i^h",
	#	'^j' => ["g4", "execute cmd"],
	#	'^k' => \"i^k",
	#	'^l' => ["", "complete"], #todo
	#	'^n' => ["", "complete"], #todo
	#	'^p' => ["", "complete"], #todo
	#	'^r' => \'i^r', # and then some...
	#	     ## ["g4 arg v6", "insert register"],
	#	'^q' => \"^q",
	#	'^u' => \"i^u",
	#	'^v' => \"i^v",
	#	'^w' => \"i^w",
	#	'^y' => ["g4", "selec<>tion to clip<>b<>oard"],
	#}, # mode c

	i => {
		"\e" => ["g7 mode", "normal mode"],

		'^@' => ["g4", => "last insert"],
		'^^' => ["g4 v6", => "toggle :lmap usag<>e"],
		'^[' => \"i\e",
		'^]' => ["g4 v6", => "abbrev<>iate"],
		'^_' => ["g4 v6", => "toggle lang<>uage"],
		'^\\'=>\'^\\',

		'^a' => ["g4 v6", => "insert prev<>ious"],
		'^b' => ["no v6", => "former i^_"],
		'^c' => ["g7 mode", => "abort, no abbr"],
		'^d' => ['g4', => "un<>ind<>ent"],
		'^e' => ["g4 v6", => "ins char below"],
		'^f' => ['g4', => "set indent<>ation"],
		'^g' => ["g9 modei^g arg", => "extra cmds"],
		'^h' => ["g4", => "back<>space"],
		'^i' => ["g4", => "tab"],
		'^j' => ["g4", => "enter"],
		'^k' => ['g4 arg arg v6 linkdigraphs', => "di<>graph\nKey code"],
		'^l' => ["g7 mode v6", => "<em>im</em> leave ins mode"],  # insertmode only
		'^m' => ["g4", => "enter"],
		'^n' => ["g2 v6", => "find next keyword"],
		'^o' => ['g4', => "exec<>ute cmd"],
		'^p' => ["g2 v6", => "find prev keyword"],
		'^q' => \'^q',  # or i^v
		'^r' => ['g4 arg v6', "insert reg<>ister"],
		'^s' => \'^s',
		'^t' => ["g4", => "indent"],
		'^u' => ["g4", => "delete line"],
		'^v' => ['g4 linkcharset', => "literal or ch<>ar<>cod<>e\nVerbatim or by Value"],
		'^w' => ["g4", => "delete word back"],
		'^x' => ['g9 arg modei^x v6', => "ex<>pand mode"],
		'^y' => ["g4 v6", => "ins char above"],
		'^z' => ["g1 v6", => ":sus<>pend in <em>im</em>"],  # insertmode only
	}, # modei

	'i^g' => {
		lead => "ĝ",

		"\e"=> ['g6 modei', "insert mode"],

		'k' => ['g2', => "<up> start col<>umn"],
		'j' => ['g2', => "<down> start col<>umn"],
		'u' => ['g4', => "break undo seq<>uence"],
		'U' => ['g4 v8', => "keep undo seq<>uence"],
		# other keys (even esc) are not recognized

		's' => ['g4 arg xsurround', => "sur<>round\nsurround plugin"],
	}, # mode i ^g

	'i^x' => {
		lead => "x̂",

		"\e" => ["g7 mode", "normal mode"], # yes, it really leaves insert mode

		'^['=> \"i^x\e",
		'^]' => ['g4', => "tag comp<>l<>et<>e"],
		'^d' => ['g4', => "def<>ine compl<>et<>e"],
		'^e' => ["g3", => "window up"],
		'^f' => ['g4', => "file comp<>l<>et<>e"],
		'^i' => ['g4', => "ident comp<>l<>et<>e"],
		'^k' => ['g4', => "dict comp<>l<>et<>e"],
		'^l' => ['g4', => "line comp<>l<>et<>e"],
		'^n' => ['g4', => "next comp<>l<>et<>e"],
		'^o' => ['g4 v7', => "omni comp<>l<>et<>e"],
		'^p' => ['g4', => "prev comp<>l<>ete"],
		'^s' => ['g4', => "spell sugg<>est"],
		 's' => \'i^x^s',
		'^t' => ['g4', => "thes<>aur<>us compl<>et<>e"],
		'^u' => ['g4 v7', => "cus<>tom comp<>l<>et<>e"],
		'^v' => ['g4', => "ex cmd compl<>et<>e"],
		'^y' => ["g3", => "window down"],
	}, # mode i ^x

	d => {
		lead => "d",

		"\e"=> ["g7 mode", "normal mode"],
		'^['=> \"d\e",

		'd'  => ['g4', 'delete line'],
		'o'  => ['g5', 'diff obtain'],
		'p'  => ['g5', 'diff put'],
		's'  => ['g4 arg xsurround', 'delete surr<>oun<>d<>ing'],

		(map { ($_ => [\$_, "delete to <alias>$_"]) } qw( g z [ ] )), # modes

		# commands
		(map { $_ => \$_ } qw( \\ ^\\ ^q ^s ^z )),
		'l'  => \'x',
		'h'  => \'X',
		'^h' => \'X',
		'^j' => \'dj',
		'^m' => \'dj',
		'^n' => \'dj',
		'+'  => \'dj',
		'^p' => \'dk',
		'-'  => \'dk',
		'$'  => \'D',
		'_'  => \'dd',

		# simple @motions
		'W' => ['g4', 'delete <span style="font-variant:small-caps">word</span>'],
		'b' => ['g4', 'delete <left> word'],
		'B' => ['g4', 'delete <left> <span style="font-variant:small-caps">word</span>'],
		'e' => ['g4', 'delete word e<>nd'],
		'E' => ['g4', 'delete <span style="font-variant:small-caps">word</span> e<>nd'],
		'G' => ['g4', 'delete to line<>/eof'],
		'H' => ['g4', 'delete to top'],
		'j' => ['g4', 'delete <down> line'],
		'k' => ['g4', 'delete <up> line'],
		'L' => ['g4', 'delete to bottom'],
		'M' => ['g4', 'delete to middle'],
		'n' => ['g4', 'delete to next res<>ult'],
		'N' => ['g4', 'delete to prev res<>ult'],
		'w' => ['g4', 'delete word'],
		',' => ['g4', 'delete to prev ch<>ar<>acter'],
		';' => ['g4', 'delete to next ch<>ar<>acter'],
		'*' => ['g4', 'delete to find'],
		'#' => ['g4', 'delete <left> to find'],
		'%' => ['g4', 'delete to line pct'],
		'^' => ['g4', 'delete to soft bol'],
		'0' => ['g4', 'delete to bol'],
		'|' => ['g4', 'delete to col<>umn'],
		'{' => ['g4', 'delete <left> par<>agr<>aph'],
		'}' => ['g4', 'delete rest of p<>ar<>agr<>aph'],
		'(' => ['g4', 'delete <left> senten<>ce'],
		')' => ['g4', 'delete rest of s<>en<>ten<>ce'],

		# @motions with option
		'f' => ['g4 arg', 'delete to char<>acter'],
		'F' => ['g4 arg', 'delete <left> to char<>acter'],
		't' => ['g4 arg', 'delete upto ch<>ar<>acter'],
		'T' => ['g4 arg', 'delete <left> upto ch<>ar<>acter'],
		'`' => ['g4 arg', 'delete to mark'],
		"'" => ['g4 arg', 'delete lines to m<>ark'],
		'/' => ['g4 arg', 'delete to res<>ult'],
		'?' => ['g4 arg', 'delete <left> to res<>ult'],

		# motions from virtual
		'a' => ['g9 modeva arg v6 alias', 'delete area'], # va
		'i' => ['g9 modeva arg v6 alias', 'delete inner'], # vi
	}, # mode d

	# y => { 'o' => ['g9 arg xunimpaired', "toggle option\nunimpaired plugin"] }, # TODO

	# TODO: mode/ (command-line)
	# XXX ex mode if you want to go completely wild
},
}
