Ejemplo n.º 1
0
    def on_post_save(self, view):
        if view.settings().get('vintageous_modeline', False):
            do_modeline(view)

        # Ensure the carets are within valid bounds. For instance, this is a
        # concern when 'trim_trailing_white_space_on_save' is set to true.
        view.run_command('_nv_fix_st_eol_caret', {'mode': State(view).mode})
Ejemplo n.º 2
0
    def on_text_command(self, view, command, args):
        if command == 'drag_select':
            state = State(view)

            if state.mode in (VISUAL, VISUAL_LINE, VISUAL_BLOCK):
                if (args.get('extend') or (args.get('by') == 'words') or args.get('additive')):
                    return
                elif args.get('by') == 'lines':
                    return ('sequence', {
                        'commands': [
                            ['drag_select', args],
                            ['_enter_visual_line_mode', {'mode': state.mode}]
                        ]
                    })
                elif not args.get('extend'):
                    return ('sequence', {
                        'commands': [
                            ['drag_select', args],
                            ['_enter_normal_mode', {'mode': state.mode}]
                        ]
                    })

            elif state.mode == NORMAL:
                # TODO Dragging the mouse does not seem to fire a different
                # event than simply clicking. This makes it hard to update the
                # xpos.
                # See https://github.com/SublimeTextIssues/Core/issues/2117.
                if args.get('extend') or (args.get('by') == 'words'):
                    return ('sequence', {
                        'commands': [
                            ['drag_select', args],
                            ['_enter_visual_mode', {'mode': state.mode}]
                        ]
                    })
Ejemplo n.º 3
0
    def on_post_save(self, view):
        if get_option(view, 'modeline'):
            do_modeline(view)

        # Ensure the carets are within valid bounds. For instance, this is a
        # concern when 'trim_trailing_white_space_on_save' is set to true.
        # TODO Kill State dependency
        fix_eol_cursor(view, State(view).mode)
Ejemplo n.º 4
0
    def on_post_save(self, view):
        if view.settings().get('vintageous_modeline', False):
            do_modeline(view)

        # Ensure the carets are within valid bounds. For instance, this is a
        # concern when 'trim_trailing_white_space_on_save' is set to true.
        # TODO Kill State dependency
        fix_eol_cursor(view, State(view).mode)
Ejemplo n.º 5
0
    def run(self, edit):
        if self.view.score_selector(0, 'text.excmdline') == 0:
            return

        state = State(self.view)
        _nv_fs_completion.frozen_dir = (_nv_fs_completion.frozen_dir
                                        or (state.settings.vi['_cmdline_cd'] +
                                            '/'))

        cmd, prefix, only_dirs = parse_for_fs(
            self.view.substr(self.view.line(0)))
        if not cmd:
            return

        if not (_nv_fs_completion.prefix
                or _nv_fs_completion.items) and prefix:
            _nv_fs_completion.prefix = prefix
            _nv_fs_completion.is_stale = True

        if prefix == '..':
            _nv_fs_completion.prefix = '../'
            self.view.run_command('_nv_write_fs_completion', {
                'cmd': cmd,
                'completion': '../'
            })

        if prefix == '~':
            path = os.path.expanduser(prefix) + '/'
            _nv_fs_completion.prefix = path
            self.view.run_command('_nv_write_fs_completion', {
                'cmd': cmd,
                'completion': path
            })

            return

        if (not _nv_fs_completion.items) or _nv_fs_completion.is_stale:
            _nv_fs_completion.items = iter_paths(
                from_dir=_nv_fs_completion.frozen_dir,
                prefix=_nv_fs_completion.prefix,
                only_dirs=only_dirs)
            _nv_fs_completion.is_stale = False

        try:
            self.view.run_command('_nv_write_fs_completion', {
                'cmd': cmd,
                'completion': next(_nv_fs_completion.items)
            })
        except StopIteration:
            _nv_fs_completion.items = iter_paths(
                prefix=_nv_fs_completion.prefix,
                from_dir=_nv_fs_completion.frozen_dir,
                only_dirs=only_dirs)

            self.view.run_command('_nv_write_fs_completion', {
                'cmd': cmd,
                'completion': _nv_fs_completion.prefix
            })
