def value(sectname, optname): """A CompletionModel filled with setting values. Args: sectname: The name of the config section this model shows. optname: The name of the config option this model shows. """ model = completionmodel.CompletionModel(column_widths=(20, 70, 10)) config = objreg.get('config') try: current = config.get(sectname, optname, raw=True) or '""' except (configexc.NoSectionError, configexc.NoOptionError): return None default = configdata.DATA[sectname][optname].default() or '""' if hasattr(configdata.DATA[sectname], 'valtype'): # Same type for all values (ValueList) vals = configdata.DATA[sectname].valtype.complete() else: if optname is None: raise ValueError("optname may only be None for ValueList " "sections, but {} is not!".format(sectname)) # Different type for each value (KeyValue) vals = configdata.DATA[sectname][optname].typ.complete() cur_cat = listcategory.ListCategory("Current/Default", [(current, "Current value"), (default, "Default value")]) model.add_category(cur_cat) if vals is not None: model.add_category(listcategory.ListCategory("Completions", vals)) return model
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 = [] cmd_text = info.keyconf.get_command(key, 'normal') if cmd_text: parser = runners.CommandParser() try: cmd = parser.parse(cmd_text).cmd except cmdexc.NoSuchCommandError: data.append((cmd_text, '(Current) Invalid command!', key)) else: data.append((cmd_text, '(Current) {}'.format(cmd.desc), key)) cmd_text = info.keyconf.get_command(key, 'normal', default=True) if cmd_text: parser = runners.CommandParser() cmd = parser.parse(cmd_text).cmd data.append((cmd_text, '(Default) {}'.format(cmd.desc), key)) 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
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_cat = listcategory.ListCategory("Current/Default", [(current, "Current value"), (default, "Default value")]) model.add_category(cur_cat) vals = opt.typ.complete() if vals is not None: model.add_category(listcategory.ListCategory("Completions", vals)) return model
def url(*, info): """A model which combines bookmarks, quickmarks and web history URLs. Used for the `open` command. """ model = completionmodel.CompletionModel(column_widths=(40, 50, 10)) quickmarks = ((url, name) for (name, url) in objreg.get('quickmark-manager').marks.items()) bookmarks = objreg.get('bookmark-manager').marks.items() model.add_category( listcategory.ListCategory('Quickmarks', quickmarks, delete_func=_delete_quickmark)) model.add_category( listcategory.ListCategory('Bookmarks', bookmarks, delete_func=_delete_bookmark)) if info.config.get('completion.web_history_max_items') != 0: hist_cat = histcategory.HistoryCategory(delete_func=_delete_history) model.add_category(hist_cat) return model
def _buffer(*, win_id_filter=lambda _win_id: True, add_win_id=True): """Helper to get the completion model for buffer/other_buffer. Args: win_id_filter: A filter function for window IDs to include. Should return True for all included windows. add_win_id: Whether to add the window ID to the completion items. """ 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)) tabs_are_windows = config.val.tabs.tabs_are_windows # list storing all single-tabbed windows when tabs_are_windows windows = [] # type: typing.List[typing.Tuple[str, str, str]] for win_id in objreg.window_registry: if not win_id_filter(win_id): continue tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id) if tabbed_browser.shutting_down: continue tabs = [] # type: typing.List[typing.Tuple[str, str, str]] for idx in range(tabbed_browser.widget.count()): tab = tabbed_browser.widget.widget(idx) tab_str = ("{}/{}".format(win_id, idx + 1) if add_win_id else str(idx + 1)) tabs.append((tab_str, tab.url().toDisplayString(), tabbed_browser.widget.page_title(idx))) if tabs_are_windows: windows += tabs else: title = str(win_id) if add_win_id else "Tabs" cat = listcategory.ListCategory(title, tabs, delete_func=delete_buffer, sort=False) model.add_category(cat) if tabs_are_windows: win = listcategory.ListCategory("Windows", windows, delete_func=delete_buffer, sort=False) model.add_category(win) return model
def test_set_pattern(pattern, before, after, after_nosort, model_validator): """Validate the filtering and sorting results of set_pattern.""" cat = listcategory.ListCategory('Foo', before) model_validator.set_model(cat) cat.set_pattern(pattern) model_validator.validate(after) cat = listcategory.ListCategory('Foo', before, sort=False) model_validator.set_model(cat) cat.set_pattern(pattern) model_validator.validate(after_nosort)
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", sorted(settings))) return model
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)) 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'] categories = config.val.completion.open_categories models: Dict[str, QAbstractItemModel] = {} 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( database=history.web_history.database, delete_func=_delete_history) models['history'] = hist_cat if 'filesystem' in categories: models['filesystem'] = filepathcategory.FilePathCategory( name='Filesystem') for category in categories: if category in models: model.add_category(models[category]) return model
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)) tabs_are_windows = config.val.tabs.tabs_are_windows # list storing all single-tabbed windows when tabs_are_windows windows = [] # type: typing.List[typing.Tuple[str, str, str]] 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 = [] # type: typing.List[typing.Tuple[str, str, str]] 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))) if tabs_are_windows: windows += tabs else: cat = listcategory.ListCategory(str(win_id), tabs, delete_func=delete_buffer, sort=False) model.add_category(cat) if tabs_are_windows: win = listcategory.ListCategory("Windows", windows, delete_func=delete_buffer, sort=False) model.add_category(win) return model
def _back_forward(info, go_forward): history = info.cur_tab.history current_idx = history.current_idx() model = completionmodel.CompletionModel(column_widths=(5, 36, 50, 9)) if go_forward: start = current_idx + 1 items = history.forward_items() else: start = 0 items = history.back_items() entries = [ ( str(idx), entry.url().toDisplayString(), entry.title(), _qdatetime_to_completion_format(entry.lastVisited()) ) for idx, entry in enumerate(items, start) ] if not go_forward: # make sure the most recent is at the top for :back entries.reverse() cat = listcategory.ListCategory("History", entries, sort=False) model.add_category(cat) return model
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 option(*, info): """A CompletionModel filled with settings and their descriptions.""" 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()) model.add_category(listcategory.ListCategory("Options", options)) return model
def buffer(): """A model to complete on open tabs across all windows. Used for switching the buffer command. """ 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: tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id) if tabbed_browser.shutting_down: continue tabs = [] for idx in range(tabbed_browser.count()): tab = tabbed_browser.widget(idx) tabs.append(("{}/{}".format(win_id, idx + 1), tab.url().toDisplayString(), tabbed_browser.page_title(idx))) cat = listcategory.ListCategory("{}".format(win_id), tabs, delete_func=delete_buffer) model.add_category(cat) return model
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 option(sectname): """A CompletionModel filled with settings and their descriptions. Args: sectname: The name of the config section this model shows. """ model = completionmodel.CompletionModel(column_widths=(20, 70, 10)) try: sectdata = configdata.DATA[sectname] except KeyError: return None options = [] for name in sectdata: try: desc = sectdata.descriptions[name] except (KeyError, AttributeError): # Some stuff (especially ValueList items) don't have a # description. desc = "" else: desc = desc.splitlines()[0] config = objreg.get('config') val = config.get(sectname, name, raw=True) options.append((name, desc, val)) model.add_category(listcategory.ListCategory(sectname, options)) return model
def section(): """A CompletionModel filled with settings sections.""" model = completionmodel.CompletionModel(column_widths=(20, 70, 10)) sections = ((name, configdata.SECTION_DESC[name].splitlines()[0].strip()) for name in configdata.DATA) model.add_category(listcategory.ListCategory("Sections", sections)) return model
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
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 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("{}".format(win_id), tabs, delete_func=delete_buffer) model.add_category(cat) return model
def test_long_pattern(caplog, model_validator): """Validate that a huge pattern doesn't crash (#5973).""" with caplog.at_level(logging.WARNING): cat = listcategory.ListCategory('Foo', [('a' * 5000, '')]) model_validator.set_model(cat) cat.set_pattern('a' * 50000) model_validator.validate([('a' * 5000, '')])
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 customized_option(*, info): """A CompletionModel filled with set settings and their descriptions.""" model = completionmodel.CompletionModel(column_widths=(20, 70, 10)) options = ((opt.name, opt.description, info.config.get_str(opt.name)) for opt, _value in info.config) model.add_category(listcategory.ListCategory("Customized options", options)) return model
def inspector_position(*, info): """A model for possible inspector positions.""" utils.unused(info) model = completionmodel.CompletionModel(column_widths=(100, 0, 0)) positions = [(e.name, ) for e in inspector.Position] category = listcategory.ListCategory("Position (optional)", positions) model.add_category(category) return model
def test_set_model(completionview, model): """Ensure set_model actually sets the model and expands all categories.""" 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 url(*, info): """A model which combines bookmarks, quickmarks, search engines and web history URLs. Used for the `open` command. """ model = completionmodel.CompletionModel(column_widths=(40, 50, 10)) quickmarks = [(url, name) for (name, url) in objreg.get('quickmark-manager').marks.items()] bookmarks = objreg.get('bookmark-manager').marks.items() # pylint: disable=bad-config-option searchengines = { k: v for k, v in config.val.url.searchengines.items() if k not in "DEFAULT" }.items() # 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) if info.config.get('completion.web_history_max_items' ) != 0 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 bind(key): """A CompletionModel filled with all bindable commands and descriptions. Args: key: the key being bound. """ model = completionmodel.CompletionModel(column_widths=(20, 60, 20)) cmd_text = objreg.get('key-config').get_bindings_for('normal').get(key) if cmd_text: cmd_name = cmd_text.split(' ')[0] cmd = cmdutils.cmd_dict.get(cmd_name) data = [(cmd_text, cmd.desc, key)] model.add_category(listcategory.ListCategory("Current", data)) cmdlist = _get_cmd_completions(include_hidden=True, include_aliases=True) model.add_category(listcategory.ListCategory("Commands", cmdlist)) return model
def test_no_selection(self, qtbot, completionview, model, which, expected): """With no selection, the first/last item should be selected.""" items = [("First Item", ), ("Middle Item", ), ("Last Item", )] cat = listcategory.ListCategory('Test', items) model.add_category(cat) completionview.set_model(model) with qtbot.waitSignal(completionview.selection_changed) as blocker: completionview.completion_item_focus(which) assert blocker.args == [expected]
def test_completion_item_del_no_selection(completionview, model): """Test that completion_item_del with an invalid index.""" func = mock.Mock(spec=[]) 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()
def test_completion_item_del(completionview, model): """Test that completion_item_del invokes delete_cur_item in the model.""" func = mock.Mock(spec=[]) 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 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)) cmd_text = info.keyconf.get_command(key, 'normal') if cmd_text: parser = runners.CommandParser() cmd = parser.parse(cmd_text).cmd data = [(cmd_text, cmd.desc, key)] model.add_category(listcategory.ListCategory("Current", data)) cmdlist = util.get_cmd_completions(info, include_hidden=True, include_aliases=True) model.add_category(listcategory.ListCategory("Commands", cmdlist)) return model
def _get_rules_completion(*args, info): tab = objreg.get('tab', scope='tab', window=info.win_id, tab='current') model = completionmodel.CompletionModel(column_widths=(100, )) entries = [("{:10}{:10}{}".format(action.name, res_type.name.lower(), dest), ) for dest, types in SEEN_REQUESTS.matrix_rules[tab.url().host()].items() for res_type, action in types.items()] cat = listcategory.ListCategory("Requests", entries) model.add_category(cat) return model