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 ` ' # $ % ^ * ( ) { } ; / ? + - _ | ,
);

{
key => {

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

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

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

	'ga' => "char value\nGet Ascii value",
	'g^a'=> "mem usage stats",
	'gd' => "local declar<>ation",
	'gD' => "global declar<>ation",
	'ge' => "back to word end",
	'gE' => qq'back to <span style="font-variant:small-caps">word</span> end',
	'gf' => "edit file at cur<>sor\nGoto File",
	'gF' => "edit file + jump",
	'gg' => "first line",
	'g^g'=> "cur<>sor pos info",
	'gh' => "select mode\nGet Highlighted",
	'gH' => "select lines\nGet Highlighted",
	'g^h'=> "select block\nGet Highlighted",
	'gi' => "insert at last pos",
	'gI' => "insert at soft bol",
	'gj' => "<down> screen",
	'gJ' => "join leave spac<>ing",
	'gk' => "<up> screen",
	'gm' => "cen<>ter screen",
	'gn' => "select next find",
	'gN' => "select prev find",
	'go' => ":goto (byte)",
	'gp' => "paste still",
	'gP' => "paste before still",
	'gq' => "for<>mat",
	'gQ' => "ex mode manual :",
	'gr' => "virt. repl<>ace char",
	'gR' => "virt. repl<>ace mode",
	'gs' => "sleep\nGo to Sleep",
	'gt' => "next tab\nGoto Tab",
	'gT' => "tab back",
	'gu' => "lower<>case",
	'gU' => "up<>per<>case",
	'gv' => "prev<>ious highl<>ight\nprecedinG Visual",
	'gV' => "avoid resel<>ect<>ion",
	'gw' => "for<>mat still",
	'gx' => "Netrw<>BrowseX",

	"Z\e"=> "normal mode",
	'ZQ' => " :q! (force)",
	'ZZ' => " :wq (write)",

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

	'za' => "toggle fold",
	'zA' => "toggle fold rec<>urs<>ive<>ly",
	'zb' => "line at bot. bol",
	'zc' => "close fold",
	'zC' => "close folds rec<>curs<>ive<>ly",
	'zd' => "delete fold",
	'zD' => "delete folds rec<>urs<>ive",
	'ze' => "cursor at right side",
	'zE' => "elimi<>nate f<>olds",
	'zf' => "create fold",
	'zF' => "fold lines",
	'zg' => "add spell<>ing\nGood word",
	'zG' => "temp spell<>ing",
	'zh' => "scroll <left>",
	'zH' => "scroll <left> half scr<>een",
	'zi' => "toggle all folds",
	'zj' => "next fold start",
	'zk' => "prev fold end",
	'zl' => "scroll <right>",
	'zL' => "scroll <right> half scr<>een",
	'z^m'=> "line at top bol",
	'zm' => "fold more",
	'zM' => "close all folds",
	'zn' => "fold none",
	'zN' => "fold norm<>al",
	'zo' => "open fold",
	'zO' => "open folds rec<>urs<>ive<>ly",
	'zr' => "reduce folding",
	'zR' => "open all folds",
	'zs' => "cursor at left side",
	'zt' => "line at top",
	'zu' => "undo spell<>ing",
	'zv' => "unfold cursor line",
	'zw' => "add missp<>ell<>ing\nWrong word",
	'zW' => "temp missp<>ell<>ing",
	'zx' => "update folds",
	'zX' => "re<>apply f<>olds",
	'zz' => "line at center\nZee Zenter (with a funny accent)",

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

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

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

	']c' => "start of change forw<>ards",
	']d' => "next define line",
	']D' => "next define",
	']^d'=> "to next define",
	']i' => "next occur<>renc<>e line",
	']I' => "next occur<>renc<>e",
	']^i'=> "to occur<>renc<>e",
	']m' => "end of funct<>ion",
	']p' => "p reind<>ent<>ed",
	']s' => "next missp<>ell<>ing",
	']S' => "next bad word",
	']z' => "end of open fold",

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

	'^wb' => "go to bot<>tom",
	'^wc' => ":close",
	'^w^c'=> "abort",
	'^wd' => "split, to def<>inition",
	'^wf' => "split, file edit",
	'^wF' => "^wf, jump to line",
	'^wg' => "extra cmds",
	'^wh' => "go left",
	'^wH' => "move far left",
	'^wi' => "split, to decl of id<>ent<>ifier",
	'^wj' => "go down",
	'^wJ' => "move to bottom",
	'^wk' => "go up",
	'^wK' => "move to top",
	'^wl' => "go right",
	'^wL' => "move far right",
	'^wn' => "open new",
	'^wo' => ":only current",
	'^wp' => "go to prev<>ious",
	'^wP' => "go to pre<>view",
	'^wq' => ":quit current",
	'^wr' => "rotate down<>ward<>s",
	'^wR' => "rotate up<>ward<>s",
	'^ws' => "split horiz<>ont<>al<>ly",
	'^wt' => "go to top",
	'^wT' => "to tab",
	'^wv' => "split vert<>ic<>al<>ly",
	'^ww' => "go to next\nWrap around",
	'^wW' => "go above<>/left",
	'^wx' => "ex<>chan<>ge",
	'^wz' => "close pre<>view",

	"^wg\e"=> "normal mode",
	'^wg]' => "split, :ts<>elect",
	'^wg}' => ":ptj<>ump to tag",
	'^wg^]'=> "split, :tj<>ump",
	'^wgf' => "file in tab",
	'^wgF' => "^wgf, to line<>nr",

	'v!' => "external filter",
	'v:' => "cmd on range",
	'v<' => "un<>indent",
	'v=' => "re<>ind<>ent",
	'v>' => "ind<>ent",
	'v~' => "toggle case",
	"v\e"=> "normal mode",
	'v^]'=> "jump to tag",

	'va' => "ex<>tend area",
	'vA' => "ap<>pend to block", # block
	'v^a'=> "incr<>ement num<>bers",
	'vc' => "repl<>ace area",
	'vC' => "repl<>ace full lines", # like vS, but blocks are extended until eol
	'v^c'=> "abort",
	'vd' => "delete area",
	'vD' => "delete lines",
	'vg' => "extra cmds",
	'v^g'=> "select mode",
	'vi' => "extend inner a<>r<>ea",
	'vI' => "insert to block", # block
	'vJ' => "join lines",
	'vK' => "help sel<>ect<>ion",
	'vo' => "to other corner",
	'vO' => "to other side",
	'v^o'=> "visual once", # select
	'vp' => "repl<>ace w/ paste",
	'vP' => "repl<>ace w/ paste",
	'vr' => "fill up w/ ch<>ar",
	'vS' => "repl<>ace lines",
	'vu' => "lower<>case",
	'vU' => "upper<>case",
	'vv' => "char<>wise",
	'vV' => "line<>wise",
	'v^v'=> "block<>wise",
	'v^x'=> "decr<>ement num<>bers",
	'vy' => "yank area",
	'vY' => "yank lines",

	"vg\e"=> "visual mode",
	'vg?' => "rot13 encode",
	'vg^a'=> "seq. incr<>ement",
	'vg^g'=> "count region info",
	'vgJ' => "join literal<>ly",
	'vgq' => "for<>mat",
	'vgw' => "for<>mat still",
	'vg^x'=> "seq. decr<>ement",

	"va'" => "quoted string",
	'va<' => "&lt;&gt; block",
	'va[' => "[] block",
	"va\e"=> "visual mode",

	'vab' => "() block",
	'vaB' => "{} Block",
	'vap' => "para<>graph",
	'vas' => "senten<>ce",
	'vat' => "xml tag block",
	'vaw' => "word",
	'vaW' => '<span style="font-variant:small-caps">word</span>',

#	'c^a' => "complete", #todo
#	'c^b' => "bol",
#	'c^d' => "complete", #todo
#	'c^e' => "eol",
#	'c^j' => "execute cmd",
#	'c^l' => "complete", #todo
#	'c^n' => "complete", #todo
#	'c^p' => "complete", #todo
#	'c^r' => \'i^r', # and then some...
#	      ## "insert register",
#	'c^y' => "selec<>tion to clip<>b<>oard",

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

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

	"i^g\e"=> "insert mode",
	'i^gk' => "<up> start col<>umn",
	'i^gj' => "<down> start col<>umn",
	'i^gu' => "break undo seq<>uence",
	'i^gU' => "keep undo seq<>uence",
	# other i^g keys (even esc) are not recognized

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

	# plugins
	  'gc' => "(un)<>com<>ment\ncommentary or tComment plugin",
	 'vgc' => "(un)<>com<>ment\ncommentary or tComment plugin",
	  'gl' => "align to left\nlion plugin, also good for easy-align",
	 'vgl' => "align to left\nlion plugin, also good for easy-align",
	  'gL' => "align to right\nlion plugin",
	 'vgL' => "align to right\nlion plugin",
	'i^gs' => "sur<>round\nsurround plugin",

	# unimpaired
	'[a' => "prev<>ious file\nunimpaired map for :prev",
	']a' => "next file\nunimpaired map for :n",
	'[A' => "first file\nunimpaired map for :rew",
	']A' => "last file\nunimpaired map for :la",
	'[b' => "prev<>ious buffer\nunimpaired map for :bp",
	']b' => "next buffer\nunimpaired map for :bn",
	'[B' => "first buffer\nunimpaired map for :br",
	']B' => "last buffer\nunimpaired map for :bl",
	'[e' => "exchange line above\nunimpaired plugin",
	']e' => "exchange line belo<>w\nunimpaired plugin",
	'[f' => "preced<>ing file alph<>abet<>ic<>al<>ly\nunimpaired plugin",
	']f' => "next file alph<>abet<>ic<>al<>ly\nunimpaired plugin",
	'[l' => "previous loc<>at<>ion\nunimpaired map for :lp",
	']l' => "next loc<>ation\nunimpaired map for :lne",
	'[L' => "first loc<>ation\nunimpaired map for :lr",
	']L' => "last loc<>ation\nunimpaired map for :lla",
	'[^l'=> "next file in loc<>at<>ions\nunimpaired map for :lpf",
	']^l'=> "file back in loc<>at<>ions\nunimpaired map for :lnf",
	'[n' => "previous conflict<>/hunk\nunimpaired plugin",
	']n' => "next confl<>ict<>/hunk\nunimpaired plugin",
	'[o' => "enable option\nunimpaired plugin",
	']o' => "disable option\nunimpaired plugin",
	'yo' => "toggle option\nunimpaired plugin",
	'[q' => "previous quickfix\nunimpaired map for :cp",
	']q' => "next quickfix error\nunimpaired map for :cn",
	'[Q' => "first quickfix\nunimpaired map for :cr",
	']Q' => "last quickfix error\nunimpaired map for :cla",
	'[^q'=> "quickfix file b<>ack\nunimpaired map for :cpf",
	']^q'=> "next file in q<>uick<>f<>ix\nunimpaired map for :cnf",
	'[t' => "previous tag\nunimpaired map for :tp",
	']t' => "next tag\nunimpaired map for :tn",
	'[T' => "first tag\nunimpaired map for :tr",
	']T' => "last tag\nunimpaired map for :tl",
	'[u' => "url encode\nunimpaired plugin",
	']u' => "url decode\nunimpaired plugin",
	'[x' => "xml encode\nunimpaired plugin",
	']x' => "xml decode\nunimpaired plugin",
	'[y' => "escape c str<>ing\nunimpaired plugin",
	']y' => "unescap<>e c str<>ing\nunimpaired plugin",

	(map { ("d$_" => "delete to <alias>$_") } qw( g z [ ] )),
	'dW' => 'delete <span style="font-variant:small-caps">word</span>',
	'db' => 'delete <left> word',
	'dB' => 'delete <left> <span style="font-variant:small-caps">word</span>',
	'de' => 'delete word e<>nd',
	'dE' => 'delete <span style="font-variant:small-caps">word</span> e<>nd',
	'df' => 'delete to char<>acter',
	'dF' => 'delete <left> to char<>acter',
	'dG' => 'delete to line<>/eof',
	'dH' => 'delete to top',
	'dj' => 'delete <down> line',
	'dk' => 'delete <up> line',
	'dL' => 'delete to bottom',
	'dM' => 'delete to middle',
	'dn' => 'delete to next res<>ult',
	'dN' => 'delete to prev res<>ult',
	'dt' => 'delete upto ch<>ar<>acter',
	'dT' => 'delete <left> upto ch<>ar<>acter',
	'dw' => 'delete word',
	'd,' => 'delete to prev ch<>ar<>acter',
	'd;' => 'delete to next ch<>ar<>acter',
	'd/' => 'delete to res<>ult',
	'd?' => 'delete <left> to res<>ult',
	'd`' => 'delete to mark',
	"d'" => 'delete lines to m<>ark',
	'd*' => 'delete to find',
	'd#' => 'delete <left> to find',
	'd%' => 'delete to line pct',
	'd^' => 'delete to soft bol',
	'd0' => 'delete to bol',
	'd|' => 'delete to col<>umn',
	'd{' => 'delete <left> par<>agr<>aph',
	'd}' => 'delete rest of p<>ar<>agr<>aph',
	'd(' => 'delete <left> senten<>ce',
	'd)' => 'delete rest of s<>en<>ten<>ce',
	'da' => 'delete area',
	'di' => 'delete inner',
	'dd' => 'delete line',
	'do' => 'diff obtain',
	'dp' => 'diff put',
	'ds' => 'delete surr<>oun<>d<>ing',
},

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",
		'!' => "g4 argm undo modec",
		'@' => "g4 arg undo",
		'#' => "g2 v6",
		'$' => "g2",
		'%' => "g2",
		'^' => "g2",
		'&' => "g4 undo",
		'*' => "g2 v6",
		'(' => 'g2',
		')' => 'g2',
		'_' => "g2",
		'+' => "g2",
		'`' => "g2 arg",
		'0' => "g2",
		'^^'=> "g4",
		'-' => "g2",
		'=' => 'g4 argm undo',
		'?' => "g2 arg modec",
		';' => "g2",
		':' => "g4 modec",
		"'" => "g2 arg",
		'"' => 'g4 arg',
		'\\' => 'g9 arg',
		'^\\' => "g7 arg",
		',' => "g2",
		'<' => "g4 argm undo",
		'.' => "g4 undo",
		'>' => "g4 argm undo",
		'/' => "g2 arg modec",
		'[' => "g9 arg mode[",
		'{' => "g2",
		']' => "g9 arg mode]",
		'}' => "g2",
		'^]'=> "g3",
		'|' => "g2",

		'a' => "g6 undo modei",
		'A' => "g6 undo modei",
		'^a'=> "g4 undo",
		'b' => "g2",
		'B' => "g2",
		'^b'=> "g3",
		'c' => "g6 argm undo modei",
		'C' => "g6 undo modei",
		'^c'=> "g4",
		'd' => "g4 argm undo moded",
		'D' => "g4 undo",
		'^d'=> "g3",
		'e' => "g2",
		'E' => "g2",
		'^e'=> "g3",
		'f' => "g2 arg",
		'F' => "g2 arg",
		'^f'=> "g3",
		'g' => "g9 arg modeg",
		'G' => "g2",
		'^g'=> "g1",
		'h' => "g2",
		'H' => "g2",
		'^h'=> "=h",
		'i' => "g6 undo modei",
		'I' => "g6 undo modei",
		'^i'=> "g2 v6",
		'j' => "g2",
		'J' => "g4 undo",
		'^j'=> "=j",
		'k' => "g2",
		'K' => "g4",
		'l' => "g2",
		'L' => "g2",
		'^l'=> "g1",
		'm' => "g4 arg",
		'M' => "g2",
		'^m'=> "=+",
		'n' => "g2",
		'N' => "g2",
		'^n'=> "=j",
		'o' => "g6 undo modei",
		'O' => "g6 undo modei",
		'^o'=> "g2 v6",
		'p' => "g4 undo",
		'P' => "g4 undo",
		'^p'=> "=k",
		'q' => "g7 arg",
		'Q' => "g7",
		'^q'=> "g1", # or ^v
		'r' => "g4 arg undo",
		'R' => "g6 undo modei",
		'^r'=> "g4 undo v6",
		's' => "g6 undo modei",
		'S' => "g6 undo modei",
		'^s'=> "g1",
		't' => "g2 arg",
		'T' => "g2 arg",
		'^t'=> "g3",
		'u' => "g4 undo",
		'U' => "g4 undo",
		'^u'=> "g3",
		'v' => "g8 modev",
		'V' => "g8 modev",
		'^v'=> "g8 modev v6",
		'w' => "g2",
		'W' => "g2",
		'^w'=> "g9 arg mode^w",
		'x' => "g4 undo",
		'X' => "g4 undo",
		'^x'=> "g4 undo",
		'y' => "g4 argm",
		'Y' => "g4",
		'^y'=> "g3",
		'z' => "g9 arg modez",
		'Z' => "g9 arg modeZ",
		'^z'=> "g1",
	}, # normal mode

	g => {
		lead => "g",

		"\e"=> "g7 mode",

		'~' => "g4 argm v6",
		'@' => "g4 v7",
		'#' => "g2 v6",
		'$' => "g2",
		'^' => "g2 v6",
		'&' => "g4",
		'*' => "g2 v6",
		'_' => "g2 v6",
		'+' => "g4 v7",
		'`' => "g2 v6 arg",
		'8' => "g1",
		'0' => "g2 v6",
		'-' => "g4 v7",
		'^['=> "g7 mode",
		']' => "g3",
		'^]'=> "g3",
		';' => "g2",
		"'" => "g2 v6 arg",
		'<' => "g4 v7",
		'?' => "g4 argm v6",
		',' => "g2",

		'a' => "g1",
		'^a'=> "g1",
		'c' => 'g4 argm xcommentary',
		'd' => "g2 v6",
		'D' => "g2 v6",
		'e' => "g2",
		'E' => "g2",
		'f' => "g4 v6",
		'F' => "g4 v7",
		'g' => "g2",
		'^g'=> "g1 vim6",
		'h' => "g8 modev",
		'H' => "g8 modev",
		'^h'=> "g8 modev v6",
		'i' => "g6 undo modei",
		'I' => "g6 undo modei",
		'j' => "g2 v6",
		'J' => "g4",
		'k' => "g2 v6",
		'l' => 'g3 argm arg xlion',
		'L' => 'g3 argm arg xlion',
		'm' => "g2 v6",
		'n' => "g8 v7 modev",
		'N' => "g8 v7 modev",
		'o' => "g2",
		'p' => "g4 undo",
		'P' => "g4",
		'q' => "g4 argm",
		'Q' => "g7 v6",
		'r' => "g4 arg",
		'R' => "g6 undo modei",
		's' => "g1 v6",
		't' => "g3 v7",
		'T' => "g3 v7",
		'u' => "g4 argm v6", # XXX undo?
		'U' => "g4 undo argm v6",
		'v' => 'g8 modev',
		'V' => "g4",
		'w' => "g4 argm v7",
		'x' => "g4 v7 ext",
	}, # mode g

	Z => {
		lead => "Z",

		"\e"=> "g7 mode",
		'^['=> "=\e",

		'Q' => "g4 v6",
		'Z' => "g4",
	}, # mode Z

	z => {
		lead => "z",

		"\e"=> "g7 mode",

		'^' => "g3",
		'+' => "g3",
		'-' => "g3",
		'=' => "g4 v7",
		'.' => "g3",
		'^['=> "=\e",

		'a' => "g4 v6 folding",
		'A' => "g4 v6 folding",
		'b' => "g3",
		'c' => "g4 v6 folding",
		'C' => "g4 v6 folding",
		'd' => "g4 v6 folding",
		'D' => "g4 v6 folding",
		'e' => "g3",
		'E' => "g4 v6 folding",
		'f' => "g4 argm v6 folding",
		'F' => "g4 v6 folding",
		'g' => "g4 v7",
		'G' => "g4 v7",
		'h' => "g3",
		'H' => "g3",
		'i' => "g4 v6 folding",
		'j' => "g2 v6 folding",
		'k' => "g2 v6 folding",
		'l' => "g3",
		'L' => "g3",
		'^m'=> "g3",
		'm' => "g4 v6 folding",
		'M' => "g4 v6 folding",
		'n' => "g4 v6 folding",
		'N' => "g4 v6 folding",
		'o' => "g4 v6 folding",
		'O' => "g4 v6 folding",
		'r' => "g4 v6 folding",
		'R' => "g4 v6 folding",
		's' => "g3",
		't' => "g3",
		'u' => "g4 arg v7",
		'v' => "g4 v6 folding",
		'w' => "g4 v7",
		'W' => "g4 v7",
		'x' => "g4 v6 folding",
		'X' => "g4 v6 folding",
		'z' => "g3",
	}, # mode z

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

		"\e"=> "g7 mode",

		"`" => "g2 v6",
		'#' => "g2",
		'(' => "g2",
		'*' => "=[/",
		'/' => "g2",
		"'" => "=[` ^", # v6
		'{' => "g2",
		'[' => "g2",
		'^['=> "=\e",
		']' => "g2",

		'c' => "g2",
		'd' => "g1",
		'D' => "g4",
		'^d'=> "g3",
		'f' => "=gf",  # deprecated
		'i' => 'g1',
		'I' => 'g4',
		'^i'=> 'g3',
		'm' => "g2",
		'p' => "g4",
		'P' => "=[p",
		's' => "g3 v7",
		'S' => "g3 v7",
		'z' => "g2 v6 folding",

		'a' => "g3 xunimpaired",
		'A' => "g3 xunimpaired",
		'b' => "g3 xunimpaired",
		'B' => "g3 xunimpaired",
		'e' => "g4 xunimpaired",
		'l' => "g3 xunimpaired",
		'L' => "g3 xunimpaired",
		'^l'=> "g3 xunimpaired",
		'^l'=> "g3 xunimpaired",
		'f' => "g3 xunimpaired", # overrides native alias
		'n' => "g3 xunimpaired",
		'o' => "g9 arg xunimpaired",
		'q' => "g3 xunimpaired",
		'Q' => "g3 xunimpaired",
		'^q'=> "g3 xunimpaired",
		't' => "g3 xunimpaired",
		'T' => "g3 xunimpaired",
		'u' => "g4 argm xunimpaired",
		'x' => "g4 argm xunimpaired",
		'y' => "g4 argm xunimpaired",
		' ' => "g4 xunimpaired",
	}, # mode [

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

		"\e"=> "g7 mode",

		"`" => "g2 v6",
		'#' => "g2",
		')' => "g2",
		'*' => "=]/",
		"'" => "=]` ^", # v6
		'/' => "g2",
		'[' => "g2",
		'^['=> "=\e",
		']' => "g2",
		'}' => "g2",

		'c' => "g2",
		'd' => "g1",
		'D' => "g4",
		'^d'=> "g3",
		'f' => "=gf",  # deprecated
		'i' => "g1",
		'I' => "g4",
		'^i'=> "g3",
		'm' => "g2",
		'p' => "g4",
		'P' => "=[p",
		's' => "g3 v7",
		'S' => "g3 v7",
		'z' => "g2 v6 folding",

		'a' => "g3 xunimpaired",
		'A' => "g3 xunimpaired",
		'b' => "g3 xunimpaired",
		'B' => "g3 xunimpaired",
		'e' => "g4 xunimpaired",
		'l' => "g3 xunimpaired",
		'L' => "g3 xunimpaired",
		'^l'=> "g3 xunimpaired",
		'^l'=> "g3 xunimpaired",
		'f' => "g3 xunimpaired", # overrides native alias
		'n' => "g3 xunimpaired",
		'o' => "g9 arg xunimpaired",
		'q' => "g3 xunimpaired",
		'Q' => "g3 xunimpaired",
		'^q'=> "g3 xunimpaired",
		't' => "g3 xunimpaired",
		'T' => "g3 xunimpaired",
		'u' => "g4 argm xunimpaired",
		'x' => "g4 argm xunimpaired",
		'y' => "g4 argm xunimpaired",
		' ' => "g4 xunimpaired",
	}, # mode ]

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

		"\e"=> "g7 mode",

		'<' => "g3",
		'>' => "g3",
		'^' => "g4",
		'_' => "g3",
		'+' => "g3",
		'-' => "g3",
		'=' => "g3",
		'^['=> "=\e",
		']' => "g3",
		'}' => "g3",
		'|' => "g3",

		'b' => "g3",
		'c' => "g3",
		'^c'=> "g7 mode",
		'd' => "g3",
		'f' => "g4",
		'F' => "g4 v7",
		'g' => "g9 arg mode^wg",
		'h' => "g3",
		'H' => "g3",
		'i' => "g3",
		'j' => "g3",
		'J' => "g3",
		'k' => "g3",
		'K' => "g3",
		'l' => "g3",
		'L' => "g3",
		'n' => "g4",
		'o' => "g3",
		'p' => "g3",
		'P' => "g3",
		'q' => "g4",
		'r' => "g3",
		'R' => "g3",
		's' => "g3",
		'S' => "=^ws",
		't' => "g3",
		'T' => "g3 v7",
		'v' => "g3",
		'w' => "g3",
		'W' => "g3",
		'x' => "g3",
		'z' => "g3",
	}, # mode ^w

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

		"\e"=> "g7 mode",
		'^['=> "=\e",
		']' => "g3",
		'}' => "g3",
		'^]'=> "g3",
		'f' => "g4 v7",
		'F' => "g4 v7",
	}, # mode ^w g

	v => {
		"\e"=> "g7 mode",

		'!' => "g4",
		':' => "g7 modec",
		'<' => "g4",
		'=' => 'g4 undo',
		'>' => 'g4',
		'~' => "g4 v6",
		'^['=> "=\e",
		'^]'=> "g3",
		'^\\'=>'^\\',

		'a' => 'g9 modeva arg v6',
		'A' => 'g6 modei v6',
		'^a'=> 'g4 undo v8',
		'c' => 'g6 modei v6',
		'C' => 'g6 modei v6',
		'^c'=> "g7 mode",
		'd' => "g4 v6",
		'D' => "g4 v6",
		'g' => "g9 arg modevg",
		'^g'=> "g8",
		'i' => "g9 modeva arg v6",
		'I' => "g6 modei v6", # block
		'J' => "g4",
		'K' => 'g4',
		'o' => "g2",
		'O' => "g2",
		'^o'=> "g8",
		'p' => 'g4',
		'P' => 'g4',
		'r' => 'g4 arg',
		'R' => "=vS",  # "might change in future"
		's' => "=vc",
		'S' => 'g6 modei v6',
		'u' => "g4 v6",
		'U' => "g4 v6",
		'v' => "g8",
		'V' => "g8",
		'^v'=> "g8 v6",
		'x' => "=vd",
		'X' => "=vD",
		'^x'=> 'g4 undo v8',
		'y' => "g4",
		'Y' => "g4",

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

	vg => {
		lead => "g",

		"\e"=> "g8 modev",

		'^['=> "=\e",
		'?' => "g4 v6",
		'^a'=> 'g4 undo v8',
		'^g' => "g1 vim6",
		'c' => 'g4 xcommentary',
		'J' => 'g4 v6',
		'l' => 'g3 arg xlion',
		'L' => 'g3 arg xlion',
		'q' => "g4 v6",
		'v' => "=gv",
		'w' => 'g4 v7',
		'^x'=> 'g4 undo v8',
	}, # mode v g

	va => {
		"\e"=> "g8 modev",

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

		'b' => 'g2 v6',
		'B' => 'g2 v6',
		'p' => 'g2 v6',
		's' => 'g2 v6',
		't' => 'g2 v7',
		'w' => 'g2 v6',
		'W' => 'g2 v6',
	}, # mode v a

	#c => {
	#	desc => "command-line mode",
	#
	#	'^_' => "=i^_",
	#	'^^' => "=i^^",
	#	'^\\'=>'^\\',
	#	'^a' => "", #todo
	#	'^b' => "g3",
	#	'^c' => "=i^c",
	#	'^d' => "", #todo
	#	'^e' => "g3",
	#	'^h' => "=i^h",
	#	'^j' => "g4",
	#	'^k' => "=i^k",
	#	'^l' => "", #todo
	#	'^n' => "", #todo
	#	'^p' => "", #todo
	#	'^r' => "=i^r", # and then some...
	#	     ## ["g4 arg v6"],
	#	'^q' => "=^q",
	#	'^u' => "=i^u",
	#	'^v' => "=i^v",
	#	'^w' => "=i^w",
	#	'^y' => "g4",
	#}, # mode c

	i => {
		"\e" => "g7 mode",

		'^@' => "g4",
		'^^' => "g4 v6",
		'^['=> "=\e",
		'^]' => "g4 v6",
		'^_' => "g4 v6",
		'^\\'=>'^\\',

		'^a' => "g4 v6",
		'^b' => "no v6",
		'^c' => "g7 mode",
		'^d' => 'g4',
		'^e' => "g4 v6",
		'^f' => 'g4',
		'^g' => "g9 modei^g arg",
		'^h' => "g4",
		'^i' => "g4",
		'^j' => "g4",
		'^k' => 'g4 arg arg v6 linkdigraphs',
		'^l' => "g7 mode v6",  # insertmode only
		'^m' => "g4",
		'^n' => "g2 v6",
		'^o' => 'g4',
		'^p' => "g2 v6",
		'^q' => "=^q",  # or i^v
		'^r' => 'g4 arg v6',
		'^s' => "=^s",
		'^t' => "g4",
		'^u' => "g4",
		'^v' => 'g4 linkcharset',
		'^w' => "g4",
		'^x' => 'g9 arg modei^x v6',
		'^y' => "g4 v6",
		'^z' => "g1 v6",  # insertmode only
	}, # modei

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

		"\e"=> 'g6 modei',

		'k' => 'g2',
		'j' => 'g2',
		's' => 'g4 arg xsurround',
		'u' => 'g4',
		'U' => 'g4 v8',
		# other keys (even esc) are not recognized
	}, # mode i ^g

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

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

		'^['=> "=\e",
		'^]' => 'g4',
		'^d' => 'g4',
		'^e' => "g3",
		'^f' => 'g4',
		'^i' => 'g4',
		'^k' => 'g4',
		'^l' => 'g4',
		'^n' => 'g4',
		'^o' => 'g4 v7',
		'^p' => 'g4',
		'^s' => 'g4',
		 's' => "=i^x^s",
		'^t' => 'g4',
		'^u' => 'g4 v7',
		'^v' => 'g4',
		'^y' => "g3",
	}, # mode i ^x

	d => {
		lead => "d",

		"\e"=> "g7 mode",
		'^['=> "=\e",

		(map { $_ => 'g4' } @motions),
		(map { $_ => 'g4 arg' } qw( f F t T ` ' / ? )), # @motions with option
		(map { $_ => "=v$_" } qw( a i )), # motions from virtual
		(map { $_ => "=$_" } qw( g z [ ]  \\ ^\\ ^q ^s ^z )),

		'd'  => 'g4',
		'o'  => 'g5',
		'p'  => 'g5',
		's'  => 'g4 arg xsurround',

		'l'  => '=x',
		'h'  => '=X',
		'^h' => '=X',
		'^j' => '=dj',
		'^m' => '=dj',
		'^n' => '=dj',
		'+'  => '=dj',
		'^p' => '=dk',
		'-'  => '=dk',
		'$'  => '=D',
		'_'  => '=dd',
	}, # mode d

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