From b5235f06b6ee438ad860ebd1322f5141070d42db Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 16:48:19 +0200 Subject: [PATCH 01/20] Generate categories --- scripts/generate_manpage.py | 95 +++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 scripts/generate_manpage.py diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py new file mode 100644 index 000000000..509512f46 --- /dev/null +++ b/scripts/generate_manpage.py @@ -0,0 +1,95 @@ +# Copyright 2014 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Generate asciidoc source for qutebrowser based on docstrings.""" + +import os +import sys +import inspect + +sys.path.insert(0, os.getcwd()) + +import qutebrowser.app +import qutebrowser.commands.utils as cmdutils +from qutebrowser.utils.usertypes import enum + + +def get_command_doc(name, func): + """Generates documentation based on a docstring of a command handler. + + The docstring needs to follow the format described in HACKING. + """ + State = enum('short', 'desc', 'arg_start', 'arg_inside') + + doc = inspect.getdoc(func) + lines = doc.splitlines() + + cur_state = State.short + + short_desc = [] + long_desc = [] + arg_descs = {} + cur_arg_name = None + + for line in lines: + if cur_state == State.short: + if not line: + cur_state = State.desc + else: + short_desc.append(line.strip()) + elif cur_state == State.desc: + if line.startswith('Args:'): + cur_state = State.arg_start + elif line.strip(): + long_desc.append(line.strip()) + elif cur_state == State.arg_start: + cur_arg_name, argdesc = line.split(':', maxsplit=1) + cur_arg_name = cur_arg_name.strip() + arg_descs[cur_arg_name] = [argdesc.strip()] + cur_state = State.arg_inside + elif cur_state == State.arg_inside: + if not line: + break + elif line[4:].startswith(' '): + arg_descs[cur_arg_name].append(line.strip()) + else: + cur_arg_name, argdesc = line.split(':', maxsplit=1) + cur_arg_name = cur_arg_name.strip() + arg_descs[cur_arg_name] = [argdesc.strip()] + + output = ['==== {}'.format(name)] + output.append(' '.join(short_desc)) + output.append("") + output.append(' '.join(long_desc)) + if arg_descs: + output.append("") + for arg, desc in arg_descs.items(): + output.append("* {}: {}".format(arg, ' '.join(desc))) + + output.append("") + output.append("") + return '\n'.join(output) + + +def generate_commands(): + print("== Commands") + print("=== Category") + for name, cmd in cmdutils.cmd_dict.items(): + print(get_command_doc(name, cmd.handler)) + + +generate_commands() From 94f6b8e5b441d217ffce4b1b390713d6835933dd Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 16:56:10 +0200 Subject: [PATCH 02/20] Move parse_docstring to own function --- scripts/generate_manpage.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 509512f46..addb3b7cd 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -28,13 +28,18 @@ import qutebrowser.commands.utils as cmdutils from qutebrowser.utils.usertypes import enum -def get_command_doc(name, func): +def parse_docstring(func): """Generates documentation based on a docstring of a command handler. The docstring needs to follow the format described in HACKING. + + Args: + func: The function to generate the docstring for. + + Return: + A (short_desc, long_desc, arg_descs) tuple. """ State = enum('short', 'desc', 'arg_start', 'arg_inside') - doc = inspect.getdoc(func) lines = doc.splitlines() @@ -71,14 +76,19 @@ def get_command_doc(name, func): cur_arg_name = cur_arg_name.strip() arg_descs[cur_arg_name] = [argdesc.strip()] + return (short_desc, long_desc, arg_descs) + + +def get_command_doc(name, func): output = ['==== {}'.format(name)] + short_desc, long_desc, arg_descs = parse_docstring(func) output.append(' '.join(short_desc)) output.append("") output.append(' '.join(long_desc)) if arg_descs: output.append("") for arg, desc in arg_descs.items(): - output.append("* {}: {}".format(arg, ' '.join(desc))) + output.append("* +{}+: {}".format(arg, ' '.join(desc))) output.append("") output.append("") From 441ebe645fa6baa5b334f7f278069c2bd824c1e1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 17:47:11 +0200 Subject: [PATCH 03/20] Add command syntax --- scripts/generate_manpage.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index addb3b7cd..9eb0240dc 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -79,17 +79,35 @@ def parse_docstring(func): return (short_desc, long_desc, arg_descs) -def get_command_doc(name, func): +def get_cmd_syntax(name, cmd): + words = [] + argspec = inspect.getfullargspec(cmd.handler) + words.append(name) + minargs, maxargs = cmd.nargs + i = 1 + for arg in argspec.args: + if arg in ['self', 'count']: + continue + if minargs is not None and i <= minargs: + words.append('_<{}>_'.format(arg)) + elif maxargs is None or i <= maxargs: + words.append('_[<{}>]_'.format(arg)) + i += 1 + return ' '.join(words) + +def get_command_doc(name, cmd): output = ['==== {}'.format(name)] - short_desc, long_desc, arg_descs = parse_docstring(func) + syntax = get_cmd_syntax(name, cmd) + output.append('+:{}+'.format(syntax)) + output.append("") + short_desc, long_desc, arg_descs = parse_docstring(cmd.handler) output.append(' '.join(short_desc)) output.append("") output.append(' '.join(long_desc)) if arg_descs: output.append("") for arg, desc in arg_descs.items(): - output.append("* +{}+: {}".format(arg, ' '.join(desc))) - + output.append("* +_{}_+: {}".format(arg, ' '.join(desc))) output.append("") output.append("") return '\n'.join(output) @@ -99,7 +117,7 @@ def generate_commands(): print("== Commands") print("=== Category") for name, cmd in cmdutils.cmd_dict.items(): - print(get_command_doc(name, cmd.handler)) + print(get_command_doc(name, cmd)) generate_commands() From 9694000a935aba141e74a2859216debe27410923 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 18:00:47 +0200 Subject: [PATCH 04/20] Print defaults --- scripts/generate_manpage.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 9eb0240dc..2e92d5431 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -82,6 +82,10 @@ def parse_docstring(func): def get_cmd_syntax(name, cmd): words = [] argspec = inspect.getfullargspec(cmd.handler) + if argspec.defaults is not None: + defaults = dict(zip(reversed(argspec.args), reversed(list(argspec.defaults)))) + else: + defaults = {} words.append(name) minargs, maxargs = cmd.nargs i = 1 @@ -93,11 +97,11 @@ def get_cmd_syntax(name, cmd): elif maxargs is None or i <= maxargs: words.append('_[<{}>]_'.format(arg)) i += 1 - return ' '.join(words) + return (' '.join(words), defaults) def get_command_doc(name, cmd): output = ['==== {}'.format(name)] - syntax = get_cmd_syntax(name, cmd) + syntax, defaults = get_cmd_syntax(name, cmd) output.append('+:{}+'.format(syntax)) output.append("") short_desc, long_desc, arg_descs = parse_docstring(cmd.handler) @@ -107,7 +111,10 @@ def get_command_doc(name, cmd): if arg_descs: output.append("") for arg, desc in arg_descs.items(): - output.append("* +_{}_+: {}".format(arg, ' '.join(desc))) + item = "* +_{}_+: {}".format(arg, ' '.join(desc)) + if arg in defaults: + item += " (default: +{}+)".format(defaults[arg]) + output.append(item) output.append("") output.append("") return '\n'.join(output) From 7bb8ba268bd27e2308beff1a099b54bf58510422 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 18:33:17 +0200 Subject: [PATCH 05/20] Sort commands --- scripts/generate_manpage.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 2e92d5431..0923bc0ef 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -122,9 +122,20 @@ def get_command_doc(name, cmd): def generate_commands(): print("== Commands") - print("=== Category") + normal_cmds = [] + hidden_cmds = [] for name, cmd in cmdutils.cmd_dict.items(): + if cmd.hide: + hidden_cmds.append((name, cmd)) + else: + normal_cmds.append((name, cmd)) + normal_cmds.sort() + hidden_cmds.sort() + print("=== Normal commands") + for name, cmd in normal_cmds: + print(get_command_doc(name, cmd)) + print("=== Hidden commands") + for name, cmd in hidden_cmds: print(get_command_doc(name, cmd)) - generate_commands() From c5d923f92eb67234b27052a281284c9b61771025 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 19:12:12 +0200 Subject: [PATCH 06/20] Add settings to documentation --- scripts/generate_manpage.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 0923bc0ef..0636b32f1 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -25,6 +25,7 @@ sys.path.insert(0, os.getcwd()) import qutebrowser.app import qutebrowser.commands.utils as cmdutils +import qutebrowser.config.configdata as configdata from qutebrowser.utils.usertypes import enum @@ -138,4 +139,33 @@ def generate_commands(): for name, cmd in hidden_cmds: print(get_command_doc(name, cmd)) + +def generate_settings(): + print("== Settings") + for sectname, sect in configdata.DATA.items(): + print() + print("=== {}".format(sectname)) + print(configdata.SECTION_DESC[sectname]) + if not getattr(sect, 'descriptions'): + pass + else: + for optname, option in sect.items(): + print() + print("==== {}".format(optname)) + print(sect.descriptions[optname]) + print() + valid_values = option.typ.valid_values + if valid_values is not None: + print("Valid values:") + print() + for val in valid_values: + try: + desc = valid_values.descriptions[val] + print(" * _{}_: {}".format(val, desc)) + except KeyError: + print(" * _{}_".format(val)) + + + +generate_settings() generate_commands() From a68738881903b08a19b2f1120e789bcde8bf47a2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 21:45:37 +0200 Subject: [PATCH 07/20] Change config descriptions to be asciidoc --- qutebrowser/config/configdata.py | 105 ++++++++++++++++--------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 9cd29f3b5..b5e3d8ecd 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -77,35 +77,35 @@ SECTION_DESC = { "The searchengine named DEFAULT is used when general.auto-search " "is true and something else than a URL was entered to be opened. " "Other search engines can be used via the bang-syntax, e.g. " - '"qutebrowser !google". The string "{}" will be replaced by the ' - 'search term, use "{{" and "}}" for literal {/} signs.'), + "+:open qutebrowser !google+. The string +{}+ will be replaced by the " + "search term, use +{{+ and +}}+ for literal +{+/+}+ signs."), 'keybind': ( "Bindings from a key(chain) to a command.\n" "For special keys (can't be part of a keychain), enclose them in " - "<...>. For modifiers, you can use either - or + as delimiters, and " - "these names:\n" - " Control: Control, Ctrl\n" - " Meta: Meta, Windows, Mod4\n" - " Alt: Alt, Mod1\n" - " Shift: Shift\n" - "For simple keys (no <>-signs), a capital letter means the key is " - "pressed with Shift. For special keys (with <>-signs), you need " - 'to explicitely add "Shift-" to match a key pressed with shift. ' - 'You can bind multiple commands by separating them with ";;".'), + "+<+_..._+>+. For modifiers, you can use either +-+ or +++ as " + "delimiters, and these names:\n\n" + " * Control: +Control+, +Ctrl+\n" + " * Meta: +Meta+, +Windows+, +Mod4+\n" + " * Alt: +Alt+, +Mod1+\n" + " * Shift: +Shift+\n\n" + "For simple keys (no +<>+-signs), a capital letter means the key is " + "pressed with Shift. For special keys (with +<>+-signs), you need " + "to explicitely add +Shift-+ to match a key pressed with shift. " + "You can bind multiple commands by separating them with +;;+."), 'keybind.insert': ( "Keybindings for insert mode.\n" "Since normal keypresses are passed through, only special keys are " "supported in this mode.\n" - "Useful hidden commands to map in this section:\n" - " open-editor: Open a texteditor with the focused field.\n" - " leave-mode: Leave the command mode."), + "Useful hidden commands to map in this section:\n\n" + " * +open-editor+: Open a texteditor with the focused field.\n" + " * +leave-mode+: Leave the command mode."), 'keybind.hint': ( "Keybindings for hint mode.\n" "Since normal keypresses are passed through, only special keys are " "supported in this mode.\n" - "Useful hidden commands to map in this section:\n" - " follow-hint: Follow the currently selected hint.\n" - " leave-mode: Leave the command mode."), + "Useful hidden commands to map in this section:\n\n" + " * +follow-hint+: Follow the currently selected hint.\n" + " * +leave-mode+: Leave the command mode."), 'keybind.passthrough': ( "Keybindings for passthrough mode.\n" "Since normal keypresses are passed through, only special keys are " @@ -115,53 +115,54 @@ SECTION_DESC = { "Keybindings for command mode.\n" "Since normal keypresses are passed through, only special keys are " "supported in this mode.\n" - "Useful hidden commands to map in this section:\n" - " command-history-prev: Switch to previous command in history.\n" - " command-history-next: Switch to next command in history.\n" - " completion-item-prev: Select previous item in completion.\n" - " completion-item-next: Select next item in completion.\n" - " command-accept: Execute the command currently in the commandline.\n" - " leave-mode: Leave the command mode."), + "Useful hidden commands to map in this section:\n\n" + " * +command-history-prev+: Switch to previous command in history.\n" + " * +command-history-next+: Switch to next command in history.\n" + " * +completion-item-prev+: Select previous item in completion.\n" + " * +completion-item-next+: Select next item in completion.\n" + " * +command-accept+: Execute the command currently in the " + "commandline.\n" + " * +leave-mode+: Leave the command mode."), 'keybind.prompt': ( "Keybindings for prompts in the status line.\n" "You can bind normal keys in this mode, but they will be only active " "when a yes/no-prompt is asked. For other prompt modes, you can only " "bind special keys.\n" - "Useful hidden commands to map in this section:\n" - " prompt-accept: Confirm the entered value.\n" - " prompt-yes: Answer yes to a yes/no question.\n" - " prompt-no: Answer no to a yes/no question.\n" - " leave-mode: Leave the prompt mode."), + "Useful hidden commands to map in this section:\n\n" + " * +prompt-accept+: Confirm the entered value.\n" + " * +prompt-yes+: Answer yes to a yes/no question.\n" + " * +prompt-no+: Answer no to a yes/no question.\n" + " * +leave-mode+: Leave the prompt mode."), 'aliases': ( "Aliases for commands.\n" "By default, no aliases are defined. Example which adds a new command " - ":qtb to open qutebrowsers website:\n" - " qtb = open http://www.qutebrowser.org/"), + "+:qtb+ to open qutebrowsers website:\n\n" + "+qtb = open http://www.qutebrowser.org/+"), 'colors': ( "Colors used in the UI.\n" - "A value can be in one of the following format:\n" - " - #RGB/#RRGGBB/#RRRGGGBBB/#RRRRGGGGBBBB\n" - " - A SVG color name as specified in [1].\n" - " - transparent (no color)\n" - " - rgb(r, g, b) / rgba(r, g, b, a) (values 0-255 or " + "A value can be in one of the following format:\n\n" + " * +#RGB+/+#RRGGBB+/+#RRRGGGBBB+/+#RRRRGGGGBBBB+\n" + " * A SVG color name as specified in http://www.w3.org/TR/SVG/" + "types.html#ColorKeywords[the W3C specification].\n" + " * transparent (no color)\n" + " * +rgb(r, g, b)+ / +rgba(r, g, b, a)+ (values 0-255 or " "percentages)\n" - " - hsv(h, s, v) / hsva(h, s, v, a) (values 0-255, hue 0-359)\n" - ' - A gradient as explained at [2] under "Gradient"\n' - " [1] http://www.w3.org/TR/SVG/types.html#ColorKeywords\n" - " [2] http://qt-project.org/doc/qt-4.8/stylesheet-reference.html" - "#list-of-property-types\n" - 'The "hints.*" values are a special case as they\'re real CSS ' + " * +hsv(h, s, v)+ / +hsva(h, s, v, a)+ (values 0-255, hue 0-359)\n" + " * A gradient as explained in http://qt-project.org/doc/qt-4.8/" + "stylesheet-reference.html#list-of-property-types[the Qt " + "documentation] under ``Gradient''.\n\n" + "The +hints.*+ values are a special case as they're real CSS " "colors, not Qt-CSS colors. There, for a gradient, you need to use " - "-webkit-gradient, see [3].\n" - " [3] https://www.webkit.org/blog/175/introducing-css-gradients/"), + "+-webkit-gradient+, see https://www.webkit.org/blog/175/introducing-" + "css-gradients/[the WebKit documentation].\n"), 'fonts': ( - "Fonts used for the UI, with optional style/weight/size.\n" - " Style: normal/italic/oblique\n" - " Weight: normal, bold, 100..900\n" - " Size: Number + px/pt\n" + "Fonts used for the UI, with optional style/weight/size.\n\n" + " * Style: +normal+/+italic+/+oblique+\n" + " * Weight: +normal+, +bold+, 100..900\n" + " * Size: Number + +px+/+pt+\n" "Note: The font for hints is a true CSS font, not a Qt-CSS one, " - 'because of that, a general "Monospace" family is enough and we ' - 'don\'t use "${_monospace}" there.'), + "because of that, a general ``Monospace'' family is enough and we " + "don't use +${_monospace}+ there."), } @@ -200,7 +201,7 @@ DATA = OrderedDict([ ('editor', SettingValue(types.ShellCommand(placeholder=True), 'gvim -f "{}"'), "The editor (and arguments) to use for the open-editor binding. " - "Use {} for the filename. Gets split via shutils."), + "Use +{}+ for the filename. Gets split via shutils."), ('private-browsing', SettingValue(types.Bool(), 'false'), From 1d0fa621b6ab5827e5f27415cb4cb7bb1fee7d06 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 22:39:02 +0200 Subject: [PATCH 08/20] Formatting fixes --- qutebrowser/config/configdata.py | 81 ++++++++++++++++---------------- qutebrowser/config/value.py | 5 ++ scripts/generate_manpage.py | 13 ++++- 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index b5e3d8ecd..8b9fb064e 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -74,38 +74,39 @@ SECTION_DESC = { 'searchengines': ( "Definitions of search engines which can be used via the address " "bar.\n" - "The searchengine named DEFAULT is used when general.auto-search " - "is true and something else than a URL was entered to be opened. " - "Other search engines can be used via the bang-syntax, e.g. " - "+:open qutebrowser !google+. The string +{}+ will be replaced by the " - "search term, use +{{+ and +}}+ for literal +{+/+}+ signs."), + "The searchengine named `DEFAULT` is used when " + "`general -> auto-search` is true and something else than a URL was " + "entered to be opened. Other search engines can be used via the " + "bang-syntax, e.g. `:open qutebrowser !google`. The string `{}` will " + "be replaced by the search term, use `{{` and `}}` for literal " + "`{`/`}` signs."), 'keybind': ( "Bindings from a key(chain) to a command.\n" "For special keys (can't be part of a keychain), enclose them in " - "+<+_..._+>+. For modifiers, you can use either +-+ or +++ as " + "`<`...`>`. For modifiers, you can use either `-` or `+` as " "delimiters, and these names:\n\n" - " * Control: +Control+, +Ctrl+\n" - " * Meta: +Meta+, +Windows+, +Mod4+\n" - " * Alt: +Alt+, +Mod1+\n" - " * Shift: +Shift+\n\n" - "For simple keys (no +<>+-signs), a capital letter means the key is " - "pressed with Shift. For special keys (with +<>+-signs), you need " - "to explicitely add +Shift-+ to match a key pressed with shift. " - "You can bind multiple commands by separating them with +;;+."), + " * Control: `Control`, `Ctrl`\n" + " * Meta: `Meta`, `Windows`, `Mod4`\n" + " * Alt: `Alt`, `Mod1`\n" + " * Shift: `Shift`\n\n" + "For simple keys (no `<>`-signs), a capital letter means the key is " + "pressed with Shift. For special keys (with `<>`-signs), you need " + "to explicitely add `Shift-` to match a key pressed with shift. " + "You can bind multiple commands by separating them with `;;`."), 'keybind.insert': ( "Keybindings for insert mode.\n" "Since normal keypresses are passed through, only special keys are " "supported in this mode.\n" "Useful hidden commands to map in this section:\n\n" - " * +open-editor+: Open a texteditor with the focused field.\n" - " * +leave-mode+: Leave the command mode."), + " * `open-editor`: Open a texteditor with the focused field.\n" + " * `leave-mode`: Leave the command mode."), 'keybind.hint': ( "Keybindings for hint mode.\n" "Since normal keypresses are passed through, only special keys are " "supported in this mode.\n" "Useful hidden commands to map in this section:\n\n" - " * +follow-hint+: Follow the currently selected hint.\n" - " * +leave-mode+: Leave the command mode."), + " * `follow-hint`: Follow the currently selected hint.\n" + " * `leave-mode`: Leave the command mode."), 'keybind.passthrough': ( "Keybindings for passthrough mode.\n" "Since normal keypresses are passed through, only special keys are " @@ -116,53 +117,53 @@ SECTION_DESC = { "Since normal keypresses are passed through, only special keys are " "supported in this mode.\n" "Useful hidden commands to map in this section:\n\n" - " * +command-history-prev+: Switch to previous command in history.\n" - " * +command-history-next+: Switch to next command in history.\n" - " * +completion-item-prev+: Select previous item in completion.\n" - " * +completion-item-next+: Select next item in completion.\n" - " * +command-accept+: Execute the command currently in the " + " * `command-history-prev`: Switch to previous command in history.\n" + " * `command-history-next`: Switch to next command in history.\n" + " * `completion-item-prev`: Select previous item in completion.\n" + " * `completion-item-next`: Select next item in completion.\n" + " * `command-accept`: Execute the command currently in the " "commandline.\n" - " * +leave-mode+: Leave the command mode."), + " * `leave-mode`: Leave the command mode."), 'keybind.prompt': ( "Keybindings for prompts in the status line.\n" "You can bind normal keys in this mode, but they will be only active " "when a yes/no-prompt is asked. For other prompt modes, you can only " "bind special keys.\n" "Useful hidden commands to map in this section:\n\n" - " * +prompt-accept+: Confirm the entered value.\n" - " * +prompt-yes+: Answer yes to a yes/no question.\n" - " * +prompt-no+: Answer no to a yes/no question.\n" - " * +leave-mode+: Leave the prompt mode."), + " * `prompt-accept`: Confirm the entered value.\n" + " * `prompt-yes`: Answer yes to a yes/no question.\n" + " * `prompt-no`: Answer no to a yes/no question.\n" + " * `leave-mode`: Leave the prompt mode."), 'aliases': ( "Aliases for commands.\n" "By default, no aliases are defined. Example which adds a new command " - "+:qtb+ to open qutebrowsers website:\n\n" - "+qtb = open http://www.qutebrowser.org/+"), + "`:qtb` to open qutebrowsers website:\n\n" + "`qtb = open http://www.qutebrowser.org/`"), 'colors': ( "Colors used in the UI.\n" "A value can be in one of the following format:\n\n" - " * +#RGB+/+#RRGGBB+/+#RRRGGGBBB+/+#RRRRGGGGBBBB+\n" + " * `#RGB`/`#RRGGBB`/`#RRRGGGBBB`/`#RRRRGGGGBBBB`\n" " * A SVG color name as specified in http://www.w3.org/TR/SVG/" "types.html#ColorKeywords[the W3C specification].\n" " * transparent (no color)\n" - " * +rgb(r, g, b)+ / +rgba(r, g, b, a)+ (values 0-255 or " + " * `rgb(r, g, b)` / `rgba(r, g, b, a)` (values 0-255 or " "percentages)\n" - " * +hsv(h, s, v)+ / +hsva(h, s, v, a)+ (values 0-255, hue 0-359)\n" + " * `hsv(h, s, v)` / `hsva(h, s, v, a)` (values 0-255, hue 0-359)\n" " * A gradient as explained in http://qt-project.org/doc/qt-4.8/" "stylesheet-reference.html#list-of-property-types[the Qt " "documentation] under ``Gradient''.\n\n" - "The +hints.*+ values are a special case as they're real CSS " + "The `hints.*` values are a special case as they're real CSS " "colors, not Qt-CSS colors. There, for a gradient, you need to use " - "+-webkit-gradient+, see https://www.webkit.org/blog/175/introducing-" + "`-webkit-gradient`, see https://www.webkit.org/blog/175/introducing-" "css-gradients/[the WebKit documentation].\n"), 'fonts': ( "Fonts used for the UI, with optional style/weight/size.\n\n" - " * Style: +normal+/+italic+/+oblique+\n" - " * Weight: +normal+, +bold+, 100..900\n" - " * Size: Number + +px+/+pt+\n" + " * Style: `normal`/`italic`/`oblique`\n" + " * Weight: `normal`, `bold`, 100..900\n" + " * Size: _number_ `px`/`pt`\n\n" "Note: The font for hints is a true CSS font, not a Qt-CSS one, " "because of that, a general ``Monospace'' family is enough and we " - "don't use +${_monospace}+ there."), + "don't use `${_monospace}` there."), } @@ -201,7 +202,7 @@ DATA = OrderedDict([ ('editor', SettingValue(types.ShellCommand(placeholder=True), 'gvim -f "{}"'), "The editor (and arguments) to use for the open-editor binding. " - "Use +{}+ for the filename. Gets split via shutils."), + "Use `{}` for the filename. Gets split via shutils."), ('private-browsing', SettingValue(types.Bool(), 'false'), diff --git a/qutebrowser/config/value.py b/qutebrowser/config/value.py index 98453cccb..c0e8ad294 100644 --- a/qutebrowser/config/value.py +++ b/qutebrowser/config/value.py @@ -55,6 +55,11 @@ class SettingValue: """Get the currently valid value.""" return self.get_first_value() + @property + def default(self): + """Get the default value.""" + return self._values['default'] + @property def values(self): """Readonly property for _values.""" diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 0636b32f1..1b28ae3ba 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -122,6 +122,7 @@ def get_command_doc(name, cmd): def generate_commands(): + print() print("== Commands") normal_cmds = [] hidden_cmds = [] @@ -132,15 +133,18 @@ def generate_commands(): normal_cmds.append((name, cmd)) normal_cmds.sort() hidden_cmds.sort() + print() print("=== Normal commands") for name, cmd in normal_cmds: print(get_command_doc(name, cmd)) + print() print("=== Hidden commands") for name, cmd in hidden_cmds: print(get_command_doc(name, cmd)) def generate_settings(): + print() print("== Settings") for sectname, sect in configdata.DATA.items(): print() @@ -161,9 +165,14 @@ def generate_settings(): for val in valid_values: try: desc = valid_values.descriptions[val] - print(" * _{}_: {}".format(val, desc)) + print(" * +{}+: {}".format(val, desc)) except KeyError: - print(" * _{}_".format(val)) + print(" * +{}+".format(val)) + print() + if option.default: + print("Default: +pass:[{}]+".format(option.default)) + else: + print("Default: empty") From 1bef7fb3c1f5e99aff90105c4151e249305f8199 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 May 2014 00:54:30 +0200 Subject: [PATCH 09/20] Add quick references for settings/commands --- scripts/generate_manpage.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 1b28ae3ba..40b529eef 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -100,6 +100,35 @@ def get_cmd_syntax(name, cmd): i += 1 return (' '.join(words), defaults) + +def get_command_quickref(cmds): + out = [] + out.append('[options="header",width="75%"]') + out.append('|==============') + out.append('|Command|Description') + for name, cmd in cmds: + desc = inspect.getdoc(cmd.handler).splitlines()[0] + out.append('|{}|{}'.format(name, desc)) + out.append('|==============') + return '\n'.join(out) + + +def get_setting_quickref(): + out = [] + for sectname, sect in configdata.DATA.items(): + if not getattr(sect, 'descriptions'): + continue + out.append(".Quick reference for section ``{}''".format(sectname)) + out.append('[options="header",width="75%"]') + out.append('|==============') + out.append('|Setting|Description') + for optname, option in sect.items(): + desc = sect.descriptions[optname] + out.append('|{}|{}'.format(optname, desc)) + out.append('|==============') + return '\n'.join(out) + + def get_command_doc(name, cmd): output = ['==== {}'.format(name)] syntax, defaults = get_cmd_syntax(name, cmd) @@ -135,10 +164,14 @@ def generate_commands(): hidden_cmds.sort() print() print("=== Normal commands") + print(".Quick reference") + print(get_command_quickref(normal_cmds)) for name, cmd in normal_cmds: print(get_command_doc(name, cmd)) print() print("=== Hidden commands") + print(".Quick reference") + print(get_command_quickref(hidden_cmds)) for name, cmd in hidden_cmds: print(get_command_doc(name, cmd)) @@ -146,6 +179,7 @@ def generate_commands(): def generate_settings(): print() print("== Settings") + print(get_setting_quickref()) for sectname, sect in configdata.DATA.items(): print() print("=== {}".format(sectname)) From dc107f94b939b73f59665261f224a22bfd857f2f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 May 2014 00:57:30 +0200 Subject: [PATCH 10/20] Add header --- scripts/generate_manpage.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 40b529eef..a560b650c 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -150,6 +150,13 @@ def get_command_doc(name, cmd): return '\n'.join(output) +def generate_header(): + print('= qutebrowser manpage') + print('Florian Bruhin ') + print(':toc:') + print(':hoempage: http://www.qutebrowser.org/') + + def generate_commands(): print() print("== Commands") @@ -209,6 +216,6 @@ def generate_settings(): print("Default: empty") - +generate_header() generate_settings() generate_commands() From 8b5e23dd6623411a35664f9073f58f651f160d47 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 May 2014 21:08:22 +0200 Subject: [PATCH 11/20] Add links to command quickref --- scripts/generate_manpage.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index a560b650c..bc13fe9b7 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -108,7 +108,7 @@ def get_command_quickref(cmds): out.append('|Command|Description') for name, cmd in cmds: desc = inspect.getdoc(cmd.handler).splitlines()[0] - out.append('|{}|{}'.format(name, desc)) + out.append('|<>|{}'.format(name, name, desc)) out.append('|==============') return '\n'.join(out) @@ -124,13 +124,15 @@ def get_setting_quickref(): out.append('|Setting|Description') for optname, option in sect.items(): desc = sect.descriptions[optname] - out.append('|{}|{}'.format(optname, desc)) + out.append('|<>|{}'.format( + sectname, optname, optname, desc)) out.append('|==============') return '\n'.join(out) def get_command_doc(name, cmd): - output = ['==== {}'.format(name)] + output = ['[[cmd-{}]]'.format(name)] + output += ['==== {}'.format(name)] syntax, defaults = get_cmd_syntax(name, cmd) output.append('+:{}+'.format(syntax)) output.append("") @@ -196,6 +198,7 @@ def generate_settings(): else: for optname, option in sect.items(): print() + print('[[setting-{}-{}]]'.format(sectname, optname)) print("==== {}".format(optname)) print(sect.descriptions[optname]) print() From 8afb20c226ae1199f07e7c427df0db5e86974f98 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 29 May 2014 21:38:06 +0200 Subject: [PATCH 12/20] Specify column widths --- scripts/generate_manpage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index bc13fe9b7..5655dbdbe 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -103,7 +103,7 @@ def get_cmd_syntax(name, cmd): def get_command_quickref(cmds): out = [] - out.append('[options="header",width="75%"]') + out.append('[options="header",width="75%",cols="25%,75%"]') out.append('|==============') out.append('|Command|Description') for name, cmd in cmds: @@ -119,7 +119,7 @@ def get_setting_quickref(): if not getattr(sect, 'descriptions'): continue out.append(".Quick reference for section ``{}''".format(sectname)) - out.append('[options="header",width="75%"]') + out.append('[options="header",width="75%",cols="25%,75%"]') out.append('|==============') out.append('|Setting|Description') for optname, option in sect.items(): From 42c9cdf97adaaed7f87060283e3015f887833db2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 2 Jun 2014 15:04:25 +0200 Subject: [PATCH 13/20] Escape HTML chars in passthrough --- scripts/generate_manpage.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 5655dbdbe..06e0e492c 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -19,6 +19,7 @@ import os import sys +import cgi import inspect sys.path.insert(0, os.getcwd()) @@ -214,7 +215,8 @@ def generate_settings(): print(" * +{}+".format(val)) print() if option.default: - print("Default: +pass:[{}]+".format(option.default)) + print("Default: +pass:[{}]+".format(cgi.escape( + option.default))) else: print("Default: empty") From fe814df3c20645c70d8accd0633fca335fb913f1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 2 Jun 2014 15:04:57 +0200 Subject: [PATCH 14/20] Fix homepage spelling --- scripts/generate_manpage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 06e0e492c..726e0814d 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -157,7 +157,7 @@ def generate_header(): print('= qutebrowser manpage') print('Florian Bruhin ') print(':toc:') - print(':hoempage: http://www.qutebrowser.org/') + print(':homepage: http://www.qutebrowser.org/') def generate_commands(): From 44c3ef2bed4452264e2e69c1a95c76d8c1b46d67 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 2 Jun 2014 15:05:10 +0200 Subject: [PATCH 15/20] Add NAME section --- scripts/generate_manpage.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 726e0814d..95d5304f5 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -158,6 +158,7 @@ def generate_header(): print('Florian Bruhin ') print(':toc:') print(':homepage: http://www.qutebrowser.org/') + print("== NAME") def generate_commands(): From dd601ab9b6f1203c413992da2e97c224d31ca39c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 2 Jun 2014 15:05:17 +0200 Subject: [PATCH 16/20] Don't use _foo_ inside +foo+. --- scripts/generate_manpage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 95d5304f5..17187d844 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -95,9 +95,9 @@ def get_cmd_syntax(name, cmd): if arg in ['self', 'count']: continue if minargs is not None and i <= minargs: - words.append('_<{}>_'.format(arg)) + words.append('<{}>'.format(arg)) elif maxargs is None or i <= maxargs: - words.append('_[<{}>]_'.format(arg)) + words.append('[<{}>]'.format(arg)) i += 1 return (' '.join(words), defaults) @@ -144,7 +144,7 @@ def get_command_doc(name, cmd): if arg_descs: output.append("") for arg, desc in arg_descs.items(): - item = "* +_{}_+: {}".format(arg, ' '.join(desc)) + item = "* +{}+: {}".format(arg, ' '.join(desc)) if arg in defaults: item += " (default: +{}+)".format(defaults[arg]) output.append(item) From 1c65a38254c6ca3acbf64c2bf4dace7f46eea4a4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 26 Jun 2014 06:35:57 +0200 Subject: [PATCH 17/20] Add debug commands to manpage separately --- scripts/generate_manpage.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 17187d844..5599c69e6 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -166,13 +166,17 @@ def generate_commands(): print("== Commands") normal_cmds = [] hidden_cmds = [] + debug_cmds = [] for name, cmd in cmdutils.cmd_dict.items(): if cmd.hide: hidden_cmds.append((name, cmd)) + elif cmd.debug: + debug_cmds.append((name, cmd)) else: normal_cmds.append((name, cmd)) normal_cmds.sort() hidden_cmds.sort() + debug_cmds.sort() print() print("=== Normal commands") print(".Quick reference") @@ -185,6 +189,15 @@ def generate_commands(): print(get_command_quickref(hidden_cmds)) for name, cmd in hidden_cmds: print(get_command_doc(name, cmd)) + print() + print("=== Debugging commands") + print("These commands are mainly intended for debugging. They are hidden " + "if qutebrowser was started without the `--debug`-flag.") + print() + print(".Quick reference") + print(get_command_quickref(debug_cmds)) + for name, cmd in debug_cmds: + print(get_command_doc(name, cmd)) def generate_settings(): From 62300a82906c947d7c5ff2dfea76f12ccb611e95 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 26 Jun 2014 20:11:10 +0200 Subject: [PATCH 18/20] Github README updates --- README.asciidoc | 119 ++++++++++++++++++++++++++++++++++++++------ doc/THANKS.asciidoc | 53 -------------------- 2 files changed, 104 insertions(+), 68 deletions(-) delete mode 100644 doc/THANKS.asciidoc diff --git a/README.asciidoc b/README.asciidoc index 4d3b5c8b7..a330fab03 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -1,15 +1,13 @@ -qutebrowser readme -================== +qutebrowser +=========== -About qutebrowser ------------------ +_A keyboard-driven, vim-like browser based on PyQt5 and QtWebKit._ -qutebrowser is a browser based on PyQt5 which aims to be keyboard-focused with -an input similar to vim. +qutebrowser is a keyboard-focused browser with with a minimal GUI. It's based +on Python, PyQt5 and QtWebKit and free software, licensed under the GPL. It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl. - Getting help ------------ @@ -21,7 +19,33 @@ message to the https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at mailto:qutebrowser@lists.qutebrowser.org[]. +Running qutebrowser +------------------- +After installing the <>, you have these options: + +* Run qutebrowser directly via `python3 -m qutebrowser`. Note executing +qutebrowser.py directly as script won't work, as Python won't recognize the +module. +* Run `python3 setup.py install` to install qutebrowser, then call +`qutebrowser`. + +Contributions / Bugs +-------------------- + +You want to contribute to qutebrowser? Awesome! Please read +link:doc/HACKING.asciidoc[HACKING] for details and useful hints. + +If you found a bug or have a feature request, you can report it in several +ways: + +* Use the built-in `:report` command or the automatic crash dialog. +* Open an issue in the Github issue tracker. +* Write a mail to the +https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at +mailto:qutebrowser@lists.qutebrowser.org[]. + +[[requirements]] Requirements ------------ @@ -33,27 +57,92 @@ The following software and libraries are required to run qutebrowser: * http://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.2 or newer (5.3.1 recommended) for Python 3 * https://pypi.python.org/pypi/setuptools/[pkg_resources/setuptools] +* https://github.com/g2p/rfc6266[rfc6266] The following libraries are optional and provide better debugging: * https://pypi.python.org/pypi/colorlog/[colorlog] * On Windows: https://pypi.python.org/pypi/colorama/[colorama] -.On Debian: +On Debian +~~~~~~~~~ - apt-get install python3-pyqt5 python3-pyqt5.qtwebkit python3-pkg-resources +---- +# apt-get install python3-pyqt5 python3-pyqt5.qtwebkit python3-pkg-resources +# pip3 install rfc6266 +---- -.On Archlinux: +On Archlinux +~~~~~~~~~~~~ - pacman -S python-pyqt5 qt5-webkit python-setuptools +Install https://aur.archlinux.org/packages/qutebrowser-git/[qutebrowser-git] +from the AUR. -Note an Archlinux AUR package is available. - -.On Windows: +On Windows +~~~~~~~~~~ Use the installer from http://www.python.org/downloads[python.org] to get Python 3 and the installer from http://www.riverbankcomputing.com/software/pyqt/download5[Riverbank computing] to get Qt and PyQt5. Run `scripts/ez_setup.py` to get setuptools. -Note a standalone .EXE is available. +Note a standalone .exe is available. + +Authors +------- + +include::doc/AUTHORS.asciidoc[] + +Thanks / Similiar projects +-------------------------- + +Many projects with a similiar goal as qutebrowser exist: + +* http://portix.bitbucket.org/dwb/[dwb] +* https://github.com/fanglingsu/vimb[vimb] +* http://sourceforge.net/projects/vimprobable/[vimprobable] +* https://mason-larobina.github.io/luakit/[luakit] +* http://pwmt.org/projects/jumanji/[jumanji] +* http://conkeror.org/[conkeror] +* http://surf.suckless.org/[surf] +* http://www.uzbl.org/[uzbl] +* http://www.vimperator.org/[Vimperator] (Firefox addon) +* http://5digits.org/pentadactyl/[Pentadactyl] (Firefox addon) +* https://github.com/akhodakivskiy/VimFx[VimFx] (Firefox addon) +* http://vimium.github.io/[vimium] (Chrome/Chromium addon) + +Most of them were inspirations for qutebrowser in some way, thanks for that! + +Thanks as well to the following projects and people for helping me with +problems and helpful hints: + +* http://eric-ide.python-projects.org/[eric5] / Detlev Offenbach +* https://code.google.com/p/devicenzo/[devicenzo] +* portix +* seir +* nitroxleecher + +Also, thanks to: + +* Everyone who had the patience to test qutebrowser before v0.1. +* Everyone triaging/fixing my bugs in the +https://bugreports.qt-project.org/secure/Dashboard.jspa[Qt bugtracker] +* Everyone answering my questions on http://stackoverflow.com/[Stack Overflow] +and in IRC. +* All the projects which were a great help while developing qutebrowser. + +License +------- + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/doc/THANKS.asciidoc b/doc/THANKS.asciidoc deleted file mode 100644 index 405596064..000000000 --- a/doc/THANKS.asciidoc +++ /dev/null @@ -1,53 +0,0 @@ -Thanks -====== - -Thanks to the following projects, which were a source for great inspiration: - -* http://eric-ide.python-projects.org/[eric5] -* http://portix.bitbucket.org/dwb/[dwb] -* http://www.vimperator.org/[Vimperator] -* http://5digits.org/pentadactyl/[Pentadactyl] -* https://github.com/fanglingsu/vimb[vimb] -* http://vimium.github.io/[vimium] -* https://code.google.com/p/devicenzo/[devicenzo] - -Thanks to the following people for helping me with problems big and small: - -* portix -* Detlev Offenbach -* seir -* nitroxleecher - -Thanks to the following people for early testing: - -* V155 -* eto -* portix -* iggy -* meisterT_ -* hrnz -* pedromj -* china -* Tsutsukakushi -* seir -* raven_ch -* rieper -* thorsten` - -Thanks to everone answering my and other questions on Stackoverflow and the IRC. - -Thanks to the people triaging bugs in the Qt bugtracker. - -Thanks to these projects which were essential while developing qutebrowser, and -all their contributors: - -* http://www.python.org/[Python] -* http://www.vim.org/[vim] -* http://git-scm.com/[git] -* http://qt-project.org/[Qt] -* http://www.riverbankcomputing.com/software/pyqt/intro[PyQt] -* http://www.pylint.org/[pylint] -* https://pypi.python.org/pypi/pyflakes[pyflakes] -* https://pypi.python.org/pypi/pep8/[pep8] -* https://github.com/GreenSteam/pep257/[pep257] -* https://pypi.python.org/pypi/flake8[flake8] From a2c9e099f0831b38ede2e94af3e2d024587287f9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 26 Jun 2014 20:14:05 +0200 Subject: [PATCH 19/20] Make authors a list --- doc/AUTHORS.asciidoc | 2 +- scripts/generate_authors.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/AUTHORS.asciidoc b/doc/AUTHORS.asciidoc index 2c07aa61f..a091ae32d 100644 --- a/doc/AUTHORS.asciidoc +++ b/doc/AUTHORS.asciidoc @@ -1,3 +1,3 @@ Contributors, sorted by the number of commits in descending order: -Florian Bruhin +* Florian Bruhin diff --git a/scripts/generate_authors.py b/scripts/generate_authors.py index cd3ac4ac4..999e5e148 100644 --- a/scripts/generate_authors.py +++ b/scripts/generate_authors.py @@ -27,9 +27,9 @@ from collections import Counter commits = subprocess.check_output(['git', 'log', '--format=%aN']) cnt = Counter(commits.decode('utf-8').splitlines()) -with open('AUTHORS', 'w', newline='\n', encoding='utf-8') as f: +with open('doc/AUTHORS.asciidoc', 'w', newline='\n', encoding='utf-8') as f: f.write("Contributors, sorted by the number of commits in descending " "order:\n\n") for author in sorted(cnt, key=lambda k: cnt[k]): - f.write(author) + f.write('* ' + author) f.write('\n') From f7304298abdad53a257ba7eb53f30326fd514200 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Jul 2014 20:09:41 +0200 Subject: [PATCH 20/20] Separate docstrings into command/documentation parts. --- doc/HACKING.asciidoc | 11 +++++++++++ qutebrowser/app.py | 2 ++ qutebrowser/browser/commands.py | 4 ++++ qutebrowser/config/config.py | 6 ++++++ qutebrowser/utils/debug.py | 4 +++- qutebrowser/widgets/mainwindow.py | 7 ++++++- qutebrowser/widgets/statusbar/prompter.py | 4 +++- scripts/generate_manpage.py | 15 ++++++++++++++- 8 files changed, 49 insertions(+), 4 deletions(-) diff --git a/doc/HACKING.asciidoc b/doc/HACKING.asciidoc index 4d1df37d2..374907bc6 100644 --- a/doc/HACKING.asciidoc +++ b/doc/HACKING.asciidoc @@ -346,6 +346,11 @@ http://legacy.python.org/dev/peps/pep-0008/[PEP8] and the https://google-stylegu http://legacy.python.org/dev/peps/pep-0257/[PEP257] and the google guidelines. * Class docstrings have additional _Attributes:_, _Class attributes:_ and _Signals:_ sections, method/function docstrings have an _Emit:_ section. +* In docstrings of command handlers (registered via `@cmdutils.register`), the +description should be split into two parts by using `//` - the first part is +the description of the command like it will appear in the documentation, the +second part is "internal" documentation only relevant to people reading the +sourcecode. + Example for a class docstring: + @@ -368,6 +373,12 @@ Example for a method/function docstring: ---- """Do something special. +This will do something. + +// + +It is based on http://example.com/. + Args: foo: ... diff --git a/qutebrowser/app.py b/qutebrowser/app.py index d61a1f087..4827b76a9 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -616,6 +616,8 @@ class Application(QApplication): def debug_pyeval(self, s): """Evaluate a python string and display the results as a webpage. + // + We have this here rather in utils.debug so the context of eval makes more sense and because we don't want to import much stuff in the utils. diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index b856b7717..e0d8690f3 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -619,6 +619,8 @@ class CommandDispatcher: The command will be run in a shell, so you can use shell features like redirections. + // + We use subprocess rather than Qt's QProcess here because of it's shell=True argument and because we really don't care about the process anymore as soon as it's spawned. @@ -706,6 +708,8 @@ class CommandDispatcher: def open_editor(self): """Open an external editor with the current form field. + // + We use QProcess rather than subprocess here because it makes it a lot easier to execute some code as soon as the process has been finished and do everything async. diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index f92acb134..0568e3791 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -287,6 +287,8 @@ class ConfigManager(QObject): def get_wrapper(self, sectname, optname): """Get the value from a section/option. + // + Wrapper for the get-command to output the value in the status bar. """ try: @@ -331,6 +333,8 @@ class ConfigManager(QObject): def set_wrapper(self, sectname, optname, value): """Set an option. + // + Wrapper for self.set() to output exceptions in the status bar. """ try: @@ -344,6 +348,8 @@ class ConfigManager(QObject): def set_temp_wrapper(self, sectname, optname, value): """Set a temporary option. + // + Wrapper for self.set() to output exceptions in the status bar. """ try: diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py index c8b3f443a..e9d998e3f 100644 --- a/qutebrowser/utils/debug.py +++ b/qutebrowser/utils/debug.py @@ -34,7 +34,9 @@ import qutebrowser.commands.utils as cmdutils @cmdutils.register(debug=True, name='debug-set-trace') def set_trace(): - """Set a tracepoint in the Python debugger that works with Qt. + """Break into the debugger in the shell. + + // Based on http://stackoverflow.com/a/1745965/2085149 """ diff --git a/qutebrowser/widgets/mainwindow.py b/qutebrowser/widgets/mainwindow.py index 09d47bb5f..173c408bd 100644 --- a/qutebrowser/widgets/mainwindow.py +++ b/qutebrowser/widgets/mainwindow.py @@ -148,7 +148,12 @@ class MainWindow(QWidget): @cmdutils.register(instance='mainwindow', name=['quit', 'q'], nargs=0) def close(self): - """Extend close() so we can register it as a command.""" + """Quit qutebrowser. + + // + + Extend close() so we can register it as a command. + """ super().close() def resizeEvent(self, e): diff --git a/qutebrowser/widgets/statusbar/prompter.py b/qutebrowser/widgets/statusbar/prompter.py index 7250c4aac..b4b63b49f 100644 --- a/qutebrowser/widgets/statusbar/prompter.py +++ b/qutebrowser/widgets/statusbar/prompter.py @@ -171,7 +171,9 @@ class Prompter: @cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True, modes=['prompt']) def prompt_accept(self): - """Accept the prompt. + """Accept the current prompt. + + // This executes the next action depending on the question mode, e.g. asks for the password or leaves the mode. diff --git a/scripts/generate_manpage.py b/scripts/generate_manpage.py index 5599c69e6..e8ccb4803 100644 --- a/scripts/generate_manpage.py +++ b/scripts/generate_manpage.py @@ -41,7 +41,8 @@ def parse_docstring(func): Return: A (short_desc, long_desc, arg_descs) tuple. """ - State = enum('short', 'desc', 'arg_start', 'arg_inside') + State = enum('short', 'desc', 'desc_hidden', 'arg_start', 'arg_inside', + 'misc') doc = inspect.getdoc(func) lines = doc.splitlines() @@ -61,8 +62,20 @@ def parse_docstring(func): elif cur_state == State.desc: if line.startswith('Args:'): cur_state = State.arg_start + elif line.startswith('Emit:') or line.startswith('Raise:'): + cur_state = State.misc + elif line.strip() == '//': + cur_state = State.desc_hidden elif line.strip(): long_desc.append(line.strip()) + elif cur_state == State.misc: + if line.startswith('Args:'): + cur_state = State.arg_start + else: + pass + elif cur_state == State.desc_hidden: + if line.startswith('Args:'): + cur_state = State.arg_start elif cur_state == State.arg_start: cur_arg_name, argdesc = line.split(':', maxsplit=1) cur_arg_name = cur_arg_name.strip()