Refactor saving logic, only save stuff if modified.
Fixes #113. See #11.
This commit is contained in:
parent
d6e87a2672
commit
43c5dc3bf6
@ -32,7 +32,7 @@
|
||||
|<<repeat,repeat>>|Repeat a given command.
|
||||
|<<report,report>>|Report a bug in qutebrowser.
|
||||
|<<restart,restart>>|Restart qutebrowser while keeping existing tabs open.
|
||||
|<<save,save>>|Save the config file.
|
||||
|<<save,save>>|Save configs and state.
|
||||
|<<search,search>>|Search for a text on the current page.
|
||||
|<<set,set>>|Set an option.
|
||||
|<<set-cmd-text,set-cmd-text>>|Preset the statusbar to some text.
|
||||
@ -352,7 +352,13 @@ Restart qutebrowser while keeping existing tabs open.
|
||||
|
||||
[[save]]
|
||||
=== save
|
||||
Save the config file.
|
||||
Syntax: +:save ['what' ['what' ...]]+
|
||||
|
||||
Save configs and state.
|
||||
|
||||
==== positional arguments
|
||||
* +'what'+: What to save (`config`/`key-config`/`cookies`/...). If not given, everything is saved.
|
||||
|
||||
|
||||
[[search]]
|
||||
=== search
|
||||
|
@ -43,7 +43,7 @@ from qutebrowser.config import style, config, websettings
|
||||
from qutebrowser.browser import quickmarks, cookies, cache, adblock
|
||||
from qutebrowser.browser.network import qutescheme, proxy
|
||||
from qutebrowser.mainwindow import mainwindow
|
||||
from qutebrowser.misc import crashdialog, readline, ipc, earlyinit
|
||||
from qutebrowser.misc import crashdialog, readline, ipc, earlyinit, savemanager
|
||||
from qutebrowser.misc import utilcmds # pylint: disable=unused-import
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.utils import (log, version, message, utils, qtutils, urlutils,
|
||||
@ -162,14 +162,18 @@ class Application(QApplication):
|
||||
|
||||
def _init_modules(self):
|
||||
"""Initialize all 'modules' which need to be initialized."""
|
||||
log.init.debug("Initializing save manager...")
|
||||
save_manager = savemanager.SaveManager(self)
|
||||
objreg.register('save-manager', save_manager)
|
||||
log.init.debug("Initializing readline-bridge...")
|
||||
readline_bridge = readline.ReadlineBridge()
|
||||
objreg.register('readline-bridge', readline_bridge)
|
||||
|
||||
log.init.debug("Initializing directories...")
|
||||
standarddir.init()
|
||||
log.init.debug("Initializing config...")
|
||||
config.init(self._args)
|
||||
save_manager.add_saveable('window-geometry', self._save_geometry)
|
||||
save_manager.add_saveable('version', self._save_version)
|
||||
log.init.debug("Initializing crashlog...")
|
||||
self._handle_segfault()
|
||||
log.init.debug("Initializing js-bridge...")
|
||||
@ -741,9 +745,6 @@ class Application(QApplication):
|
||||
|
||||
def _shutdown(self, status): # noqa
|
||||
"""Second stage of shutdown."""
|
||||
# pylint: disable=too-many-branches, too-many-statements
|
||||
# FIXME refactor this
|
||||
# https://github.com/The-Compiler/qutebrowser/issues/113
|
||||
log.destroy.debug("Stage 2 of shutting down...")
|
||||
# Remove eventfilter
|
||||
try:
|
||||
@ -760,59 +761,19 @@ class Application(QApplication):
|
||||
pass
|
||||
# Save everything
|
||||
try:
|
||||
config_obj = objreg.get('config')
|
||||
save_manager = objreg.get('save-manager')
|
||||
except KeyError:
|
||||
log.destroy.debug("Config not initialized yet, so not saving "
|
||||
"anything.")
|
||||
log.destroy.debug("Save manager not initialized yet, so not "
|
||||
"saving anything.")
|
||||
else:
|
||||
to_save = []
|
||||
if config.get('general', 'auto-save-config'):
|
||||
to_save.append(("config", config_obj.save))
|
||||
for key in save_manager.saveables:
|
||||
try:
|
||||
key_config = objreg.get('key-config')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
to_save.append(("keyconfig", key_config.save))
|
||||
to_save += [("window geometry", self._save_geometry)]
|
||||
to_save += [("version", self._save_version)]
|
||||
try:
|
||||
command_history = objreg.get('command-history')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
to_save.append(("command history", command_history.save))
|
||||
try:
|
||||
quickmark_manager = objreg.get('quickmark-manager')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
to_save.append(("command history", quickmark_manager.save))
|
||||
try:
|
||||
state_config = objreg.get('state-config')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
to_save.append(("window geometry", state_config.save))
|
||||
try:
|
||||
cookie_jar = objreg.get('cookie-jar')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
to_save.append(("cookies", cookie_jar.save))
|
||||
for what, handler in to_save:
|
||||
log.destroy.debug("Saving {} (handler: {})".format(
|
||||
what, utils.qualname(handler)))
|
||||
try:
|
||||
handler()
|
||||
save_manager.save(key, is_exit=True)
|
||||
except OSError as e:
|
||||
msgbox = QMessageBox(
|
||||
QMessageBox.Critical, "Error while saving!",
|
||||
"Error while saving {}: {}".format(what, e))
|
||||
"Error while saving {}: {}".format(key, e))
|
||||
msgbox.exec_()
|
||||
except AttributeError as e:
|
||||
log.destroy.warning("Could not save {}.".format(what))
|
||||
log.destroy.debug(e)
|
||||
# Re-enable faulthandler to stdout, then remove crash log
|
||||
log.destroy.debug("Deactiving crash log...")
|
||||
self._destroy_crashlogfile()
|
||||
|
@ -20,7 +20,7 @@
|
||||
"""Handling of HTTP cookies."""
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkCookie, QNetworkCookieJar
|
||||
from PyQt5.QtCore import QStandardPaths, QDateTime
|
||||
from PyQt5.QtCore import pyqtSignal, QStandardPaths, QDateTime
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.config.parsers import line as lineparser
|
||||
@ -29,7 +29,16 @@ from qutebrowser.utils import utils, standarddir, objreg
|
||||
|
||||
class RAMCookieJar(QNetworkCookieJar):
|
||||
|
||||
"""An in-RAM cookie jar."""
|
||||
"""An in-RAM cookie jar.
|
||||
|
||||
Signals:
|
||||
changed: Emitted when the cookie store was changed.
|
||||
"""
|
||||
|
||||
changed = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
def __repr__(self):
|
||||
return utils.get_repr(self, count=len(self.allCookies()))
|
||||
@ -47,6 +56,7 @@ class RAMCookieJar(QNetworkCookieJar):
|
||||
if config.get('content', 'cookies-accept') == 'never':
|
||||
return False
|
||||
else:
|
||||
self.changed.emit()
|
||||
return super().setCookiesFromUrl(cookies, url)
|
||||
|
||||
|
||||
@ -62,12 +72,15 @@ class CookieJar(RAMCookieJar):
|
||||
super().__init__(parent)
|
||||
datadir = standarddir.get(QStandardPaths.DataLocation)
|
||||
self._linecp = lineparser.LineConfigParser(datadir, 'cookies',
|
||||
binary=True)
|
||||
binary=True, parent=self)
|
||||
cookies = []
|
||||
for line in self._linecp:
|
||||
cookies += QNetworkCookie.parseCookies(line)
|
||||
self.setAllCookies(cookies)
|
||||
objreg.get('config').changed.connect(self.cookies_store_changed)
|
||||
objreg.get('save-manager').add_saveable(
|
||||
'cookies', self.save, self.changed,
|
||||
config_opt=('content', 'cookies-store'))
|
||||
|
||||
def purge_old_cookies(self):
|
||||
"""Purge expired cookies from the cookie jar."""
|
||||
@ -80,8 +93,6 @@ class CookieJar(RAMCookieJar):
|
||||
|
||||
def save(self):
|
||||
"""Save cookies to disk."""
|
||||
if not config.get('content', 'cookies-store'):
|
||||
return
|
||||
self.purge_old_cookies()
|
||||
lines = []
|
||||
for cookie in self.allCookies():
|
||||
@ -96,3 +107,4 @@ class CookieJar(RAMCookieJar):
|
||||
if not config.get('content', 'cookies-store'):
|
||||
self._linecp.data = []
|
||||
self._linecp.save()
|
||||
self.changed.emit()
|
||||
|
@ -29,7 +29,7 @@ import collections
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QStandardPaths, QUrl, QObject
|
||||
|
||||
from qutebrowser.utils import message, usertypes, urlutils, standarddir
|
||||
from qutebrowser.utils import message, usertypes, urlutils, standarddir, objreg
|
||||
from qutebrowser.commands import cmdexc, cmdutils
|
||||
from qutebrowser.config.parsers import line as lineparser
|
||||
|
||||
@ -52,7 +52,8 @@ class QuickmarkManager(QObject):
|
||||
self.marks = collections.OrderedDict()
|
||||
|
||||
confdir = standarddir.get(QStandardPaths.ConfigLocation)
|
||||
self._linecp = lineparser.LineConfigParser(confdir, 'quickmarks')
|
||||
self._linecp = lineparser.LineConfigParser(confdir, 'quickmarks',
|
||||
parent=self)
|
||||
for line in self._linecp:
|
||||
try:
|
||||
key, url = line.rsplit(maxsplit=1)
|
||||
@ -60,6 +61,8 @@ class QuickmarkManager(QObject):
|
||||
message.error(0, "Invalid quickmark '{}'".format(line))
|
||||
else:
|
||||
self.marks[key] = url
|
||||
objreg.get('save-manager').add_saveable('quickmark-manager', self.save,
|
||||
self.changed)
|
||||
|
||||
def save(self):
|
||||
"""Save the quickmarks to disk."""
|
||||
|
@ -119,6 +119,7 @@ def init(args):
|
||||
Args:
|
||||
args: The argparse namespace.
|
||||
"""
|
||||
save_manager = objreg.get('save-manager')
|
||||
confdir = standarddir.get(QStandardPaths.ConfigLocation, args)
|
||||
try:
|
||||
app = objreg.get('app')
|
||||
@ -139,6 +140,9 @@ def init(args):
|
||||
sys.exit(1)
|
||||
else:
|
||||
objreg.register('config', config_obj)
|
||||
save_manager.add_saveable('config', config_obj.save,
|
||||
config_obj.changed,
|
||||
config_opt=('general', 'auto-save-config'))
|
||||
try:
|
||||
key_config = keyconf.KeyConfigParser(confdir, 'keys.conf')
|
||||
except (keyconf.KeyConfigError, UnicodeDecodeError) as e:
|
||||
@ -154,15 +158,23 @@ def init(args):
|
||||
sys.exit(1)
|
||||
else:
|
||||
objreg.register('key-config', key_config)
|
||||
save_manager.add_saveable('key-config', key_config.save,
|
||||
key_config.changed,
|
||||
config_opt=('general', 'auto-save-config'))
|
||||
|
||||
datadir = standarddir.get(QStandardPaths.DataLocation, args)
|
||||
state_config = ini.ReadWriteConfigParser(datadir, 'state')
|
||||
objreg.register('state-config', state_config)
|
||||
save_manager.add_saveable('state-config', state_config.save)
|
||||
|
||||
# We need to import this here because lineparser needs config.
|
||||
from qutebrowser.config.parsers import line
|
||||
command_history = line.LineConfigParser(datadir, 'cmd-history',
|
||||
('completion', 'history-length'))
|
||||
('completion', 'history-length'),
|
||||
parent=config_obj)
|
||||
objreg.register('command-history', command_history)
|
||||
save_manager.add_saveable('command-history', command_history.save,
|
||||
command_history.changed)
|
||||
|
||||
|
||||
class ConfigManager(QObject):
|
||||
@ -577,14 +589,6 @@ class ConfigManager(QObject):
|
||||
if self._initialized:
|
||||
self._after_set(sectname, optname)
|
||||
|
||||
@cmdutils.register(instance='config', name='save')
|
||||
def save_command(self):
|
||||
"""Save the config file."""
|
||||
try:
|
||||
self.save()
|
||||
except OSError as e:
|
||||
raise cmdexc.CommandError("Could not save config: {}".format(e))
|
||||
|
||||
def save(self):
|
||||
"""Save the config file."""
|
||||
if self._configdir is None:
|
||||
|
@ -41,11 +41,6 @@ FIRST_COMMENT = r"""
|
||||
|
||||
# Configfile for qutebrowser.
|
||||
#
|
||||
# WARNING:
|
||||
#
|
||||
# This config file will be OVERWRITTEN when closing qutebrowser.
|
||||
# Close qutebrowser before changing this file, or YOUR CHANGES WILL BE LOST.
|
||||
#
|
||||
# This configfile is parsed by python's configparser in extended
|
||||
# interpolation mode. The format is very INI-like, so there are
|
||||
# categories like [general] with "key = value"-pairs.
|
||||
|
@ -21,15 +21,14 @@
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import collections
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||
|
||||
from qutebrowser.utils import log, utils, objreg, qtutils
|
||||
from qutebrowser.config import config
|
||||
|
||||
|
||||
class LineConfigParser(collections.UserList):
|
||||
class LineConfigParser(QObject):
|
||||
|
||||
"""Parser for configuration files which are simply line-based.
|
||||
|
||||
@ -41,9 +40,15 @@ class LineConfigParser(collections.UserList):
|
||||
_binary: Whether to open the file in binary mode.
|
||||
_limit: The config section/option used to limit the maximum number of
|
||||
lines.
|
||||
|
||||
Signals:
|
||||
changed: Emitted when the history was changed.
|
||||
"""
|
||||
|
||||
def __init__(self, configdir, fname, limit=None, binary=False):
|
||||
changed = pyqtSignal()
|
||||
|
||||
def __init__(self, configdir, fname, limit=None, binary=False,
|
||||
parent=None):
|
||||
"""Config constructor.
|
||||
|
||||
Args:
|
||||
@ -52,7 +57,7 @@ class LineConfigParser(collections.UserList):
|
||||
limit: Config tuple (section, option) which contains a limit.
|
||||
binary: Whether to open the file in binary mode.
|
||||
"""
|
||||
super().__init__()
|
||||
super().__init__(parent)
|
||||
self._configdir = configdir
|
||||
self._configfile = os.path.join(self._configdir, fname)
|
||||
self._fname = fname
|
||||
@ -71,6 +76,12 @@ class LineConfigParser(collections.UserList):
|
||||
configdir=self._configdir, fname=self._fname,
|
||||
limit=self._limit, binary=self._binary)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.data)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.data[key]
|
||||
|
||||
def read(self, filename):
|
||||
"""Read the data from a file."""
|
||||
if self._binary:
|
||||
|
@ -64,8 +64,10 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
|
||||
misc.CommandLineEdit.__init__(self, parent)
|
||||
misc.MinimalLineEditMixin.__init__(self)
|
||||
self._win_id = win_id
|
||||
command_history = objreg.get('command-history')
|
||||
self.history.handle_private_mode = True
|
||||
self.history.history = objreg.get('command-history').data
|
||||
self.history.history = command_history.data
|
||||
self.history.changed.connect(command_history.changed)
|
||||
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
|
||||
self.cursorPositionChanged.connect(self.update_completion)
|
||||
self.textChanged.connect(self.update_completion)
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
"""Command history for the status bar."""
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import usertypes, log
|
||||
@ -39,7 +39,7 @@ class HistoryEndReachedError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class History:
|
||||
class History(QObject):
|
||||
|
||||
"""Command history.
|
||||
|
||||
@ -47,14 +47,20 @@ class History:
|
||||
handle_private_mode: Whether to ignore history in private mode.
|
||||
history: A list of executed commands, with newer commands at the end.
|
||||
_tmphist: Temporary history for history browsing (as NeighborList)
|
||||
|
||||
Signals:
|
||||
changed: Emitted when an entry was added to the history.
|
||||
"""
|
||||
|
||||
def __init__(self, history=None):
|
||||
changed = pyqtSignal()
|
||||
|
||||
def __init__(self, history=None, parent=None):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
history: The initial history to set.
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.handle_private_mode = False
|
||||
self._tmphist = None
|
||||
if history is None:
|
||||
@ -128,3 +134,4 @@ class History:
|
||||
return
|
||||
if not self.history or text != self.history[-1]:
|
||||
self.history.append(text)
|
||||
self.changed.emit()
|
||||
|
@ -69,7 +69,7 @@ class ConsoleLineEdit(miscwidgets.CommandLineEdit):
|
||||
QCompleter.CaseSensitivelySortedModel)
|
||||
self.setCompleter(qcompleter)
|
||||
|
||||
self._history = cmdhistory.History()
|
||||
self._history = cmdhistory.History(parent=self)
|
||||
self.returnPressed.connect(self.on_return_pressed)
|
||||
|
||||
@pyqtSlot(str)
|
||||
|
@ -58,7 +58,7 @@ class CommandLineEdit(QLineEdit):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.history = cmdhistory.History()
|
||||
self.history = cmdhistory.History(parent=self)
|
||||
self._validator = _CommandValidator(self)
|
||||
self.setValidator(self._validator)
|
||||
self.textEdited.connect(self.on_text_edited)
|
||||
|
151
qutebrowser/misc/savemanager.py
Normal file
151
qutebrowser/misc/savemanager.py
Normal file
@ -0,0 +1,151 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Saving things to disk periodically."""
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QObject
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.commands import cmdutils
|
||||
from qutebrowser.utils import utils, log, message
|
||||
|
||||
|
||||
class Saveable:
|
||||
|
||||
"""A single thing which can be saved.
|
||||
|
||||
Attributes:
|
||||
_name: The naem of the thing to be saved.
|
||||
_dirty: Whether the saveable was changed since the last save.
|
||||
_save_handler: The function to call to save this Saveable.
|
||||
_save_on_exit: Whether to always save this saveable on exit.
|
||||
_config_opt: A (section, option) tuple of a config option which decides
|
||||
whether to autosave or not. None if no such option exists.
|
||||
"""
|
||||
|
||||
def __init__(self, name, save_handler, changed=None, config_opt=None):
|
||||
self._name = name
|
||||
self._dirty = False
|
||||
self._save_handler = save_handler
|
||||
self._config_opt = config_opt
|
||||
if changed is not None:
|
||||
changed.connect(self.mark_dirty)
|
||||
self._save_on_exit = False
|
||||
else:
|
||||
self._save_on_exit = True
|
||||
|
||||
def __repr__(self):
|
||||
return utils.get_repr(self, name=self._name, dirty=self._dirty,
|
||||
save_handler=self._save_handler,
|
||||
config_opt=self._config_opt,
|
||||
save_on_exit=self._save_on_exit)
|
||||
|
||||
@pyqtSlot()
|
||||
def mark_dirty(self):
|
||||
"""Mark this saveable as dirty (having changes)."""
|
||||
log.save.debug("Marking {} as dirty.".format(self._name))
|
||||
self._dirty = True
|
||||
|
||||
def save(self, is_exit=False, explicit=False):
|
||||
"""Save this saveable.
|
||||
|
||||
Args:
|
||||
is_exit: Whether we're currently exiting qutebrowser.
|
||||
explicit: Whether the user explicitely requested this save.
|
||||
"""
|
||||
if (self._config_opt is not None and
|
||||
(not config.get(*self._config_opt)) and
|
||||
(not explicit)):
|
||||
log.save.debug("Not saving {} because autosaving has been "
|
||||
"disabled by {cfg[0]} -> {cfg[1]}.".format(
|
||||
self._name, cfg=self._config_opt))
|
||||
return
|
||||
do_save = self._dirty or (self._save_on_exit and is_exit)
|
||||
log.save.debug("Save of {} requested - dirty {}, save_on_exit {}, "
|
||||
"is_exit {} -> {}".format(
|
||||
self._name, self._dirty, self._save_on_exit,
|
||||
is_exit, do_save))
|
||||
if do_save:
|
||||
self._save_handler()
|
||||
self._dirty = False
|
||||
|
||||
|
||||
class SaveManager(QObject):
|
||||
|
||||
"""Responsible to save 'saveables' periodically and on exit.
|
||||
|
||||
Attributes:
|
||||
saveables: A dict mapping names to Saveable instances.
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.saveables = {}
|
||||
|
||||
def __repr__(self):
|
||||
return utils.get_repr(self, saveables=self.saveables)
|
||||
|
||||
def add_saveable(self, name, save, changed=None, config_opt=None):
|
||||
"""Add a new saveable.
|
||||
|
||||
Args:
|
||||
name: The name to use.
|
||||
save: The function to call to save this saveable.
|
||||
changed: The signal emitted when this saveable changed.
|
||||
config_opt: A (section, option) tuple deciding whether to autosave
|
||||
or not.
|
||||
"""
|
||||
if name in self.saveables:
|
||||
raise ValueError("Saveable {} already registered!".format(name))
|
||||
self.saveables[name] = Saveable(name, save, changed, config_opt)
|
||||
|
||||
def save(self, name, is_exit=False, explicit=False):
|
||||
"""Save a saveable by name.
|
||||
|
||||
Args:
|
||||
is_exit: Whether we're currently exiting qutebrowser.
|
||||
explicit: Whether this save operation was triggered explicitely.
|
||||
"""
|
||||
self.saveables[name].save(is_exit=is_exit, explicit=explicit)
|
||||
|
||||
@cmdutils.register(instance='save-manager', name='save')
|
||||
def save_command(self, win_id: {'special': 'win_id'},
|
||||
*what: {'nargs': '*'}):
|
||||
"""Save configs and state.
|
||||
|
||||
Args:
|
||||
win_id: The window this command is executed in.
|
||||
*what: What to save (`config`/`key-config`/`cookies`/...).
|
||||
If not given, everything is saved.
|
||||
"""
|
||||
if what:
|
||||
explicit = True
|
||||
else:
|
||||
what = self.saveables
|
||||
explicit = False
|
||||
for key in what:
|
||||
if key not in self.saveables:
|
||||
message.error(win_id, "{} is nothing which can be "
|
||||
"saved".format(key))
|
||||
else:
|
||||
try:
|
||||
self.save(key, explicit=explicit)
|
||||
except OSError as e:
|
||||
message.error(win_id, "Could not save {}: "
|
||||
"{}".format(key, e))
|
@ -126,6 +126,7 @@ style = logging.getLogger('style')
|
||||
rfc6266 = logging.getLogger('rfc6266')
|
||||
ipc = logging.getLogger('ipc')
|
||||
shlexer = logging.getLogger('shlexer')
|
||||
save = logging.getLogger('save')
|
||||
|
||||
|
||||
ram_handler = None
|
||||
|
Loading…
Reference in New Issue
Block a user