Ejemplo n.º 6
0
 def on_post_text_command(self, view, command, args):
     # This fixes issues where the xpos is not updated after a mouse click
     # moves the cursor position. These issues look like they could be
     # compounded by Sublime Text issues (see on_post_save() and the
     # fix_eol_cursor utility). The xpos only needs to be updated on single
     # mouse click. See https://github.com/SublimeTextIssues/Core/issues/2117.
     if command == 'drag_select':
         if set(args) == {'event'}:
             if set(args['event']) == {'x', 'y', 'button'}:
                 if args['event']['button'] == 1:
                     state = State(view)
                     state.update_xpos(force=True)
Ejemplo n.º 7
0
    def on_text_command(self, view, command, args):
        # Called when a text command is issued.
        #
        # The listener may return a (command, arguments) tuple to rewrite the
        # command, or None to run the command unmodified.
        #
        # Args:
        #   view (View)
        #   command (str)
        #   args (dict)
        #
        # Returns:
        #   Tuple (str, dict):
        #       If the command is to be rewritten
        #   None:
        #       If the command is unmodified
        if command == 'drag_select':

            # Updates the mode based on mouse events. For example, a double
            # click will select a word and enter VISUAL mode. A triple click
            # will select a line and enter VISUAL LINE mode.
            #
            # The command is rewritten by returning a chain of commands that
            # executes the original drag_select command followed by entering the
            # correct mode.

            # TODO Kill State dependency
            mode = State(view).mode

            if mode in (VISUAL, VISUAL_LINE, VISUAL_BLOCK):
                if (args.get('extend') or (args.get('by') == 'words') or args.get('additive')):
                    return
                elif args.get('by') == 'lines':
                    # Triple click: enter VISUAL LINE.
                    return ('_nv_run_cmds', {'commands': [
                        ['drag_select', args],
                        ['_enter_visual_line_mode', {'mode': mode}]
                    ]})
                elif not args.get('extend'):
                    # Single click: enter NORMAL.
                    return ('_nv_run_cmds', {'commands': [
                        ['drag_select', args],
                        ['_enter_normal_mode', {'mode': mode}]
                    ]})

            elif mode == NORMAL:
                # TODO Dragging the mouse does not seem to fire a different event than simply clicking. This makes it hard to update the xpos. See https://github.com/SublimeTextIssues/Core/issues/2117.  # noqa: E501
                if args.get('extend') or (args.get('by') == 'words'):
                    # Double click: enter VISUAL.
                    return ('_nv_run_cmds', {'commands': [
                        ['drag_select', args],
                        ['_enter_visual_mode', {'mode': mode}]
                    ]})
Ejemplo n.º 8
0
    def run(self, initial_text=':', cmd_line=''):
        if cmd_line:
            # The caller has provided a command, to we're not in interactive
            # mode -- just run the command.
            ViColonInput.interactive_call = False
            self.on_done(cmd_line)
            return
        else:
            ViColonInput.interactive_call = True

        FsCompletion.invalidate()

        ui_cmdline_prompt(self.window,
                          initial_text=self.adjust_initial_text(initial_text),
                          on_done=self.on_done,
                          on_change=self.on_change,
                          on_cancel=self.on_cancel)

        state = State(self.window.active_view())
        state.reset_during_init = False
