diff options
author | nfnty <git@nfnty.se> | 2017-02-04 11:40:58 +0100 |
---|---|---|
committer | nfnty <git@nfnty.se> | 2017-02-04 11:42:38 +0100 |
commit | b108f821d0838aaa5fea11a52c3620aec33a5340 (patch) | |
tree | c9ba4701e841a9007cc2facfa943f3b1544a10e9 | |
parent | 8e8493e93ec705b5296684d5884794dd446d9116 (diff) | |
download | ranger-b108f821d0838aaa5fea11a52c3620aec33a5340.tar.gz |
api.commands: Refactor function and alias commands
-rw-r--r-- | ranger/api/commands.py | 124 | ||||
-rw-r--r-- | ranger/core/actions.py | 9 |
2 files changed, 64 insertions, 69 deletions
diff --git a/ranger/api/commands.py b/ranger/api/commands.py index f5011232..763e2fef 100644 --- a/ranger/api/commands.py +++ b/ranger/api/commands.py @@ -16,6 +16,8 @@ import ranger from ranger.core.shared import FileManagerAware from ranger.ext.lazy_property import lazy_property +__all__ = ['Command'] + _SETTINGS_RE = re.compile(r'^\s*([^\s]+?)=(.*)$') _ALIAS_LINE_RE = re.compile(r'(\s+)') @@ -35,18 +37,12 @@ class CommandContainer(FileManagerAware): except KeyError: self.fm.notify('alias failed: No such command: {0}'.format(cmd_name), bad=True) return None - - class CommandAlias(cmd): # pylint: disable=too-few-public-methods - def __init__(self, line, *args, **kwargs): - super(CommandAlias, self).__init__( - (self.full_command + ''.join(_ALIAS_LINE_RE.split(line)[1:])), *args, **kwargs) - self.commands[name] = type(name, (CommandAlias,), dict(full_command=full_command)) + self.commands[name] = command_alias_factory(name, cmd, full_command) def load_commands_from_module(self, module): for var in vars(module).values(): try: - if issubclass(var, Command) and var != Command \ - and var != FunctionCommand: + if issubclass(var, Command) and var != Command: self.commands[var.get_name()] = var except TypeError: pass @@ -57,11 +53,7 @@ class CommandContainer(FileManagerAware): continue attribute = getattr(obj, attribute_name) if hasattr(attribute, '__call__'): - cmd = type(attribute_name, (FunctionCommand,), dict(__doc__=attribute.__doc__)) - cmd.based_function = attribute - cmd.function_name = attribute.__name__ - cmd.object_name = obj.__class__.__name__ - self.commands[attribute_name] = cmd + self.commands[attribute_name] = command_function_factory(attribute) def get_command(self, name, abbrev=True): if abbrev: @@ -371,62 +363,68 @@ class Command(FileManagerAware): return (self.start(1) + program for program in programs) -class FunctionCommand(Command): - based_function = None - object_name = "" - function_name = "unknown" - - def execute(self): # pylint: disable=too-many-branches - if not self.based_function: - return - if len(self.args) == 1: - try: - return self.based_function( # pylint: disable=not-callable - **{'narg': self.quantifier}) - except TypeError: - return self.based_function() # pylint: disable=not-callable +def command_alias_factory(name, cls, full_command): + class CommandAlias(cls): # pylint: disable=too-few-public-methods + __name__ = name - args, keywords = list(), dict() - for arg in self.args[1:]: - equal_sign = arg.find("=") - value = arg if equal_sign == -1 else arg[equal_sign + 1:] - try: - value = int(value) - except ValueError: - if value in ('True', 'False'): - value = (value == 'True') - else: - try: - value = float(value) - except ValueError: - pass + def __init__(self, line, *args, **kwargs): + super(CommandAlias, self).__init__( + (full_command + ''.join(_ALIAS_LINE_RE.split(line)[1:])), *args, **kwargs) + return CommandAlias - if equal_sign == -1: - args.append(value) - else: - keywords[arg[:equal_sign]] = value - if self.quantifier is not None: - keywords['narg'] = self.quantifier +def command_function_factory(func): + class CommandFunction(Command): + __name__ = func.__name__ + __doc__ = func.__doc__ - try: - if self.quantifier is None: - return self.based_function(*args, **keywords) # pylint: disable=not-callable - else: + def execute(self): # pylint: disable=too-many-branches + if not func: + return + if len(self.args) == 1: try: - return self.based_function(*args, **keywords) # pylint: disable=not-callable + return func(**{'narg': self.quantifier}) except TypeError: - del keywords['narg'] - return self.based_function(*args, **keywords) # pylint: disable=not-callable - except TypeError: - if ranger.args.debug: - raise - else: - self.fm.notify( - "Bad arguments for %s.%s: %s, %s" % ( - self.object_name, self.function_name, repr(args), repr(keywords)), - bad=True, - ) + return func() + + args, kwargs = list(), dict() + for arg in self.args[1:]: + equal_sign = arg.find("=") + value = arg if equal_sign == -1 else arg[equal_sign + 1:] + try: + value = int(value) + except ValueError: + if value in ('True', 'False'): + value = (value == 'True') + else: + try: + value = float(value) + except ValueError: + pass + + if equal_sign == -1: + args.append(value) + else: + kwargs[arg[:equal_sign]] = value + + if self.quantifier is not None: + kwargs['narg'] = self.quantifier + + try: + if self.quantifier is None: + return func(*args, **kwargs) + else: + try: + return func(*args, **kwargs) + except TypeError: + del kwargs['narg'] + return func(*args, **kwargs) + except TypeError: + if ranger.args.debug: + raise + self.fm.notify("Bad arguments for %s: %s, %s" % (func.__name__, args, kwargs), + bad=True) + return CommandFunction if __name__ == '__main__': diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 29e1f69f..c78f61e2 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -239,8 +239,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m except ValueError as ex: if ranger.args.debug: raise - else: - return self.notify(ex) + return self.notify(ex) cmd.init_line(line) try: @@ -248,8 +247,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m except Exception as ex: # pylint: disable=broad-except if ranger.args.debug: raise - else: - self.notify(ex) + self.notify(ex) def substitute_macros(self, string, # pylint: disable=redefined-outer-name additional=None, escape=False): @@ -384,8 +382,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m except Exception as ex: # pylint: disable=broad-except if ranger.args.debug: raise - else: - self.notify('Error in line `%s\':\n %s' % (line, str(ex)), bad=True) + self.notify('Error in line `%s\':\n %s' % (line, str(ex)), bad=True) def execute_file(self, files, **kw): """Uses the "rifle" module to open/execute a file |