1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-02-21 20:38:54 +00:00

Make settings a global singleton

This commit is contained in:
nvbn 2015-09-06 21:47:12 +03:00
parent 191a2e588d
commit 105d3d8137
8 changed files with 114 additions and 119 deletions

View File

@ -29,7 +29,7 @@ def environ(monkeypatch):
def test_settings_defaults(load_source): def test_settings_defaults(load_source):
load_source.return_value = object() load_source.return_value = object()
for key, val in conf.DEFAULT_SETTINGS.items(): for key, val in conf.DEFAULT_SETTINGS.items():
assert getattr(conf.get_settings(Mock()), key) == val assert getattr(conf.init_settings(Mock()), key) == val
@pytest.mark.usefixture('environ') @pytest.mark.usefixture('environ')
@ -41,7 +41,7 @@ class TestSettingsFromFile(object):
no_colors=True, no_colors=True,
priority={'vim': 100}, priority={'vim': 100},
exclude_rules=['git']) exclude_rules=['git'])
settings = conf.get_settings(Mock()) settings = conf.init_settings(Mock())
assert settings.rules == ['test'] assert settings.rules == ['test']
assert settings.wait_command == 10 assert settings.wait_command == 10
assert settings.require_confirmation is True assert settings.require_confirmation is True
@ -55,7 +55,7 @@ class TestSettingsFromFile(object):
exclude_rules=[], exclude_rules=[],
require_confirmation=True, require_confirmation=True,
no_colors=True) no_colors=True)
settings = conf.get_settings(Mock()) settings = conf.init_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['test'] assert settings.rules == conf.DEFAULT_RULES + ['test']
@ -68,7 +68,7 @@ class TestSettingsFromEnv(object):
'THEFUCK_REQUIRE_CONFIRMATION': 'true', 'THEFUCK_REQUIRE_CONFIRMATION': 'true',
'THEFUCK_NO_COLORS': 'false', 'THEFUCK_NO_COLORS': 'false',
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'}) 'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
settings = conf.get_settings(Mock()) settings = conf.init_settings(Mock())
assert settings.rules == ['bash', 'lisp'] assert settings.rules == ['bash', 'lisp']
assert settings.exclude_rules == ['git', 'vim'] assert settings.exclude_rules == ['git', 'vim']
assert settings.wait_command == 55 assert settings.wait_command == 55
@ -78,7 +78,7 @@ class TestSettingsFromEnv(object):
def test_from_env_with_DEFAULT(self, environ): def test_from_env_with_DEFAULT(self, environ):
environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'}) environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})
settings = conf.get_settings(Mock()) settings = conf.init_settings(Mock())
assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp'] assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp']

View File

