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

Vimprint - A Vim Keystroke Parser

Vimprint - A Vim Keystroke Parser

802afd5856ed0054d7d1851ea21cbabe?s=128

nelstrom

May 28, 2013
Tweet

Transcript

  1. VIMPRINT A VIM KEYSTROKE PARSER 28th May, 2013 Drew Neil

    @nelstrom
  2. VIMPRINT should... visualize keystrokes in realtime

  3. VIMPRINT should... understand all built-in commands

  4. VIMPRINT should... be extensible

  5. VimSpeak Turns spoken English into keystrokes https://github.com/AshleyF/VimSpeak

  6. None
  7. VimSplain Turns keystrokes into plain English https://github.com/pafcu/Vimsplain

  8. Vimulator Turns live keystrokes into plain English https://github.com/thoughtbot/vimulator

  9. None
  10. VimGolf Logs real keystrokes https://github.com/igrigorik/vimgolf

  11. None
  12. vim -w keystrokes are BUFFERED

  13. None
  14. Parslet 1st attempt at parsing Vim keystrokes

  15. None
  16. 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
  17. gv major stumbling block: switch from Normal mode to Visual

    mode and select the last selected text
  18. Ragel 2nd attempt at parsing Vim keystrokes

  19. 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.
  20. %%{ 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 )*; }%%
  21. 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
  22. 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;
  23. 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
  24. 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
  25. FATAL FLAWS with parsing keystrokes

  26. FATAL FLAWS no timestamps <leader>{...}

  27. FATAL FLAWS no document context :s/{pattern}/{string}/c

  28. FATAL FLAWS no filetype detection

  29. HALP! https://github.com/nelstrom/vimprint Vimprint Realtime Vim keystroke visualizer