Exemple #1
0
    def validate_user_input(self):
        name = ''
        if len(self.user_input_parsers) == 2:
            # We have two parsers: one for the motion, one for the action.
            # Evaluate first the motion's.
            name = self.motion
            validator = self.user_input_parsers[-1]
        elif self.motion and INPUT_FOR_ACTIONS.get(self.action, (None, None))[0] == INPUT_AFTER_MOTION:
            assert len(self.user_input_parsers) == 1
            name = self.action
            validator = self.user_input_parsers[-1]
        elif self.motion and self.action:
            name = self.motion
            validator = self.user_input_parsers[-1]
        elif self.action:
            name = self.action
            validator = self.user_input_parsers[-1]
        elif self.motion:
            name = self.motion
            validator = self.user_input_parsers[-1]

        assert validator, "Validator must exist if expecting user input."
        if validator(self.user_input):
            if name == self.motion:
                self.settings.vi['user_motion_input'] = self.user_input
                self.settings.vi['user_input'] = None
            elif name == self.action:
                self.settings.vi['user_action_input'] = self.user_input
                self.settings.vi['user_input'] = None

            self.user_input_parsers.pop()
            if len(self.user_input_parsers) == 0:
                self.expecting_user_input = False
Exemple #2
0
    def validate_user_input(self):
        name = ''
        if len(self.user_input_parsers) == 2:
            # We have two parsers: one for the motion, one for the action.
            # Evaluate first the motion's.
            name = self.motion
            validator = self.user_input_parsers[-1]
        elif self.motion and INPUT_FOR_ACTIONS.get(
                self.action, (None, None))[0] == INPUT_AFTER_MOTION:
            assert len(self.user_input_parsers) == 1
            name = self.action
            validator = self.user_input_parsers[-1]
        elif self.motion and self.action:
            name = self.motion
            validator = self.user_input_parsers[-1]
        elif self.action:
            name = self.action
            validator = self.user_input_parsers[-1]
        elif self.motion:
            name = self.motion
            validator = self.user_input_parsers[-1]

        assert validator, "Validator must exist if expecting user input."
        if validator(self.user_input):
            if name == self.motion:
                self.settings.vi['user_motion_input'] = self.user_input
                self.settings.vi['user_input'] = None
            elif name == self.action:
                self.settings.vi['user_action_input'] = self.user_input
                self.settings.vi['user_input'] = None

            self.user_input_parsers.pop()
            if len(self.user_input_parsers) == 0:
                self.expecting_user_input = False
Exemple #3
0
    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()
Exemple #4
0
 def register_action_input_parser(self, ip):
     INPUT_FOR_ACTIONS.update(ip)
Exemple #5
0
 def register_action_input_parser(self, ip):
     INPUT_FOR_ACTIONS.update(ip)
Exemple #6
0
    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()