@ -1,12 +1,11 @@
from copy import copy
from imp import load_source from imp import load_source
import os import os
import sys import sys
from six import text_type from six import text_type
from . import logs, types from .types import RulesNamesList, Settings
class _DefaultRulesNames(types.RulesNamesList): class _DefaultRulesNames(RulesNamesList):
def __add__(self, items): def __add__(self, items):
return _DefaultRulesNames(list(self) + items) return _DefaultRulesNames(list(self) + items)
@ -24,7 +23,6 @@ class _DefaultRulesNames(types.RulesNamesList):
DEFAULT_RULES = _DefaultRulesNames([]) DEFAULT_RULES = _DefaultRulesNames([])
DEFAULT_PRIORITY = 1000 DEFAULT_PRIORITY = 1000
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES, DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'exclude_rules': [], 'exclude_rules': [],
'wait_command': 3, 'wait_command': 3,
@ -42,7 +40,6 @@ ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
'THEFUCK_PRIORITY': 'priority', 'THEFUCK_PRIORITY': 'priority',
'THEFUCK_DEBUG': 'debug'} 'THEFUCK_DEBUG': 'debug'}
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
# #
# The rules are defined as in the example bellow: # The rules are defined as in the example bellow:
@ -105,30 +102,28 @@ def _settings_from_env():
if env in os.environ} if env in os.environ}
def get_settings(user_dir): settings = Settings(DEFAULT_SETTINGS)
"""Returns settings filled with values from `settings.py` and env."""
conf = copy(DEFAULT_SETTINGS)
try: def init_settings(user_dir):
conf.update(_settings_from_file(user_dir)) """Fills `settings` with values from `settings.py` and env."""
except Exception: from .logs import exception
logs.exception("Can't load settings from file",
sys.exc_info(),
types.Settings(conf))
try: try:
conf.update(_settings_from_env()) settings.update(_settings_from_file(user_dir))
except Exception: except Exception:
logs.exception("Can't load settings from env", exception("Can't load settings from file", sys.exc_info())
sys.exc_info(),
types.Settings(conf))
if not isinstance(conf['rules'], types.RulesNamesList): try:
conf['rules'] = types.RulesNamesList(conf['rules']) settings.update(_settings_from_env())
except Exception:
exception("Can't load settings from env", sys.exc_info())
if not isinstance(conf['exclude_rules'], types.RulesNamesList): if not isinstance(settings['rules'], RulesNamesList):
conf['exclude_rules'] = types.RulesNamesList(conf['exclude_rules']) settings.rules = RulesNamesList(settings['rules'])
return types.Settings(conf) if not isinstance(settings.exclude_rules, RulesNamesList):
settings.exclude_rules = RulesNamesList(settings.exclude_rules)
def initialize_settings_file(user_dir): def initialize_settings_file(user_dir):

View File

@ -1,16 +1,18 @@
import sys import sys
from imp import load_source from imp import load_source
from pathlib import Path from pathlib import Path
from . import conf, types, logs from .conf import settings, DEFAULT_PRIORITY
from .types import Rule, CorrectedCommand, SortedCorrectedCommandsSequence
from . import logs
def load_rule(rule, settings): def load_rule(rule):
"""Imports rule module and returns it.""" """Imports rule module and returns it."""
name = rule.name[:-3] name = rule.name[:-3]
with logs.debug_time(u'Importing rule: {};'.format(name), settings): with logs.debug_time(u'Importing rule: {};'.format(name)):
rule_module = load_source(name, str(rule)) rule_module = load_source(name, str(rule))
priority = getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY) priority = getattr(rule_module, 'priority', DEFAULT_PRIORITY)
return types.Rule(name, rule_module.match, return Rule(name, rule_module.match,
rule_module.get_new_command, rule_module.get_new_command,
getattr(rule_module, 'enabled_by_default', True), getattr(rule_module, 'enabled_by_default', True),
getattr(rule_module, 'side_effect', None), getattr(rule_module, 'side_effect', None),
@ -18,27 +20,27 @@ def load_rule(rule, settings):
getattr(rule_module, 'requires_output', True)) getattr(rule_module, 'requires_output', True))
def get_loaded_rules(rules, settings): def get_loaded_rules(rules):
"""Yields all available rules.""" """Yields all available rules."""
for rule in rules: for rule in rules:
if rule.name != '__init__.py': if rule.name != '__init__.py':
loaded_rule = load_rule(rule, settings) loaded_rule = load_rule(rule)
if loaded_rule in settings.rules and \ if loaded_rule in settings.rules and \
loaded_rule not in settings.exclude_rules: loaded_rule not in settings.exclude_rules:
yield loaded_rule yield loaded_rule
def get_rules(user_dir, settings): def get_rules(user_dir):
"""Returns all enabled rules.""" """Returns all enabled rules."""
bundled = Path(__file__).parent \ bundled = Path(__file__).parent \
.joinpath('rules') \ .joinpath('rules') \
.glob('*.py') .glob('*.py')
user = user_dir.joinpath('rules').glob('*.py') user = user_dir.joinpath('rules').glob('*.py')
return sorted(get_loaded_rules(sorted(bundled) + sorted(user), settings), return sorted(get_loaded_rules(sorted(bundled) + sorted(user)),
key=lambda rule: rule.priority) key=lambda rule: rule.priority)
def is_rule_match(command, rule, settings): def is_rule_match(command, rule):
"""Returns first matched rule for command.""" """Returns first matched rule for command."""
script_only = command.stdout is None and command.stderr is None script_only = command.stdout is None and command.stderr is None
@ -46,27 +48,26 @@ def is_rule_match(command, rule, settings):
return False return False
try: try:
with logs.debug_time(u'Trying rule: {};'.format(rule.name), with logs.debug_time(u'Trying rule: {};'.format(rule.name)):
settings):
if rule.match(command, settings): if rule.match(command, settings):
return True return True
except Exception: except Exception:
logs.rule_failed(rule, sys.exc_info(), settings) logs.rule_failed(rule, sys.exc_info())
def make_corrected_commands(command, rule, settings): def make_corrected_commands(command, rule):
new_commands = rule.get_new_command(command, settings) new_commands = rule.get_new_command(command, settings)
if not isinstance(new_commands, list): if not isinstance(new_commands, list):
new_commands = (new_commands,) new_commands = (new_commands,)
for n, new_command in enumerate(new_commands): for n, new_command in enumerate(new_commands):
yield types.CorrectedCommand(script=new_command, yield CorrectedCommand(script=new_command,
side_effect=rule.side_effect, side_effect=rule.side_effect,
priority=(n + 1) * rule.priority) priority=(n + 1) * rule.priority)
def get_corrected_commands(command, user_dir, settings): def get_corrected_commands(command, user_dir):
corrected_commands = ( corrected_commands = (
corrected for rule in get_rules(user_dir, settings) corrected for rule in get_rules(user_dir)
if is_rule_match(command, rule, settings) if is_rule_match(command, rule)
for corrected in make_corrected_commands(command, rule, settings)) for corrected in make_corrected_commands(command, rule))
return types.SortedCorrectedCommandsSequence(corrected_commands, settings) return SortedCorrectedCommandsSequence(corrected_commands)

