diff options
author | Abdó Roig-Maranges <abdo.roig@gmail.com> | 2012-12-06 15:12:54 +0100 |
---|---|---|
committer | hut <hut@lavabit.com> | 2012-12-09 15:16:45 +0100 |
commit | 864331a0edd73b364c22985bbb1aa7f55dcf25f4 (patch) | |
tree | 831b060f839eb11d34b17a58293b4220ff1800ff | |
parent | a45403b7f5c055ecac308c6b6adb1fe3f892f6eb (diff) | |
download | ranger-864331a0edd73b364c22985bbb1aa7f55dcf25f4.tar.gz |
Implement local per-directory settings
SettingObject can store settings local to a directory. Then LocalSettingObject choses the right settings according to context.
-rw-r--r-- | ranger/container/settingobject.py | 92 | ||||
-rw-r--r-- | ranger/core/actions.py | 6 | ||||
-rw-r--r-- | ranger/fsobject/directory.py | 5 |
3 files changed, 78 insertions, 25 deletions
diff --git a/ranger/container/settingobject.py b/ranger/container/settingobject.py index 780b6365..23bf10ba 100644 --- a/ranger/container/settingobject.py +++ b/ranger/container/settingobject.py @@ -51,43 +51,53 @@ DEFAULT_VALUES = { str: "", int: 0, list: [], + tuple: tuple([]), } class SettingObject(SignalDispatcher, FileManagerAware): def __init__(self): SignalDispatcher.__init__(self) + self.__dict__['_localsettings'] = dict() self.__dict__['_settings'] = dict() for name in ALLOWED_SETTINGS: self.signal_bind('setopt.'+name, self._raw_set_with_signal, priority=0.2) + def set(self, name, value, path=None): + assert name in ALLOWED_SETTINGS, "No such setting: {0}!".format(name) + if name not in self._settings: + previous = None + else: + previous=self._settings[name] + assert self._check_type(name, value) + kws = dict(setting=name, value=value, previous=previous, path=path, fm=self.fm) + self.signal_emit('setopt', **kws) + self.signal_emit('setopt.'+name, **kws) + + def get(self, name, path=None): + assert name in ALLOWED_SETTINGS, "No such setting: {0}!".format(name) + if path and path in self._localsettings and name in self._localsettings[path]: + return self._localsettings[path][name] + elif name in self._settings: + return self._settings[name] + else: + type_ = self.types_of(name)[0] + value = DEFAULT_VALUES[type_] + self._raw_set(name, value, None) + self.__setattr__(name, value) + return self._settings[name] + def __setattr__(self, name, value): - if name[0] == '_': + if name.startswith('_'): self.__dict__[name] = value else: - assert name in ALLOWED_SETTINGS, "No such setting: {0}!".format(name) - if name not in self._settings: - previous = None - else: - previous=self._settings[name] - assert self._check_type(name, value) - kws = dict(setting=name, value=value, previous=previous, fm=self.fm) - self.signal_emit('setopt', **kws) - self.signal_emit('setopt.'+name, **kws) + self.set(name, value, None) def __getattr__(self, name): - assert name in ALLOWED_SETTINGS or name in self._settings, \ - "No such setting: {0}!".format(name) if name.startswith('_'): return self.__dict__[name] - try: - return self._settings[name] - except: - type_ = self.types_of(name)[0] - value = DEFAULT_VALUES[type_] - self._raw_set(name, value) - self.__setattr__(name, value) - return self._settings[name] + else: + return self.get(name, None) def __iter__(self): for x in self._settings: @@ -121,8 +131,44 @@ class SettingObject(SignalDispatcher, FileManagerAware): __getitem__ = __getattr__ __setitem__ = __setattr__ - def _raw_set(self, name, value): - self._settings[name] = value + def _raw_set(self, name, value, path): + if path: + if not path in self._localsettings: + self._localsettings[path] = dict() + self._localsettings[path][name] = value + + # make sure name is in _settings, so __iter__ runs through local settigns too. + if not name in self._settings: + type_ = self.types_of(name)[0] + value = DEFAULT_VALUES[type_] + self._settings[name] = value + else: + self._settings[name] = value def _raw_set_with_signal(self, signal): - self._settings[signal.setting] = signal.value + self._raw_set(signal.setting, signal.value, signal.path) + + +class LocalSettingObject(): + def __init__(self, path, parent): + self.__dict__['_parent'] = parent + self.__dict__['_path'] = path + + def __setattr__(self, name, value): + if name.startswith('_'): + self.__dict__[name] = value + else: + self._parent.set(name, value, self._path) + + def __getattr__(self, name): + if name.startswith('_'): + return self.__dict__[name] + else: + return self._parent.get(name, self._path) + + def __iter__(self): + for x in self._parent._settings: + yield x + + __getitem__ = __getattr__ + __setitem__ = __setattr__ diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 6df73cdf..0b4948a0 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -67,13 +67,15 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.mode = mode self.ui.status.request_redraw() - def set_option_from_string(self, option_name, value): + def set_option_from_string(self, option_name, value, localpath=None): if option_name not in ALLOWED_SETTINGS: raise ValueError("The option named `%s' does not exist" % option_name) if not isinstance(value, str): raise ValueError("The value for an option needs to be a string.") - self.settings[option_name] = self._parse_option_value(option_name, value) + + self.settings.set(option_name, self._parse_option_value(option_name, value), localpath) + def _parse_option_value(self, name, value): types = self.fm.settings.types_of(name) diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py index a58201c0..f8271b6d 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -3,6 +3,7 @@ import os.path import re + from os import stat as os_stat, lstat as os_lstat from collections import deque from time import time @@ -15,6 +16,7 @@ from ranger.core.shared import SettingsAware from ranger.ext.accumulator import Accumulator from ranger.ext.lazy_property import lazy_property from ranger.ext.human_readable import human_readable +from ranger.container.settingobject import LocalSettingObject def sort_by_basename(path): """returns path.basename (for sorting)""" @@ -99,6 +101,9 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): for opt in ('hidden_filter', 'show_hidden'): self.settings.signal_bind('setopt.' + opt, self.request_reload, weak=True, autosort=False) + + self.settings = LocalSettingObject(path, self.settings) + self.use() def request_resort(self): |