Ejemplo n.º 9
0
    def on_activated(self, view):

        # Clear any visual selections in the view we are leaving. This mirrors
        # Vim behaviour. We can't put this functionality in the
        # view.on_deactivate() event, because that event is triggered when the
        # user right button clicks the view with the mouse, and we don't want
        # visual selections to be cleared on mouse right button clicks.
        if not view.settings().get('is_widget'):
            window = view.window()
            if window:
                active_group = window.active_group()
                for group in range(window.num_groups()):
                    if group != active_group:
                        other_view = window.active_view_in_group(group)
                        if other_view and other_view != view:
                            sel = other_view.sel()
                            if len(sel) > 0 and any([not s.empty() for s in sel]):
                                enter_normal_mode(other_view, State(other_view).mode)

        # Initialise view state.
        init_state(view)
Ejemplo n.º 10
0
    def run(self, cmdline=None, initial_text=None):
        _log.debug('cmdline.run cmdline = %s', cmdline)

        if cmdline:

            # The caller has provided a command (non-interactive mode), so run
            # the command without a prompt.
            # TODO [review] Non-interactive mode looks unused?

            _nv_cmdline.interactive_call = False

            return self.on_done(cmdline)
        else:
            _nv_cmdline.interactive_call = True

        # TODO There has got to be a better way to handle fs ("file system"?) completions.
        _nv_fs_completion.invalidate()

        state = State(self.window.active_view())
        state.reset_during_init = False

        if initial_text is None:
            if state.mode in (VISUAL, VISUAL_LINE, VISUAL_BLOCK):
                initial_text = ":'<,'>"
            else:
                initial_text = ':'
        else:
            if initial_text[0] != ':':
                raise ValueError(
                    'initial cmdline text must begin with a colon')

        ui_cmdline_prompt(self.window,
                          initial_text=initial_text,
                          on_done=self.on_done,
                          on_change=self.on_change,
                          on_cancel=self.on_cancel)
Ejemplo n.º 11
0
 def run(self, key=None):
     state = State(self.window.active_view())
     state.motion = ViSearchBackwardImpl()
     state.last_buffer_search = (state.motion._inp
                                 or state.last_buffer_search)
Ejemplo n.º 12
0
    def adjust_initial_text(self, text):
        state = State(self.window.active_view())
        if state.mode in (VISUAL, VISUAL_LINE):
            text = ":'<,'>" + text[1:]

        return text
Ejemplo n.º 13
0
 def state(self):
     return State(self.view)
Ejemplo n.º 14
0
def _resolve_line_number(view, token, current):
    # type: (...) -> int
    # Args:
    #   view (View): The view where the calculation is made.
    #   token (Token):
    #   current (int): Line number where we are now.
    if isinstance(token, TokenDot):
        return row_at(view, view.text_point(current, 0))

    if isinstance(token, TokenDigits):
        return max(int(token.content) - 1, -1)

    if isinstance(token, TokenPercent):
        return row_at(view, view.size())

    if isinstance(token, TokenDollar):
        return row_at(view, view.size())

    if isinstance(token, TokenOffset):
        return current + sum(token.content)

    if isinstance(token, TokenSearchForward):
        match = view.find(token.content, view.text_point(current, 0))
        if not match:
            raise ValueError('pattern not found')

        return row_at(view, match.a)

    if isinstance(token, TokenSearchBackward):
        match = reverse_search_by_pt(view, token.content, 0,
                                     view.text_point(current, 0))
        if not match:
            raise ValueError('pattern not found')

        return row_at(view, match.a)

    if isinstance(token, TokenMark):
        if token.content == '<':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.a)
            else:
                return row_at(view, sel.a - 1)
        elif token.content == '>':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.b - 1)
            else:
                return row_at(view, sel.b)
        elif token.content in tuple('abcdefghijklmnopqrstuvwxyz'):
            # The state class is intentionally imported here instead of at the
            # begining of the file to avoid circular imports errors. The State
            # needs to refactored and replaced with some less god-like
            from NeoVintageous.nv.state import State
            address = State(view).marks.get_as_encoded_address(token.content)

            return view.rowcol(address.b)[0]

    raise NotImplementedError()