View File

@ -5,9 +5,10 @@ from datetime import datetime
import sys import sys
from traceback import format_exception from traceback import format_exception
import colorama import colorama
from .conf import settings
def color(color_, settings): def color(color_):
"""Utility for ability to disabling colored output.""" """Utility for ability to disabling colored output."""
if settings.no_colors: if settings.no_colors:
return '' return ''
@ -15,37 +16,37 @@ def color(color_, settings):
return color_ return color_
def exception(title, exc_info, settings): def exception(title, exc_info):
sys.stderr.write( sys.stderr.write(
u'{warn}[WARN] {title}:{reset}\n{trace}' u'{warn}[WARN] {title}:{reset}\n{trace}'
u'{warn}----------------------------{reset}\n\n'.format( u'{warn}----------------------------{reset}\n\n'.format(
warn=color(colorama.Back.RED + colorama.Fore.WHITE warn=color(colorama.Back.RED + colorama.Fore.WHITE
+ colorama.Style.BRIGHT, settings), + colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
title=title, title=title,
trace=''.join(format_exception(*exc_info)))) trace=''.join(format_exception(*exc_info))))
def rule_failed(rule, exc_info, settings): def rule_failed(rule, exc_info):
exception('Rule {}'.format(rule.name), exc_info, settings) exception('Rule {}'.format(rule.name), exc_info)
def failed(msg, settings): def failed(msg):
sys.stderr.write('{red}{msg}{reset}\n'.format( sys.stderr.write('{red}{msg}{reset}\n'.format(
msg=msg, msg=msg,
red=color(colorama.Fore.RED, settings), red=color(colorama.Fore.RED),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL)))
def show_corrected_command(corrected_command, settings): def show_corrected_command(corrected_command):
sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format( sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format(
script=corrected_command.script, script=corrected_command.script,
side_effect=' (+side effect)' if corrected_command.side_effect else '', side_effect=' (+side effect)' if corrected_command.side_effect else '',
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL)))
def confirm_text(corrected_command, settings): def confirm_text(corrected_command):
sys.stderr.write( sys.stderr.write(
('{clear}{bold}{script}{reset}{side_effect} ' ('{clear}{bold}{script}{reset}{side_effect} '
'[{green}enter{reset}/{blue}{reset}/{blue}{reset}' '[{green}enter{reset}/{blue}{reset}/{blue}{reset}'
@ -53,42 +54,42 @@ def confirm_text(corrected_command, settings):
script=corrected_command.script, script=corrected_command.script,
side_effect=' (+side effect)' if corrected_command.side_effect else '', side_effect=' (+side effect)' if corrected_command.side_effect else '',
clear='\033[1K\r', clear='\033[1K\r',
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
green=color(colorama.Fore.GREEN, settings), green=color(colorama.Fore.GREEN),
red=color(colorama.Fore.RED, settings), red=color(colorama.Fore.RED),
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
blue=color(colorama.Fore.BLUE, settings))) blue=color(colorama.Fore.BLUE)))
def debug(msg, settings): def debug(msg):
if settings.debug: if settings.debug:
sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format( sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format(
msg=msg, msg=msg,
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
blue=color(colorama.Fore.BLUE, settings), blue=color(colorama.Fore.BLUE),
bold=color(colorama.Style.BRIGHT, settings))) bold=color(colorama.Style.BRIGHT)))
@contextmanager @contextmanager
def debug_time(msg, settings): def debug_time(msg):
started = datetime.now() started = datetime.now()
try: try:
yield yield
finally: finally:
debug(u'{} took: {}'.format(msg, datetime.now() - started), settings) debug(u'{} took: {}'.format(msg, datetime.now() - started))
def how_to_configure_alias(configuration_details, settings): def how_to_configure_alias(configuration_details):
print("Seems like {bold}fuck{reset} alias isn't configured!".format( print("Seems like {bold}fuck{reset} alias isn't configured!".format(
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL)))
if configuration_details: if configuration_details:
content, path = configuration_details content, path = configuration_details
print( print(
"Please put {bold}{content}{reset} in your " "Please put {bold}{content}{reset} in your "
"{bold}{path}{reset}.".format( "{bold}{path}{reset}.".format(
bold=color(colorama.Style.BRIGHT, settings), bold=color(colorama.Style.BRIGHT),
reset=color(colorama.Style.RESET_ALL, settings), reset=color(colorama.Style.RESET_ALL),
path=path, path=path,
content=content)) content=content))
print('More details - https://github.com/nvbn/thefuck#manual-installation') print('More details - https://github.com/nvbn/thefuck#manual-installation')

View File

@ -10,7 +10,8 @@ import sys
from psutil import Process, TimeoutExpired from psutil import Process, TimeoutExpired
import colorama import colorama
import six import six
from . import logs, conf, types, shells from . import logs, types, shells
from .conf import initialize_settings_file, init_settings, settings
from .corrector import get_corrected_commands from .corrector import get_corrected_commands
from .ui import select_command from .ui import select_command
@ -21,11 +22,11 @@ def setup_user_dir():
rules_dir = user_dir.joinpath('rules') rules_dir = user_dir.joinpath('rules')
if not rules_dir.is_dir(): if not rules_dir.is_dir():
rules_dir.mkdir(parents=True) rules_dir.mkdir(parents=True)
conf.initialize_settings_file(user_dir) initialize_settings_file(user_dir)
return user_dir return user_dir
def wait_output(settings, popen): def wait_output(popen):
"""Returns `True` if we can get output of the command in the """Returns `True` if we can get output of the command in the
`settings.wait_command` time. `settings.wait_command` time.
@ -43,7 +44,7 @@ def wait_output(settings, popen):
return False return False
def get_command(settings, args): def get_command(args):
"""Creates command from `args` and executes it.""" """Creates command from `args` and executes it."""
if six.PY2: if six.PY2:
script = ' '.join(arg.decode('utf-8') for arg in args[1:]) script = ' '.join(arg.decode('utf-8') for arg in args[1:])
@ -58,23 +59,22 @@ def get_command(settings, args):
env = dict(os.environ) env = dict(os.environ)
env.update(settings.env) env.update(settings.env)
with logs.debug_time(u'Call: {}; with env: {};'.format(script, env), with logs.debug_time(u'Call: {}; with env: {};'.format(script, env)):
settings):
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env) result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env)
if wait_output(settings, result): if wait_output(result):
stdout = result.stdout.read().decode('utf-8') stdout = result.stdout.read().decode('utf-8')
stderr = result.stderr.read().decode('utf-8') stderr = result.stderr.read().decode('utf-8')
logs.debug(u'Received stdout: {}'.format(stdout), settings) logs.debug(u'Received stdout: {}'.format(stdout))
logs.debug(u'Received stderr: {}'.format(stderr), settings) logs.debug(u'Received stderr: {}'.format(stderr))
return types.Command(script, stdout, stderr) return types.Command(script, stdout, stderr)
else: else:
logs.debug(u'Execution timed out!', settings) logs.debug(u'Execution timed out!')
return types.Command(script, None, None) return types.Command(script, None, None)
def run_command(old_cmd, command, settings): def run_command(old_cmd, command):
"""Runs command from rule for passed command.""" """Runs command from rule for passed command."""
if command.side_effect: if command.side_effect:
command.side_effect(old_cmd, command.script, settings) command.side_effect(old_cmd, command.script, settings)
@ -87,20 +87,20 @@ def run_command(old_cmd, command, settings):
def fix_command(): def fix_command():
colorama.init() colorama.init()
user_dir = setup_user_dir() user_dir = setup_user_dir()
settings = conf.get_settings(user_dir) init_settings(user_dir)
with logs.debug_time('Total', settings): with logs.debug_time('Total'):
logs.debug(u'Run with settings: {}'.format(pformat(settings)), settings) logs.debug(u'Run with settings: {}'.format(pformat(settings)))
command = get_command(settings, sys.argv) command = get_command(sys.argv)
if not command: if not command:
logs.debug('Empty command, nothing to do', settings) logs.debug('Empty command, nothing to do')
return return
corrected_commands = get_corrected_commands(command, user_dir, settings) corrected_commands = get_corrected_commands(command, user_dir)
selected_command = select_command(corrected_commands, settings) selected_command = select_command(corrected_commands)
if selected_command: if selected_command:
run_command(command, selected_command, settings) run_command(command, selected_command)
def _get_current_version(): def _get_current_version():
@ -128,8 +128,8 @@ def how_to_configure_alias():
""" """
colorama.init() colorama.init()
user_dir = setup_user_dir() user_dir = setup_user_dir()
settings = conf.get_settings(user_dir) init_settings(user_dir)
logs.how_to_configure_alias(shells.how_to_configure(), settings) logs.how_to_configure_alias(shells.how_to_configure())
def main(): def main():

