Esempio n. 1
0
def value(optname, *values, info):
    """A CompletionModel filled with setting values.

    Args:
        optname: The name of the config option this model shows.
        values: The values already provided on the command line.
        info: A CompletionInfo instance.
    """
    model = completionmodel.CompletionModel(column_widths=(30, 70, 0))

    try:
        current = info.config.get_str(optname)
    except configexc.NoOptionError:
        return None

    opt = info.config.get_opt(optname)
    default = opt.typ.to_str(opt.default)
    cur_def = []
    if current not in values:
        cur_def.append((current, "Current value"))
    if default not in values:
        cur_def.append((default, "Default value"))
    if cur_def:
        cur_cat = listcategory.ListCategory("Current/Default", cur_def)
        model.add_category(cur_cat)

    vals = opt.typ.complete() or []
    vals = [x for x in vals if x[0] not in values]
    if vals:
        model.add_category(listcategory.ListCategory("Completions", vals))
    return model
def test_completion_item_focus_fetch(completionview, qtbot):
    """Test that on_next_prev_item moves the selection properly.

    Args:
        which: the direction in which to move the selection.
        tree: Each list represents a completion category, with each string
              being an item under that category.
        expected: expected argument from on_selection_changed for each
                  successive movement. None implies no signal should be
                  emitted.
    """
    model = completionmodel.CompletionModel()
    cat = mock.Mock(spec=[
        'layoutChanged', 'layoutAboutToBeChanged', 'canFetchMore', 'fetchMore',
        'rowCount', 'index', 'data'
    ])
    cat.canFetchMore = lambda *_: True
    cat.rowCount = lambda *_: 2
    cat.fetchMore = mock.Mock()
    model.add_category(cat)
    completionview.set_model(model)
    # clear the fetchMore call that happens on set_model
    cat.reset_mock()

    # not at end, fetchMore shouldn't be called
    completionview.completion_item_focus('next')
    assert not cat.fetchMore.called

    # at end, fetchMore should be called
    completionview.completion_item_focus('next')
    assert cat.fetchMore.called
def test_completion_show(show, rows, quick_complete, completionview,
                         config_stub):
    """Test that the completion widget is shown at appropriate times.

    Args:
        show: The completion show config setting.
        rows: Each entry represents a completion category with only one item.
        quick_complete: The `completion.quick` config setting.
    """
    config_stub.val.completion.show = show
    config_stub.val.completion.quick = quick_complete

    model = completionmodel.CompletionModel()
    for name in rows:
        cat = listcategory.ListCategory('', [(name, )])
        model.add_category(cat)

    assert not completionview.isVisible()
    completionview.set_model(model)
    assert completionview.isVisible() == (show == 'always' and len(rows) > 0)
    completionview.completion_item_focus('next')
    expected = (show != 'never' and len(rows) > 0
                and not (quick_complete and len(rows) == 1))
    assert completionview.isVisible() == expected
    completionview.set_model(None)
    completionview.completion_item_focus('next')
    assert not completionview.isVisible()
def test_set_pattern(completionview):
    model = completionmodel.CompletionModel()
    model.set_pattern = mock.Mock(spec=[])
    completionview.set_model(model)
    completionview.set_pattern('foo')
    model.set_pattern.assert_called_with('foo')
    assert not completionview.selectionModel().currentIndex().isValid()
Esempio n. 5
0
def command(*, info):
    """A CompletionModel filled with non-hidden commands and descriptions."""
    model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
    cmdlist = util.get_cmd_completions(info,
                                       include_aliases=True,
                                       include_hidden=False)
    model.add_category(listcategory.ListCategory("Commands", cmdlist))
    return model
def test_count(counts):
    model = completionmodel.CompletionModel()
    for c in counts:
        cat = mock.Mock(
            spec=['rowCount', 'layoutChanged', 'layoutAboutToBeChanged'])
        cat.rowCount = mock.Mock(return_value=c, spec=[])
        model.add_category(cat)
    assert model.count() == sum(counts)
def test_delete_cur_item():
    func = mock.Mock(spec=[])
    model = completionmodel.CompletionModel()
    cat = listcategory.ListCategory('', [('foo', 'bar')], delete_func=func)
    model.add_category(cat)
    parent = model.index(0, 0)
    model.delete_cur_item(model.index(0, 0, parent))
    func.assert_called_once_with(['foo', 'bar'])
