def state(self): return State(self._view)
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()
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 }]] })