
var state_display = $("#state-display");
var helps_display = $("#helps-display");

var commandListEN = [
  { keys:['w'],     type:'motion',   help:'a word' },
  { keys:['d'],     type:'operator', help:'Delete' },
  { keys:['<Esc>'], type:'action',   help:'Exit to normal mode' },
  { keys:['x'],     type:'action',   help:'Delete a character' },
];

function VimFSM() {
  var fsm = StateMachine.create({
    initial:'_none',
    events: [
      { name:'motion',   from:'_none',     to:'_motion'   },
      { name:'motion',   from:'_operator', to:'_motion'   },
      { name:'operator', from:'_none',     to:'_operator' },
      { name:'action',   from:'_none',     to:'_action'   },
      { name:'done',     from:'*',         to:'_none'     },
  ]});

  fsm.onenterstate = function(e, from, to) {
    state_display.html(from + " -> " + to);
  };

  fsm.on_motion = function(e, from, to, command) {
    helps_display.append("<br>"+command.help);
  };
  fsm.onleave_motion = function(e, from, to) {
    setTimeout(function() {
      helps_display.html("");
      fsm.transition();
    }, 1000);
    return StateMachine.ASYNC;
  };

  fsm.on_operator = function(e, from, to, command) {
    helps_display.append("<br>"+command.help);
  };

  fsm.on_action = function(e, from, to, command) {
    helps_display.append("<br>"+command.help);
  };
  fsm.onleave_action = function(e, from, to) {
    setTimeout(function() {
      helps_display.html("");
      fsm.transition();
    }, 1000);
    return StateMachine.ASYNC;
  };
  return fsm;
}

function CommandHelper (commandList) {
  this.commandList = commandList;
  this.fsm = VimFSM();
}
CommandHelper.prototype = {
  matchCommand: function(key) {

    var fsm = this.fsm;
    var commandList = this.commandList;
    var matchList = [];

    for (var i=0; i<commandList.length; i++) {
      command = commandList[i];
      if (command.keys[0] == key && fsm.can(command.type)) {
        matchList.push(command);
      }
    }

    var match;
    if (matchList.length == 0) {
      throw ("No match found:"+key)
    }
    else if (matchList.length == 1) {
      match = matchList[0];
      fsm[match.type](match);
    }
    else
      throw ("More than one commands match:"+key)
    return match;
  },
  done: function() {
    this.fsm.done();
  }
}

var commandHelper = new CommandHelper(commandListEN);


@@ -835,24 +835,101 @@
  + to);%0A  %7D;
+%0A  fsm.onleave_none = function(e, from, to) %7B%0A    helps_display.html(%22%22);%0A  %7D
 %0A%0A  fsm.on_m
@@ -1024,187 +1024,8 @@
   %7D;
-%0A  fsm.onleave_motion = function(e, from, to) %7B%0A    setTimeout(function() %7B%0A      helps_display.html(%22%22);%0A      fsm.transition();%0A    %7D, 1000);%0A    return StateMachine.ASYNC;%0A  %7D;
 %0A%0A  
@@ -1235,187 +1235,8 @@
  %7D;%0A
-  fsm.onleave_action = function(e, from, to) %7B%0A    setTimeout(function() %7B%0A      helps_display.html(%22%22);%0A      fsm.transition();%0A    %7D, 1000);%0A    return StateMachine.ASYNC;%0A  %7D;%0A
   re

Remove async state transition.