def test_set_model(completionview):
    """Ensure set_model actually sets the model and expands all categories."""
    model = completionmodel.CompletionModel()
    for _i in range(3):
        model.add_category(listcategory.ListCategory('', [('foo', )]))
    completionview.set_model(model)
    assert completionview.model() is model
    for i in range(3):
        assert completionview.isExpanded(model.index(i, 0))
def test_delete_cur_item_no_cat():
    """Test completion_item_del with no selected category."""
    callback = mock.Mock(spec=[])
    model = completionmodel.CompletionModel()
    model.rowsAboutToBeRemoved.connect(callback)
    model.rowsRemoved.connect(callback)
    with pytest.raises(qtutils.QtValueError):
        model.delete_cur_item(QModelIndex())
    callback.assert_not_called()
Esempio n. 10
0
def customized_option(*, info):
    """A CompletionModel filled with set settings and their descriptions."""
    model = completionmodel.CompletionModel(column_widths=(20, 70, 10))
    options = ((values.opt.name, values.opt.description,
                info.config.get_str(values.opt.name)) for values in info.config
               if values)
    model.add_category(listcategory.ListCategory("Customized options",
                                                 options))
    return model
def test_completion_item_del(completionview):
    """Test that completion_item_del invokes delete_cur_item in the model."""
    func = mock.Mock(spec=[])
    model = completionmodel.CompletionModel()
    cat = listcategory.ListCategory('', [('foo', 'bar')], delete_func=func)
    model.add_category(cat)
    completionview.set_model(model)
    completionview.completion_item_focus('next')
    completionview.completion_item_del()
    func.assert_called_once_with(['foo', 'bar'])
def test_completion_item_del_no_selection(completionview):
    """Test that completion_item_del with an invalid index."""
    func = mock.Mock(spec=[])
    model = completionmodel.CompletionModel()
    cat = listcategory.ListCategory('', [('foo', )], delete_func=func)
    model.add_category(cat)
    completionview.set_model(model)
    with pytest.raises(cmdutils.CommandError, match='No item selected!'):
        completionview.completion_item_del()
    func.assert_not_called()
Esempio n. 13
0
def session(*, info=None):  # pylint: disable=unused-argument
    """A CompletionModel filled with session names."""
    model = completionmodel.CompletionModel()
    try:
        manager = objreg.get('session-manager')
        sessions = ((name, ) for name in manager.list_sessions()
                    if not name.startswith('_'))
        model.add_category(listcategory.ListCategory("Sessions", sessions))
    except OSError:
        log.completion.exception("Failed to list sessions!")
    return model
def test_delete_cur_item_no_func():
    callback = mock.Mock(spec=[])
    model = completionmodel.CompletionModel()
    cat = listcategory.ListCategory('', [('foo', 'bar')], delete_func=None)
    model.rowsAboutToBeRemoved.connect(callback)
    model.rowsRemoved.connect(callback)
    model.add_category(cat)
    parent = model.index(0, 0)
    with pytest.raises(cmdutils.CommandError):
        model.delete_cur_item(model.index(0, 0, parent))
    callback.assert_not_called()
def test_set_pattern(pat, qtbot):
    """Validate the filtering and sorting results of set_pattern."""
    model = completionmodel.CompletionModel()
    cats = [mock.Mock(spec=['set_pattern']) for _ in range(3)]
    for c in cats:
        c.set_pattern = mock.Mock(spec=[])
        model.add_category(c)
    with qtbot.waitSignals([model.layoutAboutToBeChanged, model.layoutChanged],
                           order='strict'):
        model.set_pattern(pat)
    for c in cats:
        c.set_pattern.assert_called_with(pat)
def test_completion_item_focus_no_model(which, completionview, qtbot):
    """Test that selectionChanged is not fired when the model is None.

    Validates #1812: help completion repeatedly completes
    """
    with qtbot.assertNotEmitted(completionview.selection_changed):
        completionview.completion_item_focus(which)
    model = completionmodel.CompletionModel()
    completionview.set_model(model)
    completionview.set_model(None)
    with qtbot.assertNotEmitted(completionview.selection_changed):
        completionview.completion_item_focus(which)