View File

@ -1,6 +1,5 @@
from collections import namedtuple from collections import namedtuple
from traceback import format_stack from traceback import format_stack
from .logs import debug
Command = namedtuple('Command', ('script', 'stdout', 'stderr')) Command = namedtuple('Command', ('script', 'stdout', 'stderr'))
@ -8,6 +7,7 @@ Rule = namedtuple('Rule', ('name', 'match', 'get_new_command',
'enabled_by_default', 'side_effect', 'enabled_by_default', 'side_effect',
'priority', 'requires_output')) 'priority', 'requires_output'))
class CorrectedCommand(object): class CorrectedCommand(object):
def __init__(self, script, side_effect, priority): def __init__(self, script, side_effect, priority):
self.script = script self.script = script
@ -17,7 +17,7 @@ class CorrectedCommand(object):
def __eq__(self, other): def __eq__(self, other):
"""Ignores `priority` field.""" """Ignores `priority` field."""
if isinstance(other, CorrectedCommand): if isinstance(other, CorrectedCommand):
return (other.script, other.side_effect) ==\ return (other.script, other.side_effect) == \
(self.script, self.side_effect) (self.script, self.side_effect)
else: else:
return False return False
@ -41,13 +41,8 @@ class Settings(dict):
def __getattr__(self, item): def __getattr__(self, item):
return self.get(item) return self.get(item)
def update(self, **kwargs): def __setattr__(self, key, value):
""" self[key] = value
Returns new settings with values from `kwargs` for unset settings.
"""
conf = dict(kwargs)
conf.update(self)
return Settings(conf)
class SortedCorrectedCommandsSequence(object): class SortedCorrectedCommandsSequence(object):
@ -59,8 +54,7 @@ class SortedCorrectedCommandsSequence(object):
""" """
def __init__(self, commands, settings): def __init__(self, commands):
self._settings = settings
self._commands = commands self._commands = commands
self._cached = self._realise_first() self._cached = self._realise_first()
self._realised = False self._realised = False
@ -81,13 +75,15 @@ class SortedCorrectedCommandsSequence(object):
def _realise(self): def _realise(self):
"""Realises generator, removes duplicates and sorts commands.""" """Realises generator, removes duplicates and sorts commands."""
from .logs import debug
if self._cached: if self._cached:
commands = self._remove_duplicates(self._commands) commands = self._remove_duplicates(self._commands)
self._cached = [self._cached[0]] + sorted( self._cached = [self._cached[0]] + sorted(
commands, key=lambda corrected_command: corrected_command.priority) commands, key=lambda corrected_command: corrected_command.priority)
self._realised = True self._realised = True
debug('SortedCommandsSequence was realised with: {}, after: {}'.format( debug('SortedCommandsSequence was realised with: {}, after: {}'.format(
self._cached, '\n'.join(format_stack())), self._settings) self._cached, '\n'.join(format_stack())))
def __getitem__(self, item): def __getitem__(self, item):
if item != 0 and not self._realised: if item != 0 and not self._realised:

