diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index e0080bf1c..69d6f7d29 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -439,7 +439,8 @@ Syntax: +:session-save [*--current*] [*--quiet*] [*--force*] ['name']+ Save a session. ==== positional arguments -* +'name'+: The name of the session. +* +'name'+: The name of the session. If not given, the session configured in general -> session-default-name is saved. + ==== optional arguments * +*-c*+, +*--current*+: Save the current session instead of the default. diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 1ff878ac9..9a30d83d1 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -22,6 +22,7 @@ |<>|How to open links in an existing instance if a new one is launched. |<>|Whether to log javascript console messages. |<>|Whether to always save the open pages. +|<>|The name of the session to save by default, or empty for the last loaded session. |============== .Quick reference for section ``ui'' @@ -419,6 +420,12 @@ Valid values: Default: +pass:[false]+ +[[general-session-default-name]] +=== session-default-name +The name of the session to save by default, or empty for the last loaded session. + +Default: +pass:[default]+ + == ui General options related to the user interface. diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 0cd309515..ffaaa79af 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -829,7 +829,7 @@ class Application(QApplication): @cmdutils.register(instance='app', name='wq', completion=[usertypes.Completion.sessions]) - def save_and_quit(self, name='default'): + def save_and_quit(self, name=sessions.default): """Save open pages and quit. Args: @@ -863,7 +863,7 @@ class Application(QApplication): session_manager.save(session, last_window=last_window, load_next_time=True) elif config.get('general', 'save-session'): - session_manager.save('default', last_window=last_window, + session_manager.save(sessions.default, last_window=last_window, load_next_time=True) deferrer = False diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index d274071c5..1d332e62a 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -216,6 +216,11 @@ def data(readonly=False): SettingValue(typ.Bool(), 'false'), "Whether to always save the open pages."), + ('session-default-name', + SettingValue(typ.SessionName(none_ok=True), ''), + "The name of the session to save by default, or empty for the " + "last loaded session."), + readonly=readonly )), diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 4431e77c2..af4474c8a 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1294,6 +1294,22 @@ class UrlList(List): "{}".format(val.errorString())) +class SessionName(BaseType): + + """The name of a session.""" + + typestr = 'session' + + def validate(self, value): + if not value: + if self._none_ok: + return + else: + raise configexc.ValidationError(value, "may not be empty!") + if value.startswith('_'): + raise configexc.ValidationError(value, "may not start with '_'!") + + class SelectOnRemove(BaseType): """Which tab to select when the focused tab is removed.""" diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py index 9ca5ad2a1..96fbdf9e4 100644 --- a/qutebrowser/misc/sessions.py +++ b/qutebrowser/misc/sessions.py @@ -35,6 +35,10 @@ from qutebrowser.utils import (standarddir, objreg, qtutils, log, usertypes, message) from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.mainwindow import mainwindow +from qutebrowser.config import config + + +default = object() # Sentinel value class SessionError(Exception): @@ -163,10 +167,22 @@ class SessionManager(QObject): """Save a named session. Args: + name: The name of the session to save, or the 'default' sentinel + object. last_window: If set, saves the saved self._last_window_session instead of the currently open state. load_next_time: If set, prepares this session to be load next time. + + Return: + The name of the saved session. """ + if name is default: + name = config.get('general', 'session-default-name') + if name is None: + if self._current is not None: + name = self._current + else: + name = 'default' path = self._get_session_path(name) log.misc.debug("Saving session {} to {}...".format(name, path)) @@ -187,6 +203,7 @@ class SessionManager(QObject): if load_next_time: state_config = objreg.get('state-config') state_config['general']['session'] = name + return name def save_last_window_session(self): """Temporarily save the session for the last closed window.""" @@ -299,18 +316,22 @@ class SessionManager(QObject): @cmdutils.register(name=['session-save', 'w'], completion=[usertypes.Completion.sessions], instance='session-manager') - def session_save(self, win_id: {'special': 'win_id'}, name='default', - current=False, quiet=False, force=False): + def session_save(self, win_id: {'special': 'win_id'}, + name: {'type': str}=default, current=False, quiet=False, + force=False): """Save a session. Args: win_id: The current window ID. - name: The name of the session. + name: The name of the session. If not given, the session configured + in general -> session-default-name is saved. current: Save the current session instead of the default. quiet: Don't show confirmation message. force: Force saving internal sessions (starting with an underline). """ - if name.startswith('_') and not force: + if (name is not default and + name.startswith('_') and # pylint: disable=no-member + not force): raise cmdexc.CommandError("{!r} is an internal session, use " "--force to save anyways.".format(name)) if current: @@ -319,7 +340,7 @@ class SessionManager(QObject): name = self._current assert not name.startswith('_') try: - self.save(name) + name = self.save(name) except SessionError as e: raise cmdexc.CommandError("Error while saving session: {}" .format(e))