Ejemplo n.º 1
0
def _ui_bell(*msg: str) -> None:
    window = active_window()
    if not window:
        return

    view = window.active_view()
    if not view:
        return

    if msg:
        status_message(*msg)

    if get_option(view, 'belloff') == 'all':
        return

    color_scheme = get_setting(view, 'bell_color_scheme')
    if color_scheme in ('dark', 'light'):
        color_scheme = 'Packages/NeoVintageous/res/Bell-%s.hidden-color-scheme' % color_scheme

    duration = int(0.3 * 1000)
    times = 4
    delay = 55

    style = get_setting(view, 'bell')

    settings = view.settings()

    if style == 'view':
        settings.set('color_scheme', color_scheme)

        def remove_bell() -> None:
            settings.erase('color_scheme')

        set_timeout(remove_bell, duration)
    elif style == 'views':
        views = []
        for group in range(window.num_groups()):
            view = window.active_view_in_group(group)
            if view:
                view.settings().set('color_scheme', color_scheme)
                views.append(view)

        def remove_bell() -> None:
            for view in views:
                view.settings().erase('color_scheme')

        set_timeout(remove_bell, duration)
    elif style == 'blink':
        # Ensure we leave the setting as we found it.
        times = times if (times % 2) == 0 else times + 1

        def do_blink() -> None:
            nonlocal times
            if times > 0:
                settings.set('highlight_line', not settings.get('highlight_line'))
                times -= 1
                set_timeout(do_blink, delay)

        do_blink()
Ejemplo n.º 2
0
def _seq_to_command(view, seq: str, mode: str):
    # Return the command definition mapped for seq and mode.
    #
    # Args:
    #   view (View):
    #   seq (str): The command sequence.
    #   mode (str): Forces the use of this mode instead of the global state's.
    #
    # Returns:
    #   ViCommandDefBase:
    #   ViMissingCommandDef: If not found.
    if mode in plugin.mappings:
        plugin_command = plugin.mappings[mode].get(seq)
        if plugin_command:
            plugin_name = plugin_command.__class__.__module__[24:]
            is_plugin_enabled = get_setting(view, 'enable_%s' % plugin_name)
            if is_plugin_enabled:
                return plugin_command

    if mode in keys.mappings:
        command = keys.mappings[mode].get(seq)
        if command:
            return command

    return ViMissingCommandDef()
Ejemplo n.º 3
0
def _get_search_flags(view, search: str) -> int:
    flags = LITERAL

    if search and get_setting(view, 'sneak_use_ic_scs') == 1:
        if get_option(view,
                      'ignorecase') and not is_smartcase_pattern(view, search):
            flags |= IGNORECASE

    return flags
Ejemplo n.º 4
0
    def _get(self, view):
        try:
            value = _session[self._name]
        except KeyError:
            # DEPRECATED This is for backwards compatability only. All options
            # should be set by the .neovintageousrc configuration file.
            # See https://github.com/NeoVintageous/NeoVintageous/issues/404.
            value = get_setting(view, self._name, self._default)

        return value
Ejemplo n.º 5
0
def window_quit_view(window, **kwargs) -> None:
    # Need to get the setting before quiting the the view because if closing the
    # last view there may not be a view to get the setting from.
    exit_when_quiting_last_window = get_setting(
        window.active_view(), 'exit_when_quiting_last_window')

    _close_view(window, **kwargs)

    if len(window.views()) == 0 and exit_when_quiting_last_window:
        window.run_command('close')
Ejemplo n.º 6
0
def _get(view, name: str = _UNNAMED):
    name = str(name)

    assert len(name) == 1, "Register names must be 1 char long."

    if name == _CURRENT_FILE_NAME:
        try:
            file_name = view.file_name()
            if not file_name:
                return

            return [file_name]
        except AttributeError:
            return

    if name in _CLIPBOARD:
        return [get_clipboard()]

    if ((name not in (_UNNAMED, _SMALL_DELETE)) and (name in _SPECIAL)):
        return

    # Special case lumped among these --user always wants the sys clipboard
    if ((name == _UNNAMED)
            and (get_setting(view, 'use_sys_clipboard') is True)):
        return [get_clipboard()]

    # If the expression register holds a value and we're requesting the unnamed
    # register, return the expression register and clear it aftwerwards.
    if name == _UNNAMED and _data.get(_EXPRESSION, ''):
        value = _data[_EXPRESSION]
        _data[_EXPRESSION] = None

        return value

    if name.isdigit():
        if name == _LAST_YANK:
            return _data[name]

        return _get_numbered_register(name)

    try:
        return _data[name.lower()]
    except KeyError:
        pass
