def motion(self, name): if self.action in INCOMPLETE_ACTIONS: # The .action should handle this. self.action = name return # HACK: Translate vi_enter to \n if we're expecting user input. # This enables r\n, for instance. # XXX: I don't understand why the enter key is captured as a motion in this case, though; # the catch-all key binding for user input should have intercepted it. if self.expecting_user_input and name == 'vi_enter': self.view.run_command('collect_user_input', {'character': '\n'}) return # Check for digraphs like gg in dgg. stored_motion = self.motion if stored_motion and name: name, type_ = digraphs.get((stored_motion, name), (None, None)) if type_ != DIGRAPH_MOTION: # We know there's an action because we only check for digraphs when there is one. self.cancel_action = True return motion_name = MOTION_TRANSLATION_TABLE.get((self.action, name), name) input_type, input_parser = INPUT_FOR_MOTIONS.get(motion_name, (None, None)) if input_type == INPUT_IMMEDIATE: self.expecting_user_input = True self.user_input_parsers.append(input_parser) if not input_type and self.user_input_parsers: self.expecting_user_input = True self.settings.vi['motion'] = motion_name self.display_partial_command()
def motion(self, name): if self.action in INCOMPLETE_ACTIONS: # The .action should handle this. self.action = name return # HACK: Translate vi_enter to \n if we're expecting user input. # This enables r\n, for instance. # XXX: I don't understand why the enter key is captured as a motion in this case, though; # the catch-all key binding for user input should have intercepted it. if self.expecting_user_input and name == 'vi_enter': self.view.run_command('collect_user_input', {'character': '\n'}) return # Check for digraphs like gg in dgg. stored_motion = self.motion if stored_motion and name: name, type_ = digraphs.get((stored_motion, name), (None, None)) if type_ != DIGRAPH_MOTION: # We know there's an action because we only check for digraphs when there is one. self.cancel_action = True return motion_name = MOTION_TRANSLATION_TABLE.get((self.action, name), name) input_type, input_parser = INPUT_FOR_MOTIONS.get( motion_name, (None, None)) if input_type == INPUT_IMMEDIATE: self.expecting_user_input = True self.user_input_parsers.append(input_parser) if not input_type and self.user_input_parsers: self.expecting_user_input = True self.settings.vi['motion'] = motion_name self.display_partial_command()
def action(self, action): stored_action = self.settings.vi['action'] target = 'action' # Sometimes we'll receive an incomplete command that may be an action or a motion, like g # or dg, both leading up to gg and dgg, respectively. When there's already a complete # action, though, we already know it must be a motion (as in dg and dgg). # Similarly, if there is an action and a motion, the motion must handle the new name just # received. This would be the case when we have dg and we receive another 'g' (or # anything else, for that matter). if (self.action and INCOMPLETE_ACTIONS.get(action) == ACTION_OR_MOTION or self.motion): # The .motion should handle this. self.motion = action return # Check for digraphs like cc, dd, yy. final_action = action if stored_action and action: final_action, type_ = digraphs.get((stored_action, action), ('', None)) # We didn't find a built-in action; let's try with the plugins. if final_action == '': final_action, type_ = plugin_manager.composite_commands.get((stored_action, action), ('', None)) # Check for multigraphs like g~g~, g~~. # This sequence would get us here: # * vi_g_action # * vi_tilde # * vi_g_action => vi_g_tilde, STASH # * vi_tilde => vi_g_tilde_vi_g_tilde, DIGRAPH_ACTION if self.stashed_action: final_action, type_ = digraphs.get((self.stashed_action, final_action), ('', None)) # Some motion digraphs are captured as actions, but need to be stored as motions # instead so that the vi command is evaluated correctly. # Ex: gg (vi_g_action, vi_gg) if type_ == DIGRAPH_MOTION: target = 'motion' # TODO: Encapsulate this in a method. input_type, input_parser = INPUT_FOR_MOTIONS.get(final_action, (None, None)) if input_parser: self.user_input_parsers.append(input_parser) if input_type == INPUT_IMMEDIATE: self.expecting_user_input = True self.settings.vi['action'] = None # We are still in an intermediary step, so do some bookkeeping... elif type_ == STASH: # In this case we need to overwrite the current action differently. self.stashed_action = final_action self.settings.vi['action'] = action self.display_partial_command() return # Avoid recursion. The .reset() method will try to set this property to None, not ''. if final_action == '': # The chord is invalid, so notify that we need to cancel the command in .eval(). self.cancel_action = True return if target == 'action': input_type, input_parser = INPUT_FOR_ACTIONS.get(final_action, (None, None)) if input_parser: self.user_input_parsers.append(input_parser) if input_type == INPUT_IMMEDIATE: self.expecting_user_input = True self.settings.vi[target] = final_action self.display_partial_command()
def action(self, action): stored_action = self.settings.vi['action'] target = 'action' # Sometimes we'll receive an incomplete command that may be an action or a motion, like g # or dg, both leading up to gg and dgg, respectively. When there's already a complete # action, though, we already know it must be a motion (as in dg and dgg). # Similarly, if there is an action and a motion, the motion must handle the new name just # received. This would be the case when we have dg and we receive another 'g' (or # anything else, for that matter). if (self.action and INCOMPLETE_ACTIONS.get(action) == ACTION_OR_MOTION or self.motion): # The .motion should handle this. self.motion = action return # Check for digraphs like cc, dd, yy. final_action = action if stored_action and action: final_action, type_ = digraphs.get((stored_action, action), ('', None)) # We didn't find a built-in action; let's try with the plugins. if final_action == '': final_action, type_ = plugin_manager.composite_commands.get( (stored_action, action), ('', None)) # Check for multigraphs like g~g~, g~~. # This sequence would get us here: # * vi_g_action # * vi_tilde # * vi_g_action => vi_g_tilde, STASH # * vi_tilde => vi_g_tilde_vi_g_tilde, DIGRAPH_ACTION if self.stashed_action: final_action, type_ = digraphs.get( (self.stashed_action, final_action), ('', None)) # Some motion digraphs are captured as actions, but need to be stored as motions # instead so that the vi command is evaluated correctly. # Ex: gg (vi_g_action, vi_gg) if type_ == DIGRAPH_MOTION: target = 'motion' # TODO: Encapsulate this in a method. input_type, input_parser = INPUT_FOR_MOTIONS.get( final_action, (None, None)) if input_parser: self.user_input_parsers.append(input_parser) if input_type == INPUT_IMMEDIATE: self.expecting_user_input = True self.settings.vi['action'] = None # We are still in an intermediary step, so do some bookkeeping... elif type_ == STASH: # In this case we need to overwrite the current action differently. self.stashed_action = final_action self.settings.vi['action'] = action self.display_partial_command() return # Avoid recursion. The .reset() method will try to set this property to None, not ''. if final_action == '': # The chord is invalid, so notify that we need to cancel the command in .eval(). self.cancel_action = True return if target == 'action': input_type, input_parser = INPUT_FOR_ACTIONS.get( final_action, (None, None)) if input_parser: self.user_input_parsers.append(input_parser) if input_type == INPUT_IMMEDIATE: self.expecting_user_input = True self.settings.vi[target] = final_action self.display_partial_command()