def test_completion_item_yank(completionview, mocker, sel):
    """Test that completion_item_yank invokes delete_cur_item in the model."""
    m = mocker.patch('glimpsebrowser.completion.completionwidget.utils',
                     autospec=True)
    model = completionmodel.CompletionModel()
    cat = listcategory.ListCategory('', [('foo', 'bar')])
    model.add_category(cat)

    completionview.set_model(model)
    completionview.completion_item_focus('next')
    completionview.completion_item_yank(sel)

    m.set_clipboard.assert_called_once_with('foo', sel)
Esempio n. 18
0
def _option(info, title, predicate):
    """A CompletionModel that is generated for several option sets.

    Args:
        info: The config info that can be passed through.
        title: The title of the options.
        predicate: The function for filtering out the options. Takes a single
                   argument.
    """
    model = completionmodel.CompletionModel(column_widths=(20, 70, 10))
    options = ((opt.name, opt.description, info.config.get_str(opt.name))
               for opt in configdata.DATA.values() if predicate(opt))
    model.add_category(listcategory.ListCategory(title, options))
    return model
Esempio n. 19
0
def helptopic(*, info):
    """A CompletionModel filled with help topics."""
    model = completionmodel.CompletionModel()

    cmdlist = util.get_cmd_completions(info,
                                       include_aliases=False,
                                       include_hidden=True,
                                       prefix=':')
    settings = ((opt.name, opt.description)
                for opt in configdata.DATA.values())

    model.add_category(listcategory.ListCategory("Commands", cmdlist))
    model.add_category(listcategory.ListCategory("Settings", settings))
    return model
Esempio n. 20
0
def url(*, info):
    """A model which combines various URLs.

    This combines:
    - bookmarks
    - quickmarks
    - search engines
    - web history URLs

    Used for the `open` command.
    """
    model = completionmodel.CompletionModel(column_widths=(40, 50, 10))

    # pylint: disable=bad-config-option
    quickmarks = [(url, name)
                  for (name,
                       url) in objreg.get('quickmark-manager').marks.items()]
    bookmarks = objreg.get('bookmark-manager').marks.items()
    searchengines = [(k, v)
                     for k, v in sorted(config.val.url.searchengines.items())
                     if k != 'DEFAULT']
    # pylint: enable=bad-config-option
    categories = config.val.completion.open_categories
    models = {}

    if searchengines and 'searchengines' in categories:
        models['searchengines'] = listcategory.ListCategory('Search engines',
                                                            searchengines,
                                                            sort=False)

    if quickmarks and 'quickmarks' in categories:
        models['quickmarks'] = listcategory.ListCategory(
            'Quickmarks',
            quickmarks,
            delete_func=_delete_quickmark,
            sort=False)
    if bookmarks and 'bookmarks' in categories:
        models['bookmarks'] = listcategory.ListCategory(
            'Bookmarks', bookmarks, delete_func=_delete_bookmark, sort=False)

    history_disabled = info.config.get('completion.web_history.max_items') == 0
    if not history_disabled and 'history' in categories:
        hist_cat = histcategory.HistoryCategory(delete_func=_delete_history)
        models['history'] = hist_cat

    for category in categories:
        if category in models:
            model.add_category(models[category])

    return model
def test_completion_item_yank_selected(completionview, status_command_stub,
                                       mocker, sel):
    """Test that completion_item_yank yanks selected text."""
    m = mocker.patch('glimpsebrowser.completion.completionwidget.utils',
                     autospec=True)
    model = completionmodel.CompletionModel()
    cat = listcategory.ListCategory('', [('foo', 'bar')])
    model.add_category(cat)

    completionview.set_model(model)
    completionview.completion_item_focus('next')

    status_command_stub.selectedText = mock.Mock(return_value='something')
    completionview.completion_item_yank(sel)

    m.set_clipboard.assert_called_once_with('something', sel)
Esempio n. 22
0
def bookmark(*, info=None):  # pylint: disable=unused-argument
    """A CompletionModel filled with all bookmarks."""
    def delete(data: typing.Sequence[int]) -> None:
        """Delete a bookmark from the completion menu."""
        urlstr = data[0]
        log.completion.debug('Deleting bookmark {}'.format(urlstr))
        bookmark_manager = objreg.get('bookmark-manager')
        bookmark_manager.delete(urlstr)

    model = completionmodel.CompletionModel(column_widths=(30, 70, 0))
    marks = objreg.get('bookmark-manager').marks.items()
    model.add_category(
        listcategory.ListCategory('Bookmarks',
                                  marks,
                                  delete_func=delete,
                                  sort=False))
    return model