Ejemplo n.º 7
0
    def on_query_context(self, view, key, operator, operand, match_all):
        # Called when determining to trigger a key binding with the given context key.
        #
        # If the plugin knows how to respond to the context, it should return
        # either True of False. If the context is unknown, it should return
        # None.
        #
        # Args:
        #   view (View):
        #   key (str):
        #   operator (int):
        #   operand (bool):
        #   match_all (bool):
        #
        # Returns:
        #   bool: If the context is known.
        #   None: If the context is unknown.
        if key == 'nv_handle_key':
            handle_keys = get_setting(view, 'handle_keys')
            if handle_keys:
                try:
                    # Check if the key (no mode prefix; all modes) should be handled.
                    return bool(handle_keys[operand])
                except KeyError:
                    # Check if the key should be handled only for a specific mode.
                    # The format is "{mode}_{key}" e.g. "n_<C-w>", "v_<C-w>"
                    # meaning NORMAL, VISUAL respectively. No prefix implies all
                    # modes. See mode_to_char() for a list of valid mode prefixes.
                    cur_mode_char = mode_to_char(get_mode(view))
                    if cur_mode_char:
                        try:
                            return bool(handle_keys['%s_%s' %
                                                    (cur_mode_char, operand)])
                        except KeyError:
                            pass

            # By default all keys are handled.
            return True

        try:
            return _query_contexts[key](view, operator, operand, match_all)
        except KeyError:
            pass
Ejemplo n.º 8
0
def open(view) -> None:
    term = get_setting(view, 'terminal', 'cmd.exe')
    if term:
        subprocess.Popen([term, '/k'], cwd=os.getcwd())
Ejemplo n.º 9
0
def init_state(view) -> None:
    # Initialise view state.
    #
    # Runs every time a view is activated, loaded, etc.

    # Don't initialise if we get a console, widget, panel, or any other view
    # where Vim modes are not relevant. Some related initialised settings that
    # may cause unexpected behaviours if they exist are erased "cleaned" too.
    if not is_view(view):
        try:
            # TODO "cleaning" views that are not initialised shouldn't be necessary?
            clean_view(view)
        except Exception:
            _log.debug(
                'could not clean an object: console, widget, panel, etc.')
        finally:
            return

    if not get_reset_during_init(view):
        # Probably exiting from an input panel, like when using '/'. Don't reset
        # the global state, as it may contain data needed to complete the
        # command that's being built.
        set_reset_during_init(view, True)
        return

    mode = get_mode(view)

    # Does user want to reset mode (to normal mode) when initialising state?
    if mode not in (NORMAL, UNKNOWN) and not get_setting(
            view, 'reset_mode_when_switching_tabs'):
        return

    # Fix malformed selection: if we have no selections, add one.
    if len(view.sel()) == 0:
        view.sel().add(0)

    if get_setting(view, 'default_mode') == 'insert':
        if mode in (NORMAL, UNKNOWN):
            enter_insert_mode(view, mode)
    elif mode in (VISUAL, VISUAL_LINE, VISUAL_BLOCK):
        # Visual modes are not reset (to normal mode), because actions like
        # pressing the super key or opening a command-palette/overlay will cause
        # the active view to lose focus and when focus is received again it
        # triggers the on_activated() event, this in turn initialises the view'
        # state, which would reset the visual mode to normal mode, therefore,
        # for example, any command run from the command palette that expects to
        # operate on a visual selection wouldn't work because the visual
        # selection is reset to normal mode before the command has time to run.
        # See https://github.com/NeoVintageous/NeoVintageous/issues/547
        pass
    elif mode in (INSERT, REPLACE):
        # NOTE that the mode is not passed as an argument because it causes the
        # cursor to move back one point from it's current position, for example
        # when pressing i<Esc>i<Esc>i<Esc> the cursor moves one point each time,
        # which is expected, but not expected when initialising state. But not
        # passing the mode may also be causing some other hidden bugs too.
        view.window().run_command('_enter_normal_mode', {'from_init': True})
    elif mode != VISUAL and view.has_non_empty_selection_region():
        # Try to fixup a malformed visual state. For example, apparently this
        # can happen when a search is performed via a search panel and "Find
        # All" is pressed. In that case, multiple selections may need fixing.
        view.window().run_command('_enter_visual_mode', {'mode': mode})
    else:
        # This may be run when we're coming from cmdline mode.
        mode = VISUAL if view.has_non_empty_selection_region() else mode
        view.window().run_command('_enter_normal_mode', {
            'mode': mode,
            'from_init': True
        })

    reset_command_data(view)
