From 5e6150e6658b4202d213d8c3af6d1aec9fa08942 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 8 Sep 2014 06:57:22 +0200 Subject: [PATCH] Add a :help command. --- doc/commands.asciidoc | 14 ++++++++++ qutebrowser/browser/commands.py | 35 +++++++++++++++++++++++++ qutebrowser/models/completion.py | 43 ++++++++++++++++++++++++++++++- qutebrowser/network/qutescheme.py | 3 ++- qutebrowser/utils/completer.py | 8 +++--- qutebrowser/utils/usertypes.py | 3 ++- 6 files changed, 100 insertions(+), 6 deletions(-) diff --git a/doc/commands.asciidoc b/doc/commands.asciidoc index edbe9b05d..b533690ff 100644 --- a/doc/commands.asciidoc +++ b/doc/commands.asciidoc @@ -10,6 +10,7 @@ |<>|Download the current page. |<>|Go forward in the history of the current tab. |<>|Get the value from a section/option. +|<>|Show help about a command or setting. |<>|Start hinting. |<>|Open main startpage in current tab. |<>|Toggle the web inspector. @@ -71,6 +72,19 @@ Get the value from a section/option. * +'sectname'+: The section where the option is in. * +'optname'+: The name of the option. +[[help]] +=== help +Syntax: +:help 'topic'+ + +Show help about a command or setting. + +==== positional arguments +* +'topic'+: The topic to show help for. + + - :__command__ for commands. + - __section__\->__option__ for settings. + + [[hint]] === hint Syntax: +:hint ['group'] ['target'] ['args']+ diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index f4e730670..5a41fdb59 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -667,6 +667,41 @@ class CommandDispatcher: page = self._current_widget().page() self._tabs.download_get.emit(self._tabs.current_url(), page) + @cmdutils.register(instance='mainwindow.tabs.cmd', name='help', + completion=[usertypes.Completion.helptopic]) + def show_help(self, topic): + """Show help about a command or setting. + + Args: + topic: The topic to show help for. + + - :__command__ for commands. + - __section__\->__option__ for settings. + """ + if topic.startswith(':'): + command = topic[1:] + if command not in cmdutils.cmd_dict: + raise cmdexc.CommandError("Invalid command {}!".format( + command)) + path = 'commands.html#{}'.format(command) + elif '->' in topic: + parts = topic.split('->') + if len(parts) != 2: + raise cmdexc.CommandError("Invalid help topic {}!".format( + topic)) + try: + config.get(*parts) + except config.NoSectionError: + raise cmdexc.CommandError("Invalid section {}!".format( + parts[0])) + except config.NoOptionError: + raise cmdexc.CommandError("Invalid option {}!".format( + parts[1])) + path = 'settings.html#{}'.format(topic.replace('->', '-')) + else: + raise cmdexc.CommandError("Invalid help topic {}!".format(topic)) + self.openurl('qute://help/{}'.format(path)) + @cmdutils.register(instance='mainwindow.tabs.cmd', modes=[usertypes.KeyMode.insert], hide=True) diff --git a/qutebrowser/models/completion.py b/qutebrowser/models/completion.py index 6e09fca3d..39144ec86 100644 --- a/qutebrowser/models/completion.py +++ b/qutebrowser/models/completion.py @@ -58,7 +58,7 @@ class SettingOptionCompletionModel(basecompletion.BaseCompletionModel): sectdata = configdata.DATA[section] self._misc_items = {} self._section = section - for name, _ in sectdata.items(): + for name in sectdata.keys(): try: desc = sectdata.descriptions[name] except (KeyError, AttributeError): @@ -165,3 +165,44 @@ class CommandCompletionModel(basecompletion.BaseCompletionModel): cat = self.new_category("Commands") for (name, desc) in sorted(cmdlist): self.new_item(cat, name, desc) + + + +class HelpCompletionModel(basecompletion.BaseCompletionModel): + + """A CompletionModel filled with help topics.""" + + # pylint: disable=abstract-method + + def __init__(self, parent=None): + super().__init__(parent) + self._init_commands() + self._init_settings() + + def _init_commands(self): + assert cmdutils.cmd_dict + cmdlist = [] + for obj in set(cmdutils.cmd_dict.values()): + if obj.hide or (obj.debug and not + QCoreApplication.instance().args.debug): + pass + else: + cmdlist.append((':' + obj.name, obj.desc)) + cat = self.new_category("Commands") + for (name, desc) in sorted(cmdlist): + self.new_item(cat, name, desc) + + def _init_settings(self): + cat = self.new_category("Settings") + for sectname, sectdata in configdata.DATA.items(): + for optname in sectdata.keys(): + try: + desc = sectdata.descriptions[optname] + except (KeyError, AttributeError): + # Some stuff (especially ValueList items) don't have a + # description. + desc = "" + else: + desc = desc.splitlines()[0] + name = '{}->{}'.format(sectname, optname) + self.new_item(cat, name, desc) diff --git a/qutebrowser/network/qutescheme.py b/qutebrowser/network/qutescheme.py index a6046def9..6d1f33412 100644 --- a/qutebrowser/network/qutescheme.py +++ b/qutebrowser/network/qutescheme.py @@ -127,4 +127,5 @@ class QuteHandlers: def help(cls, request): """Handler for qute:help. Return HTML content as bytes.""" path = 'html/doc/{}'.format(request.url().path()) - return utils.read_file(path).encode('ASCII') + return utils.read_file(path).encode('UTF-8', + errors='xmlcharrefreplace') diff --git a/qutebrowser/utils/completer.py b/qutebrowser/utils/completer.py index a70bbe5f2..d24d5c62c 100644 --- a/qutebrowser/utils/completer.py +++ b/qutebrowser/utils/completer.py @@ -57,13 +57,15 @@ class Completer(QObject): usertypes.Completion.option: {}, usertypes.Completion.value: {}, } - self._init_command_completion() + self._init_static_completions() self._init_setting_completions() - def _init_command_completion(self): - """Initialize the command completion model.""" + def _init_static_completions(self): + """Initialize the static completion models.""" self._models[usertypes.Completion.command] = CFM( models.CommandCompletionModel(self), self) + self._models[usertypes.Completion.helptopic] = CFM( + models.HelpCompletionModel(self), self) def _init_setting_completions(self): """Initialize setting completion models.""" diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 2337b4be0..d48e8b759 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -248,7 +248,8 @@ KeyMode = enum('KeyMode', 'normal', 'hint', 'command', 'yesno', 'prompt', # Available command completions -Completion = enum('Completion', 'command', 'section', 'option', 'value') +Completion = enum('Completion', 'command', 'section', 'option', 'value', + 'helptopic') class Question(QObject):