poezio/src/decorators.py

139 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Module containing various decorators
"""
import common
class RefreshWrapper(object):
def __init__(self):
self.core = None
def conditional(self, func):
"""
Decorator to refresh the UI if the wrapped function
returns True
"""
def wrap(*args, **kwargs):
ret = func(*args, **kwargs)
if self.core and ret:
self.core.refresh_window()
return ret
return wrap
def always(self, func):
"""
Decorator that refreshs the UI no matter what after the function
"""
def wrap(*args, **kwargs):
ret = func(*args, **kwargs)
if self.core:
self.core.refresh_window()
return ret
return wrap
def update(self, func):
"""
Decorator that only updates the screen
"""
def wrap(*args, **kwargs):
ret = func(*args, **kwargs)
if self.core:
self.core.doupdate()
return ret
return wrap
refresh_wrapper = RefreshWrapper()
class CommandArgParser(object):
"""Modify the string argument of the function into a list of strings
containing the right number of extracted arguments, or None if we dont
have enough.
"""
@staticmethod
def raw(func):
"""Just call the function with a single string, which is the original string
untouched
"""
def wrap(self, args, *a, **kw):
return func(self, args, *a, **kw)
return wrap
@staticmethod
def ignored(func):
"""
Call the function without any argument
"""
def wrap(self, args, *a, **kw):
return func(self, *a, **kw)
return wrap
@staticmethod
def quoted(mandatory, optional=0, defaults=[],
ignore_trailing_arguments=False):
"""The function receives a list with a number of arguments that is between
the numbers `mandatory` and `optional`.
If the string doesnt contain at least `mandatory` arguments, we return
None because the given arguments are invalid.
If there are any remaining arguments after `mandatory` and `optional`
arguments have been found (and “ignore_trailing_arguments" is not True),
we happen them to the last argument of the list.
An argument is a string (with or without whitespaces) between to quotes
("), or a whitespace separated word (if not inside quotes).
The argument `defaults` is a list of strings that are used when an
optional argument is missing. For example if we accept one optional
argument, zero is available but we have one value in the `defaults`
list, we use that string inplace. The `defaults` list can only
replace missing optional arguments, not mandatory ones. And it
should not contain more than `mandatory` values. Also you cannot
Example:
This method needs at least one argument, and accepts up to 3
arguments
>> @command_args_parser.quoted(1, 2, ['default for first arg'], False)
>> def f(args):
>> print(args)
>> f('coucou les amis') # We have one mandatory and two optional
['coucou', 'les', 'amis']
>> f('"coucou les amis" "PROUT PROUT"') # One mandator and only one optional,
# no default for the second
['coucou les amis', 'PROUT PROUT']
>> f('') # Not enough args for mandatory number
None
>> f('"coucou les potes"') # One mandatory, and use the default value
# for the first optional
['coucou les potes, 'default for first arg']
>> f('"un et demi" deux trois quatre cinq six') # We have three trailing arguments
['un et demi', 'deux', 'trois quatre cinq six']
"""
def first(func):
def second(self, args, *a, **kw):
default_args = defaults
args = common.shell_split(args)
if len(args) < mandatory:
return func(self, None, *a, **kw)
res, args = args[:mandatory], args[mandatory:]
if optional == -1:
opt_args = args[:]
else:
opt_args = args[:optional]
if opt_args:
res += opt_args
args = args[len(opt_args):]
default_args = default_args[len(opt_args):]
res += default_args
if args and res and not ignore_trailing_arguments:
res[-1] += " " + " ".join(args)
return func(self, res, *a, **kw)
return second
return first
command_args_parser = CommandArgParser()