Пример #1
0
def registers_get_for_paste(view, register: str, mode: str) -> tuple:
    values = _get(view, register)
    linewise = _is_register_linewise(register)

    filtered = []

    if values:
        # Populate unnamed register with the text we're about to paste into (the
        # text we're about to replace), but only if there was something in
        # requested register (not empty), and we're in VISUAL mode.
        if is_visual_mode(mode):
            current_content = _get_selected_text(
                view, linewise=(mode == VISUAL_LINE))
            if current_content:
                _set(view,
                     _UNNAMED,
                     current_content,
                     linewise=(mode == VISUAL_LINE))

        for value in values:
            if mode == VISUAL:
                if linewise and value and value[0] != '\n':
                    value = '\n' + value

            if mode == VISUAL_LINE:
                # Pasting characterwise content in visual line mode needs an
                # extra newline to account for visual line eol newline.
                if not linewise:
                    value += '\n'

            filtered.append(value)

    return filtered, linewise
Пример #2
0
def extract_word(view, mode, sel):
    if is_visual_mode(mode):
        word = view.substr(sel)
    else:
        word = view.substr(view.word(sel))

    return word
Пример #3
0
    def get_for_big_p(self, register, mode):
        if not register:
            register = _UNNAMED

        as_str = ''
        values = self._get(register)
        linewise = _is_register_linewise(register)

        if values:
            # Populate unnamed register with the text we're about to paste into
            # (the text we're about to replace), but only if there was something
            # in requested register (not empty), and we're in VISUAL mode.
            if is_visual_mode(mode):
                current_content = self._get_selected_text(linewise=(mode == VISUAL_LINE))
                if current_content:
                    self._set(_UNNAMED, current_content, linewise=(mode == VISUAL_LINE))

            # If register content is from a linewise operation, and in VISUAL
            # mode, and doesn't begin with newline, then a newline is prefixed.
            as_str = ''.join(values)
            if as_str and linewise and is_visual_mode(mode) and as_str[0] != '\n':
                as_str = '\n' + as_str

        return as_str, linewise
Пример #4
0
    def get_for_p(self, register, mode):
        if not register:
            register = _UNNAMED

        values = self._get(register)
        linewise = _is_register_linewise(register)

        # Populate unnamed register with the text we're about to paste into (the
        # text we're about to replace), but only if there was something in
        # requested register (not empty), and we're in VISUAL mode.
        if values and is_visual_mode(mode):
            content = self._get_selected_text(linewise=(mode == VISUAL_LINE))
            if content:
                self._set(_UNNAMED, content, linewise=(mode == VISUAL_LINE))

        return values, linewise
Пример #5
0
    def set_command(self, command):
        # type: (ViCommandDefBase) -> None
        # Set the current command.
        #
        # Args:
        #   command (ViCommandDefBase): A command definition.
        #
        # Raises:
        #   ValueError: If too many motions.
        #   ValueError: If too many actions.
        #   ValueError: Unexpected command type.
        assert isinstance(
            command,
            ViCommandDefBase), 'ViCommandDefBase expected, got {}'.format(
                type(command))  # FIXME # noqa: E501

        is_runnable = self.runnable()

        if isinstance(command, ViMotionDef):
            if is_runnable:
                # We already have a motion, so this looks like an error.
                raise ValueError('too many motions')

            self.motion = command

            if self.mode == OPERATOR_PENDING:
                self.mode = NORMAL

            self._set_parsers(command)

        elif isinstance(command, ViOperatorDef):
            if is_runnable:
                # We already have an action, so this looks like an error.
                raise ValueError('too many actions')

            self.action = command

            if (self.action.motion_required and not is_visual_mode(self.mode)):
                self.mode = OPERATOR_PENDING

            self._set_parsers(command)

        else:
            raise ValueError('unexpected command type')
Пример #6
0
    def set_command(self, command):
        # type: (ViCommandDefBase) -> None
        # Set the current command.
        #
        # Args:
        #   command (ViCommandDefBase): A command definition.
        #
        # Raises:
        #   ValueError: If too many motions.
        #   ValueError: If too many actions.
        #   ValueError: Unexpected command type.
        assert isinstance(
            command,
            ViCommandDefBase), 'ViCommandDefBase expected, got {}'.format(
                type(command))

        is_runnable = self.runnable()

        if isinstance(command, ViMotionDef):
            if is_runnable:
                raise ValueError('too many motions')

            self.motion = command

            if self.mode == OPERATOR_PENDING:
                self.mode = NORMAL

        elif isinstance(command, ViOperatorDef):
            if is_runnable:
                raise ValueError('too many actions')

            self.action = command

            if command.motion_required and not is_visual_mode(self.mode):
                self.mode = OPERATOR_PENDING

        else:
            raise ValueError('unexpected command type')

        if not self.non_interactive:
            if command.accept_input and command.input_parser and command.input_parser.is_type_via_panel(
            ):
                command.input_parser.run_command()