Esempio n. 23
0
def bind(key, *, info):
    """A CompletionModel filled with all bindable commands and descriptions.

    Args:
        key: the key being bound.
    """
    model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
    data = _bind_current_default(key, info)

    if data:
        model.add_category(listcategory.ListCategory("Current/Default", data))

    cmdlist = util.get_cmd_completions(info,
                                       include_hidden=True,
                                       include_aliases=True)
    model.add_category(listcategory.ListCategory("Commands", cmdlist))
    return model
Esempio n. 24
0
def window(*, info):
    """A model to complete on all open windows."""
    model = completionmodel.CompletionModel(column_widths=(6, 30, 64))

    windows = []

    for win_id in objreg.window_registry:
        if win_id == info.win_id:
            continue
        tabbed_browser = objreg.get('tabbed-browser',
                                    scope='window',
                                    window=win_id)
        tab_titles = (tab.title() for tab in tabbed_browser.widgets())
        windows.append(
            ("{}".format(win_id), objreg.window_registry[win_id].windowTitle(),
             ", ".join(tab_titles)))

    model.add_category(listcategory.ListCategory("Windows", windows))

    return model
def test_first_last_item(counts):
    """Test that first() and last() index to the first and last items."""
    model = completionmodel.CompletionModel()
    for c in counts:
        cat = mock.Mock(spec=['layoutChanged', 'layoutAboutToBeChanged'])
        cat.rowCount = mock.Mock(return_value=c, spec=[])
        model.add_category(cat)
    data = [i for i, row_count in enumerate(counts) if row_count > 0]
    if not data:
        # with no items, first and last should be an invalid index
        assert not model.first_item().isValid()
        assert not model.last_item().isValid()
    else:
        first = data[0]
        last = data[-1]
        # first item of the first data category
        assert model.first_item().row() == 0
        assert model.first_item().parent().row() == first
        # last item of the last data category
        assert model.last_item().row() == counts[last] - 1
        assert model.last_item().parent().row() == last
Esempio n. 26
0
def _buffer(skip_win_id=None):
    """Helper to get the completion model for buffer/other_buffer.

    Args:
        skip_win_id: The id of the window to skip, or None to include all.
    """
    def delete_buffer(data):
        """Close the selected tab."""
        win_id, tab_index = data[0].split('/')
        tabbed_browser = objreg.get('tabbed-browser',
                                    scope='window',
                                    window=int(win_id))
        tabbed_browser.on_tab_close_requested(int(tab_index) - 1)

    model = completionmodel.CompletionModel(column_widths=(6, 40, 54))

    for win_id in objreg.window_registry:
        if skip_win_id is not None and win_id == skip_win_id:
            continue
        tabbed_browser = objreg.get('tabbed-browser',
                                    scope='window',
                                    window=win_id)
        if tabbed_browser.shutting_down:
            continue
        tabs = []
        for idx in range(tabbed_browser.widget.count()):
            tab = tabbed_browser.widget.widget(idx)
            tabs.append(("{}/{}".format(win_id,
                                        idx + 1), tab.url().toDisplayString(),
                         tabbed_browser.widget.page_title(idx)))
        cat = listcategory.ListCategory(str(win_id),
                                        tabs,
                                        delete_func=delete_buffer,
                                        sort=False)
        model.add_category(cat)

    return model
def test_completion_item_focus(which, tree, expected, completionview, qtbot):
    """Test that on_next_prev_item moves the selection properly.

    Args:
        which: the direction in which to move the selection.
        tree: Each list represents a completion category, with each string
              being an item under that category.
        expected: expected argument from on_selection_changed for each
                  successive movement. None implies no signal should be
                  emitted.
    """
    model = completionmodel.CompletionModel()
    for catdata in tree:
        cat = listcategory.ListCategory('', ((x, ) for x in catdata))
        model.add_category(cat)
    completionview.set_model(model)
    for entry in expected:
        if entry is None:
            with qtbot.assertNotEmitted(completionview.selection_changed):
                completionview.completion_item_focus(which)
        else:
            with qtbot.waitSignal(completionview.selection_changed) as sig:
                completionview.completion_item_focus(which)
                assert sig.args == [entry]