Пример #1
0
def one_char(in_):
    # Any input (character) satisfies this parser.
    #
    # Args:
    #   in_ (str):
    #
    # Returns
    #   bool: True if in_ is one character in length, False otherwise.
    return len(translate_char(in_)) == 1
Пример #2
0
    def run(self, keys, repeat_count=None, check_user_mappings=True):
        state = self.state
        _log.debug('process notation keys \'%s\', mode \'%s\'', keys,
                   state.mode)
        initial_mode = state.mode
        # Disable interactive prompts. For example, to supress interactive
        # input collection in /foo<CR>.
        state.non_interactive = True

        # First, run any motions coming before the first action. We don't keep
        # these in the undo stack, but they will still be repeated via '.'.
        # This ensures that undoing will leave the caret where the  first
        # editing action started. For example, 'lldl' would skip 'll' in the
        # undo history, but store the full sequence for '.' to use.
        leading_motions = ''
        for key in KeySequenceTokenizer(keys).iter_tokenize():
            self.window.run_command(
                'press_key', {
                    'key': key,
                    'do_eval': False,
                    'repeat_count': repeat_count,
                    'check_user_mappings': check_user_mappings
                })
            if state.action:
                # The last key press has caused an action to be primed. That
                # means there are no more leading motions. Break out of here.
                _log.debug('[process_notation] first action found in \'%s\'',
                           state.sequence)
                state.reset_command_data()
                if state.mode == OPERATOR_PENDING:
                    state.mode = NORMAL

                break

            elif state.runnable():
                # Run any primed motion.
                leading_motions += state.sequence
                state.eval()
                state.reset_command_data()

            else:
                # XXX: When do we reach here?
                state.eval()

        if state.must_collect_input:
            # State is requesting more input, so this is the last command in
            # the sequence and it needs more input.
            self.collect_input()
            return

        # Strip the already run commands
        if leading_motions:
            if ((len(leading_motions) == len(keys))
                    and (not state.must_collect_input)):
                state.non_interactive = False
                return

            _log.debug(
                '[process_notation] original seq/leading motions: %s/%s', keys,
                leading_motions)
            keys = keys[len(leading_motions):]
            _log.debug('[process_notation] seq stripped to \'%s\'', keys)

        if not (state.motion and not state.action):
            with gluing_undo_groups(self.window.active_view(), state):
                try:
                    for key in KeySequenceTokenizer(keys).iter_tokenize():
                        if key.lower() == key_names.ESC:
                            # XXX: We should pass a mode here?
                            self.window.run_command('_enter_normal_mode')
                            continue

                        elif state.mode not in (INSERT, REPLACE):
                            self.window.run_command(
                                'press_key', {
                                    'key': key,
                                    'repeat_count': repeat_count,
                                    'check_user_mappings': check_user_mappings
                                })
                        else:
                            self.window.run_command(
                                'insert', {'characters': translate_char(key)})

                    if not state.must_collect_input:
                        return

                finally:
                    state.non_interactive = False
                    # Ensure we set the full command for '.' to use, but don't
                    # store '.' alone.
                    if (leading_motions + keys) not in ('.', 'u', '<C-r>'):
                        state.repeat_data = ('vi', (leading_motions + keys),
                                             initial_mode, None)

        # We'll reach this point if we have a command that requests input
        # whose input parser isn't satistied. For example, `/foo`. Note that
        # `/foo<CR>`, on the contrary, would have satisfied the parser.
        _log.debug(
            '[process_notation] unsatisfied parser action=\'%s\', motion=\'%s\'',
            state.action, state.motion)
        if (state.action and state.motion):
            # We have a parser an a motion that can collect data. Collect data
            # interactively.
            motion_data = state.motion.translate(state) or None

            if motion_data is None:
                state.reset_command_data()

                return ui_blink()

            motion_data['motion_args']['default'] = state.motion._inp

            self.window.run_command(motion_data['motion'],
                                    motion_data['motion_args'])

            return

        self.collect_input()
Пример #3
0
 def accept(self, key):
     self.inp += translate_char(key)
     return True