Пример #7
0
    def scroll_into_view(self):
        # type: () -> None
        view = active_window().active_view()
        if view:
            # Show the *last* cursor on screen. There is currently no way to
            # identify the "active" cursor of a multiple cursor selection.
            sel = view.sel()[-1]

            target_pt = sel.b

            # In VISUAL mode we need to make sure that any newline at the end of
            # the selection is NOT included in the target, because otherwise an
            # extra line after the target line will also be scrolled into view.
            if is_visual_mode(self.mode):
                if sel.b > sel.a:
                    if view.substr(sel.b - 1) == '\n':
                        target_pt = max(0, target_pt - 1)
                        # Use the start point of the target line to avoid
                        # horizontal scrolling. For example, this can happen in
                        # VISUAL LINE mode when the EOL is off-screen.
                        target_pt = max(0, view.line(target_pt).a)

            view.show(target_pt, False)
Пример #8
0
def evaluate_state(view) -> None:
    _log.debug('evaluating...')
    if not is_runnable(view):
        _log.debug('not runnable!')
        return

    action = get_action(view)
    motion = get_motion(view)

    if action and motion:

        # Evaluate action with motion: runs the action with the motion as an
        # argument. The motion's mode is set to INTERNAL_NORMAL and is run
        # by the action internally to make the selection it operates on. For
        # example the motion commands can be used after an operator command,
        # to have the command operate on the text that was moved over.

        action_cmd = action.translate(view)
        motion_cmd = motion.translate(view)

        _log.debug('action: %s', action_cmd)
        _log.debug('motion: %s', motion_cmd)

        set_mode(view, INTERNAL_NORMAL)

        if 'mode' in action_cmd['action_args']:
            action_cmd['action_args']['mode'] = INTERNAL_NORMAL

        if 'mode' in motion_cmd['motion_args']:
            motion_cmd['motion_args']['mode'] = INTERNAL_NORMAL

        args = action_cmd['action_args']

        args['count'] = 1

        # Let the action run the motion within its edit object so that we
        # don't need to worry about grouping edits to the buffer.
        args['motion'] = motion_cmd

        if get_glue_until_normal_mode(
                view) and not is_processing_notation(view):
            run_window_command('mark_undo_groups_for_gluing')

        add_macro_step(view, action_cmd['action'], args)

        run_window_command(action_cmd['action'], args)

        if is_interactive(view) and get_action(view).repeatable:
            set_repeat_data(
                view, ('vi', str(get_sequence(view)), get_mode(view), None))

        reset_command_data(view)

        return  # Nothing more to do.

    if motion:

        # Evaluate motion: Run it.

        motion_cmd = motion.translate(view)

        _log.debug('motion: %s', motion_cmd)

        add_macro_step(view, motion_cmd['motion'], motion_cmd['motion_args'])

        run_motion(view, motion_cmd)

    if action:

        # Evaluate action. Run it.

        action_cmd = action.translate(view)

        _log.debug('action: %s', action_cmd)

        if get_mode(view) == NORMAL:
            set_mode(view, INTERNAL_NORMAL)

            if 'mode' in action_cmd['action_args']:
                action_cmd['action_args']['mode'] = INTERNAL_NORMAL

        elif is_visual_mode(get_mode(view)):
            # Special-case exclusion: saving the previous selection would
            # overwrite the previous selection needed e.g. gv in a VISUAL
            # mode needs to expand or contract to previous selection.
            if action_cmd['action'] != '_vi_gv':
                save_previous_selection(view, get_mode(view))

        # Some commands, like 'i' or 'a', open a series of edits that need
        # to be grouped together unless we are gluing a larger sequence
        # through _nv_process_notation. For example, aFOOBAR<Esc> should be
        # grouped atomically, but not inside a sequence like
        # iXXX<Esc>llaYYY<Esc>, where we want to group the whole sequence
        # instead.
        if get_glue_until_normal_mode(
                view) and not is_processing_notation(view):
            run_window_command('mark_undo_groups_for_gluing')

        sequence = get_sequence(view)
        visual_repeat_data = get_visual_repeat_data(view, get_mode(view))
        action = get_action(view)

        add_macro_step(view, action_cmd['action'], action_cmd['action_args'])

        run_action(active_window(), action_cmd)

        if not (is_processing_notation(view)
                and get_glue_until_normal_mode(view)) and action.repeatable:
            set_repeat_data(
                view, ('vi', sequence, get_mode(view), visual_repeat_data))

    if get_mode(view) == INTERNAL_NORMAL:
        set_mode(view, NORMAL)

    reset_command_data(view)
