diff --git a/README.asciidoc b/README.asciidoc index bf6225062..c7f3ebc48 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -50,6 +50,7 @@ image:https://qutebrowser.org/img/cheatsheet-small.png["qutebrowser key binding * link:doc/quickstart.asciidoc[Quick start guide] * A https://www.shortcutfoo.com/app/dojos/qutebrowser[free training course] to remember those key bindings. * link:FAQ.asciidoc[Frequently asked questions] +* link:doc/help/configuring.html[Configuring qutebrowser] * link:CONTRIBUTING.asciidoc[Contributing to qutebrowser] * link:INSTALL.asciidoc[INSTALL] * link:CHANGELOG.asciidoc[Change Log] diff --git a/doc/help/configuring.asciidoc b/doc/help/configuring.asciidoc new file mode 100644 index 000000000..f780b32ea --- /dev/null +++ b/doc/help/configuring.asciidoc @@ -0,0 +1,173 @@ +Configuring qutebrowser +======================= + +IMPORTANT: qutebrowser's configuration system was completely rewritten in +September 2017. This information is not applicable to older releases, and older +information elsewhere might be outdated. **If you had an old configuration +around and upgraded, this page will automatically open once**. To view it at a +later time, use the `:help` command. + +Migrating older configurations +------------------------------ + +qutebrowser does no automatic migration for the new configuration. However, +there's a special link:qute://configdiff[config diff page] which will show you +the changes you did in your old configuration, compared to the old defaults. + +Configuring qutebrowser via the user interface +---------------------------------------------- + +The easy (but less flexible) way to configure qutebrowser is using its user +interface or command line. Changes you make this way are immediately active +(with the exception of a few settings, where this is pointed out in the +documentation) are persisted in an `autoconfig.yml` file. + +Using the link:commands.html#set[`:set`] command and command completion, you +can quickly set settings interactively, for example `:set tabs.position left`. + +To get more help about a setting, use e.g. `:help tabs.position`. + +If you want to customize many settings, you can open the link:qute://settings[] +page by running `:set` without any arguments, where all settings are listed and +customizable. + +To bind and unbind keys, you can use the link:commands.html#bind[`:bind`] and +link:commands.html#unbind[`:unbind`] commands: + +- Binding a key: `:bind ,v spawn mpv {url}` +- Unbinding: `:unbind ,v` +- Changing an existing binding: `bind --force ,v message-info foo` + +The `autoconfig.yml` file is located in the "config" folder listed on the +link:qute://version[] page. On macOS, the "auto config" folder is used, which is +different from where hand-written config files are kept. + +**Do not** edit `autoconfig.yml` by hand. Instead, see the next section. + +Configuring qutebrowser via config.py +------------------------------------- + +For more powerful configuration, you can write a `config.py` file. Since it's a +Python file, you have much more flexibility for configuration. Note that +qutebrowser will never touch this file - this means you'll be responsible for +updating it when upgrading to a newer qutebrowser version. + +The file should be located in the "config" location listed on +link:qute://version[], which is typically `~/.config/qutebrowser/config.py` on +Linux, `~/.qutebrowser/config.py` on macOS, and +`%APPDATA%/qutebrowser/config.py` on Windows. + +Two global objects are pre-defined when executing the file: `c` and `config`. + +Setting settings +~~~~~~~~~~~~~~~~ + +`c` is a shorthand object to easily set settings like this: + +[source,python] +---- +c.tabs.position = "left" +c.completion.shrink = True +---- + +See the link:settings.html[settings help page] for all available settings. The +accepted values depend on the type of the option. Commonly used are: + +- Strings: `c.tabs.position = "left"` +- Booleans: `c.completion.shrink = True` +- Integers: `c.messages.timeout = 5000` +- Dictionaries: + * `c.headers.custom['X-Hello'] = 'World'` to override any other values in the + dictionary. + * `c.aliases['foo'] = ':message-info foo'` to add a single value. +- Lists: + * `c.url.start_pages = ["https://www.qutebrowser.org/"]` to override any + previous elements. + * `c.url.start_pages.append("https://www.python.org/")` to add a new value. + +Any other config types (e.g. a color) are specified as a string, with the +exception of the `Regex` type which can take either a string (with an `r` prefix +to preserve backslashes) or a Python regex object: + +- `c.hints.next_regexes.append(r'\bvor\b')` +- `c.hints.prev_regexes.append(re.compile(r'\bzurück\b'))` + +If you want to read a setting, you can use the `c` object to do so as well: +`c.colors.tabs.even.bg = c.colors.tabs.odd.bg`. + + +Using strings for setting names +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to set settings based on their name as a string, use the +`config.set` method: + +[source,python] +---- +config.set('content.javascript.enabled', False) +---- + +To read a setting, use the `config.get` method: + +[source,python] +---- +color = config.get('colors.completion.fg') +---- + +Binding keys +~~~~~~~~~~~~ + +While it's possible to change the `bindings.commands` setting to bind keys, it's +preferred to use the `config.bind` command. Doing so ensures the commands are +valid and normalizes different expressions which map to the same key. + +For details on how to specify keys and the available modes, see the +link:settings.html#bindings.commands[documentation] for the `bindings.commands` +setting. + +To bind a key: + +[source,python] +---- +config.bind(',v', 'spawn mpv {url}', mode='normal') +---- + +If the key is already bound, `force=True` needs to be given to rebind it: + +[source,python] +---- +config.bind(',v', 'message-info foo', mode='normal', force=True) +---- + +To unbind a key (either a key which has been bound before, or a default binding): + +[source,python] +---- +config.unbind(',v', mode='normal') +---- + +To suppress loading of any default keybindings, you can set `c.bindings.defaults += {}`. + +Prevent loading `autoconfig.yml` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want all customization done via `:set`, `:bind` and `:unbind` to be +temporary, you can suppress loading `autoconfig.yml` in your `config.py` by +doing: + +[source,python] +---- +config.load_autoconfig = False +---- + +Handling errors +~~~~~~~~~~~~~~~ + +If there are errors in your `config.py`, qutebrowser will try to apply as much +of it as possible, and show an error dialog before starting. + +qutebrowser tries to display errors which are easy to understand even for people +who are not used to writing Python. If you see a config error which you find +confusing or you think qutebrowser could handle better, please +https://github.com/qutebrowser/qutebrowser/issues[open an issue]! diff --git a/doc/help/index.asciidoc b/doc/help/index.asciidoc index 183435f68..e8321f2ad 100644 --- a/doc/help/index.asciidoc +++ b/doc/help/index.asciidoc @@ -10,6 +10,7 @@ The following help pages are currently available: * link:../../FAQ.html[Frequently asked questions] * link:../../CHANGELOG.html[Change Log] * link:commands.html[Documentation of commands] +* link:configuring.html[Configuring qutebrowser] * link:settings.html[Documentation of settings] * link:../userscripts.html[How to write userscripts] * link:../../CONTRIBUTING.html[Contributing to qutebrowser] diff --git a/qutebrowser/app.py b/qutebrowser/app.py index acd512ca2..5c9a682e2 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -324,6 +324,7 @@ def _open_special_pages(args): return state_config = objreg.get('state-config') + general_sect = state_config['general'] tabbed_browser = objreg.get('tabbed-browser', scope='window', window='last-focused') @@ -331,21 +332,32 @@ def _open_special_pages(args): needs_warning = (objects.backend == usertypes.Backend.QtWebKit and not qtutils.is_qtwebkit_ng()) - warning_shown = state_config['general'].get('backend-warning-shown') == '1' + warning_shown = general_sect.get('backend-warning-shown') == '1' if not warning_shown and needs_warning: tabbed_browser.tabopen(QUrl('qute://backend-warning'), background=False) - state_config['general']['backend-warning-shown'] = '1' + general_sect['backend-warning-shown'] = '1' # Quickstart page - quickstart_done = state_config['general'].get('quickstart-done') == '1' + quickstart_done = general_sect.get('quickstart-done') == '1' if not quickstart_done: tabbed_browser.tabopen( QUrl('https://www.qutebrowser.org/quickstart.html')) - state_config['general']['quickstart-done'] = '1' + general_sect['quickstart-done'] = '1' + + # Setting migration page + + needs_migration = os.path.exists( + os.path.join(standarddir.config(), 'qutebrowser.conf')) + migration_shown = general_sect.get('config-migration-shown') == '1' + + if needs_migration and not migration_shown: + tabbed_browser.tabopen(QUrl('qute://help/configuring.html'), + background=False) + general_sect['config-migration-shown'] = '1' def _save_version(): diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py index 6b382c32e..5d5da8c87 100644 --- a/qutebrowser/browser/qutescheme.py +++ b/qutebrowser/browser/qutescheme.py @@ -350,19 +350,6 @@ def qute_gpl(_url): @add_handler('help') def qute_help(url): """Handler for qute://help.""" - try: - utils.read_file('html/doc/index.html') - except OSError: - html = jinja.render( - 'error.html', - title="Error while loading documentation", - url=url.toDisplayString(), - error="This most likely means the documentation was not generated " - "properly. If you are running qutebrowser from the git " - "repository, please run scripts/asciidoc2html.py. " - "If you're running a released version this is a bug, please " - "use :report to report it.") - return 'text/html', html urlpath = url.path() if not urlpath or urlpath == '/': urlpath = 'index.html' @@ -375,7 +362,20 @@ def qute_help(url): if urlpath.endswith('.png'): return 'image/png', utils.read_file(path, binary=True) else: - data = utils.read_file(path) + try: + data = utils.read_file(path) + except OSError: + html = jinja.render( + 'error.html', + title="Error while loading documentation", + url=url.toDisplayString(), + error="This most likely means the documentation was not " + "generated properly. If you are running qutebrowser " + "from the git repository, please run " + "scripts/asciidoc2html.py. If you're running a released " + "version this is a bug, please use :report to report " + "it.") + return 'text/html', html return 'text/html', data