Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vimprint - A Vim Keystroke Parser

Vimprint - A Vim Keystroke Parser

nelstrom

May 28, 2013
Tweet

More Decks by nelstrom

Other Decks in Technology

Transcript

  1. class Vimprint < Parslet::Parser rule(:start) { match('[iIaAoOsS]').as(:switch) } rule(:typing) {

    match('[^\e]').repeat.as(:typing) } rule(:terminate) { match('\e').as(:escape) } rule(:insertion) { start >> typing >> terminate } root(:insertion) end
  2. gv major stumbling block: switch from Normal mode to Visual

    mode and select the last selected text
  3. Ragel state machines can not only recognize byte sequences as

    regular expression machines do, but can also execute code at arbitrary points in the recognition of a regular language.
  4. %%{ machine vim_print; action return { fret; } action push_insert_mode

    { fcall insert_mode; } escape = 27; input = (any - escape); motion = [hjklbwe0]; switch = [iIaAsSoO]; insert_mode := ( input* escape @return ); normal_mode := ( motion | switch @push_insert_mode )*; }%%
  5. 2 IN 1 insert_mode normal_mode '0', 'b', 'e', 'h', 'j'..'l',

    'w' 'A', 'I', 'O', 'S', 'a', 'i', 'o', 's' / push_insert_mode 3 27 / return DEF
  6. action H { @head = p } action T {

    @tail = p } action EmitMotion { @events << {motion: strokes} } action EmitSwitch { @events << {switch: strokes} } action EmitInput { @events << {input: strokes} } action EmitEscape { @events << {escape: '<Esc>'} } escape = 27 >H@T @EmitEscape; input = (any - escape) >H@T @EmitInput; motion = [hjklbwe0] >H@T @EmitMotion; switch = [iIaAsSoO] >H@T @EmitSwitch;
  7. class VimParser attr_accessor :head, :tail, :data def initialize(listener) @events =

    listener %% write data; end def process(input) @data = input.unpack("c*") eof = @data.length stack = [] %% write init; %% write exec; end def strokes @data[@head..@tail].pack('c*') end end
  8. VimParser.new(recorder = []).process("helihello\e") puts recorder {:motion=>"h"} {:motion=>"e"} {:motion=>"l"} {:switch=>"i"} {:input=>"h"}

    {:input=>"e"} {:input=>"l"} {:input=>"l"} {:input=>"o"} {:escape=>"<Esc>"} https://gist.github.com/nelstrom/5663083