Пример #9
0
    def eval(self):
        # type: () -> None
        # Run data as a command if possible.
        if not self.runnable():
            return

        if self.action and self.motion:
            action_cmd = self.action.translate(self)
            motion_cmd = self.motion.translate(self)

            _log.debug('changing to INTERNAL_NORMAL...')
            self.mode = INTERNAL_NORMAL

            # TODO Make motions and actions require a 'mode' param.
            if 'mode' in action_cmd['action_args']:
                _log.debug('action has a mode, changing to INTERNAL_NORMAL...')
                action_cmd['action_args']['mode'] = INTERNAL_NORMAL

            if 'mode' in motion_cmd['motion_args']:
                _log.debug('motion has a mode, changing to INTERNAL_NORMAL...')
                motion_cmd['motion_args']['mode'] = INTERNAL_NORMAL

            args = action_cmd['action_args']
            args['count'] = 1
            # Let the action run the motion within its edit object so that we
            # don't need to worry about grouping edits to the buffer.
            args['motion'] = motion_cmd

            if self.glue_until_normal_mode and not self.processing_notation:
                # Tell Sublime Text that it should group all the next edits
                # until we enter normal mode again.
                run_window_command('mark_undo_groups_for_gluing')

            self.add_macro_step(action_cmd['action'], args)
            run_window_command(action_cmd['action'], args)

            if not self.non_interactive:
                if self.action.repeatable:
                    _log.debug('action is repeatable, setting repeat data...')
                    self.repeat_data = ('vi', str(self.sequence), self.mode,
                                        None)

            self.reset_command_data()

            return

        if self.motion:
            motion_cmd = self.motion.translate(self)

            self.add_macro_step(motion_cmd['motion'],
                                motion_cmd['motion_args'])

            # All motions are subclasses of ViTextCommandBase, so it's safe to
            # run the command via the current view.
            run_view_command(self.view, motion_cmd['motion'],
                             motion_cmd['motion_args'])

        if self.action:
            action_cmd = self.action.translate(self)

            if self.mode == NORMAL:
                _log.debug('is NORMAL, changing to INTERNAL_NORMAL...')
                self.mode = INTERNAL_NORMAL

                if 'mode' in action_cmd['action_args']:
                    _log.debug(
                        'action has a mode, changing to INTERNAL_NORMAL...')
                    action_cmd['action_args']['mode'] = INTERNAL_NORMAL

            elif is_visual_mode(self.mode):
                # Special-case exclusion: saving the previous selection would
                # overwrite the previous selection needed e.g. gv in a VISUAL
                # mode needs to expand or contract to previous selection.
                if action_cmd['action'] != '_vi_gv':
                    _log.debug('is VISUAL, saving selection...')
                    save_previous_selection(self.view, self.mode)

            # Some commands, like 'i' or 'a', open a series of edits that need
            # to be grouped together unless we are gluing a larger sequence
            # through _nv_process_notation. For example, aFOOBAR<Esc> should be
            # grouped atomically, but not inside a sequence like
            # iXXX<Esc>llaYYY<Esc>, where we want to group the whole sequence
            # instead.
            if self.glue_until_normal_mode and not self.processing_notation:
                # Tell Sublime Text that it should group all the next edits
                # until we enter normal mode again.
                run_window_command('mark_undo_groups_for_gluing')

            seq = self.sequence
            visual_repeat_data = self.get_visual_repeat_data()
            action = self.action

            self.add_macro_step(action_cmd['action'],
                                action_cmd['action_args'])
            run_window_command(action_cmd['action'], action_cmd['action_args'])

            if not (self.processing_notation and self.glue_until_normal_mode):
                if action.repeatable:
                    _log.debug('action is repeatable, setting repeat data...')
                    self.repeat_data = ('vi', seq, self.mode,
                                        visual_repeat_data)

        if self.mode == INTERNAL_NORMAL:
            _log.debug('is INTERNAL_NORMAL, changing to NORMAL...')
            self.enter_normal_mode()

        self.reset_command_data()