Skip to content


Browse files Browse the repository at this point in the history
Detect mutated values in new config
This will allow to get a value and then mutate it, and we can also
make things easier for :bind and :unbind.
  • Loading branch information
The-Compiler committed Jun 20, 2017
1 parent 64359b6 commit 6e4a531
Showing 1 changed file with 29 additions and 9 deletions.
38 changes: 29 additions & 9 deletions qutebrowser/config/
Expand Up @@ -19,6 +19,7 @@

"""Configuration storage and config-related utilities."""

import copy
import os.path
import contextlib
import functools
Expand Down Expand Up @@ -165,25 +166,25 @@ def bind(self, key, command, *, mode, force=False):
except cmdexc.PrerequisitesError as e:
raise configexc.KeybindingError(str(e))

bindings = val.bindings.commands
bindings = instance.get_obj('bindings.commands')[mode]

log.keyboard.vdebug("Adding binding {} -> {} in mode {}.".format(
key, command, mode))
if key in bindings[mode] and not force:
if key in bindings and not force:
raise configexc.DuplicateKeyError(key)
bindings[mode][key] = command
val.bindings.commands = bindings # FIXME:conf
bindings[key] = command

def unbind(self, key, *, mode='normal'):
"""Unbind the given key in the given mode."""
key = self._prepare(key, mode)
bindings = val.bindings.commands
bindings = instance.get_obj('bindings.commands')[mode]
del bindings[mode][key]
del bindings[key]
except KeyError:
raise configexc.KeybindingError("Can't find binding '{}' in section '{}'!"
.format(key, mode))
val.bindings.commands = bindings # FIXME:conf

def get_command(self, key, mode):
"""Get the command for a given key (or None)."""
Expand Down Expand Up @@ -338,6 +339,7 @@ def __init__(self, parent=None):
self.options = {}
self._values = {} # FIXME:conf stub
self._mutables = []

def _changed(self, name, value):
Expand All @@ -355,8 +357,19 @@ def get_opt(self, name):

def get(self, name):
opt = self.get_opt(name)
value = self._values.get(name, opt.default)
return opt.typ.to_py(value)
obj = self.get_obj(name, mutable=False)
return opt.typ.to_py(obj)

def get_obj(self, name, *, mutable=True):
opt = self.get_opt(name)
obj = self._values.get(name, opt.default)
if isinstance(obj, (dict, list)):
if mutable:
self._mutables.append((name, copy.deepcopy(obj), obj))
# Shouldn't be mutable (and thus hashable)
assert obj.__hash__ is not None, obj
return obj

def get_str(self, name):
opt = self.get_opt(name)
Expand All @@ -376,6 +389,13 @@ def set_str(self, name, value):
self._values[name] = opt.typ.from_str(value)
self._changed(name, value)

def update_mutables(self):
for name, old_value, new_value in self._mutables:
if old_value != new_value:
log.config.debug("{} was mutated, updating".format(name))
self.set(name, new_value)
self._mutables = []

def dump_userconfig(self):
"""Get the part of the config which was changed by the user.
Expand Down

0 comments on commit 6e4a531

Please sign in to comment.