Ejemplo n.º 10
0
def open(view) -> None:
    term = get_setting(view, 'terminal', os.environ.get('TERM'))
    if term:
        subprocess.Popen([term, '-e', 'bash'], cwd=os.getcwd())
Ejemplo n.º 11
0
def init_state(view):
    # type: (...) -> None
    # Initialise view state.
    #
    # Runs at startup and every time a view gets activated, loaded, etc.
    #
    # Args:
    #   :view (sublime.View):
    if not is_view(view):
        # Abort if we got a console, widget, panel...
        try:
            # XXX: All this seems to be necessary here.
            if not is_ignored_but_command_mode(view):
                view.settings().set('command_mode', False)
                view.settings().set('inverse_caret_state', False)

            view.settings().erase('vintage')
        except Exception:
            # TODO [review] Exception handling
            _log.debug(
                'error initialising irregular view i.e. console, widget, panel, etc.'
            )
        finally:
            return

    state = State(view)

    if not get_reset_during_init(view):
        # Probably exiting from an input panel, like when using '/'. Don't
        # reset the global state, as it may contain data needed to complete
        # the command that's being built.
        set_reset_during_init(view, True)
        return

    mode = state.mode

    # Non-standard user setting.
    reset = get_setting(view, 'reset_mode_when_switching_tabs')
    # XXX: If the view was already in normal mode, we still need to run the
    # init code. I believe this is due to Sublime Text (intentionally) not
    # serializing the inverted caret state and the command_mode setting when
    # first loading a file.
    # If the mode is unknown, it might be a new file. Let normal mode setup
    # continue.
    if not reset and (mode not in (NORMAL, UNKNOWN)):
        return

    # If we have no selections, add one.
    if len(view.sel()) == 0:
        view.sel().add(0)

    if get_setting(view, 'default_mode') == 'insert':
        if mode in (NORMAL, UNKNOWN):
            enter_insert_mode(view, mode)
    elif mode in (VISUAL, VISUAL_LINE):
        # This was commented out to fix the issue of visual selections being
        # lost because some keys, like the super key, cause Sublime to lose
        # focus, and when focus comes back it triggers the on_activated() event,
        # which then initializes state, which then causes visual mode to enter
        # normal mode. Note that there may be regressions as a side effect.
        # See nv/events.py#NeoVintageousEvents::on_activated().
        # See https://github.com/NeoVintageous/NeoVintageous/issues/547
        # view.window().run_command('_enter_normal_mode', {'from_init': True})
        _log.debug('initializing %s state', mode)
    elif mode in (INSERT, REPLACE):
        # TODO: Don't we need to pass a mode here?
        view.window().run_command('_enter_normal_mode', {'from_init': True})

    elif view.has_non_empty_selection_region() and mode != VISUAL:
        # Runs, for example, when we've performed a search via ST3 search panel
        # and we've pressed 'Find All'. In this case, we want to ensure a
        # consistent state for multiple selections.
        # TODO We could end up with multiple selections in other ways that bypass init_state.
        state.mode = VISUAL
    else:
        # This may be run when we're coming from cmdline mode.
        mode = VISUAL if view.has_non_empty_selection_region() else mode
        state.enter_normal_mode()
        view.window().run_command('_enter_normal_mode', {
            'mode': mode,
            'from_init': True
        })

    state.reset_command_data()
Ejemplo n.º 12
0
def _maybe_set_sys_clipboard(view, name: str, values: list) -> None:
    if (name in _CLIPBOARD or get_setting(view, 'use_sys_clipboard') is True):
        value = '\n'.join(values)
        set_clipboard(value)
        update_clipboard_history(value)