View File

@ -1,6 +1,7 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
import sys import sys
from .conf import settings
from . import logs from . import logs
try: try:
@ -71,7 +72,7 @@ class CommandSelector(object):
fn(self.value) fn(self.value)
def select_command(corrected_commands, settings): def select_command(corrected_commands):
"""Returns: """Returns:
- the first command when confirmation disabled; - the first command when confirmation disabled;
@ -80,21 +81,21 @@ def select_command(corrected_commands, settings):
""" """
if not corrected_commands: if not corrected_commands:
logs.failed('No fucks given', settings) logs.failed('No fucks given')
return return
selector = CommandSelector(corrected_commands) selector = CommandSelector(corrected_commands)
if not settings.require_confirmation: if not settings.require_confirmation:
logs.show_corrected_command(selector.value, settings) logs.show_corrected_command(selector.value)
return selector.value return selector.value
selector.on_change(lambda val: logs.confirm_text(val, settings)) selector.on_change(lambda val: logs.confirm_text(val))
for action in read_actions(): for action in read_actions():
if action == SELECT: if action == SELECT:
sys.stderr.write('\n') sys.stderr.write('\n')
return selector.value return selector.value
elif action == ABORT: elif action == ABORT:
logs.failed('\nAborted', settings) logs.failed('\nAborted')
return return
elif action == PREVIOUS: elif action == PREVIOUS:
selector.previous() selector.previous()

View File

@ -12,6 +12,7 @@ import re
from pathlib import Path from pathlib import Path
import pkg_resources import pkg_resources
import six import six
from .types import Settings
DEVNULL = open(os.devnull, 'w') DEVNULL = open(os.devnull, 'w')
@ -70,7 +71,7 @@ def wrap_settings(params):
""" """
def _wrap_settings(fn, command, settings): def _wrap_settings(fn, command, settings):
return fn(command, settings.update(**params)) return fn(command, Settings(settings, **params))
return decorator(_wrap_settings) return decorator(_wrap_settings)