summaryrefslogtreecommitdiff
path: root/cmd2
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2018-09-27 13:08:14 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2018-09-27 13:08:14 -0400
commit0f2f798586d4b680baa20c24086709b9faec9c24 (patch)
tree1b11a12dc3a773108c47bf898f5a3c03bcd866d7 /cmd2
parent19cdd5ff086a7bc8714e011084a1aaecacbf1900 (diff)
parent86f27ac241c2366022c55e891e449a2ed08b308a (diff)
downloadcmd2-git-0f2f798586d4b680baa20c24086709b9faec9c24.tar.gz
Merge branch 'macro' into argparse_conversion
Diffstat (limited to 'cmd2')
-rw-r--r--cmd2/cmd2.py28
-rw-r--r--cmd2/parsing.py42
2 files changed, 37 insertions, 33 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index fcad6880..2c58d550 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -48,8 +48,7 @@ from . import utils
from . import plugin
from .argparse_completer import AutoCompleter, ACArgumentParser, ACTION_ARG_CHOICES
from .clipboard import can_clip, get_paste_buffer, write_to_paste_buffer
-from .parsing import StatementParser, Statement, Macro, MacroArg, \
- macro_normal_arg_pattern, macro_escaped_arg_pattern, digit_pattern
+from .parsing import StatementParser, Statement, Macro, MacroArg
# Set up readline
from .rl_utils import rl_type, RlType, rl_get_point, rl_set_prompt, vt100_support, rl_make_safe_prompt
@@ -2041,11 +2040,11 @@ class Cmd(cmd.Cmd):
for arg in reverse_arg_list:
if arg.is_escaped:
- to_replace = '{{' + str(arg.number) + '}}'
- replacement = '{' + str(arg.number) + '}'
+ to_replace = '{{' + arg.number_str + '}}'
+ replacement = '{' + arg.number_str + '}'
else:
- to_replace = '{' + str(arg.number) + '}'
- replacement = statement.argv[arg.number]
+ to_replace = '{' + arg.number_str + '}'
+ replacement = statement.argv[int(arg.number_str)]
parts = resolved.rsplit(to_replace, maxsplit=1)
resolved = parts[0] + replacement + parts[1]
@@ -2374,7 +2373,7 @@ class Cmd(cmd.Cmd):
# Find all normal arguments
arg_list = []
- normal_matches = re.finditer(macro_normal_arg_pattern, value)
+ normal_matches = re.finditer(MacroArg.macro_normal_arg_pattern, value)
max_arg_num = 0
num_set = set()
@@ -2382,8 +2381,9 @@ class Cmd(cmd.Cmd):
try:
cur_match = normal_matches.__next__()
- # Get the number between the braces
- cur_num = int(re.findall(digit_pattern, cur_match.group())[0])
+ # Get the number string between the braces
+ cur_num_str = (re.findall(MacroArg.digit_pattern, cur_match.group())[0])
+ cur_num = int(cur_num_str)
if cur_num < 1:
self.perror("Argument numbers must be greater than 0", traceback_war=False)
return
@@ -2392,7 +2392,7 @@ class Cmd(cmd.Cmd):
if cur_num > max_arg_num:
max_arg_num = cur_num
- arg_list.append(MacroArg(start_index=cur_match.start(), number=cur_num, is_escaped=False))
+ arg_list.append(MacroArg(start_index=cur_match.start(), number_str=cur_num_str, is_escaped=False))
except StopIteration:
break
@@ -2404,16 +2404,16 @@ class Cmd(cmd.Cmd):
return
# Find all escaped arguments
- escaped_matches = re.finditer(macro_escaped_arg_pattern, value)
+ escaped_matches = re.finditer(MacroArg.macro_escaped_arg_pattern, value)
while True:
try:
cur_match = escaped_matches.__next__()
- # Get the number between the braces
- cur_num = int(re.findall(digit_pattern, cur_match.group())[0])
+ # Get the number string between the braces
+ cur_num_str = re.findall(MacroArg.digit_pattern, cur_match.group())[0]
- arg_list.append(MacroArg(start_index=cur_match.start(), number=cur_num, is_escaped=True))
+ arg_list.append(MacroArg(start_index=cur_match.start(), number_str=cur_num_str, is_escaped=True))
except StopIteration:
break
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index 498834cf..949be42e 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -12,17 +12,6 @@ import attr
from . import constants
from . import utils
-# Pattern used to find normal argument
-# Match strings like: {5}, {{{{{4}, {2}}}}}
-macro_normal_arg_pattern = re.compile(r'(?<!\{)\{\d+\}|\{\d+\}(?!\})')
-
-# Pattern used to find escaped arguments (2 or more braces on each side of digit)
-# Match strings like: {{5}}, {{{{{4}}, {{2}}}}}, {{{4}}}
-macro_escaped_arg_pattern = re.compile(r'\{{2}\d+\}{2}')
-
-# Finds a string of digits
-digit_pattern = re.compile(r'\d+')
-
@attr.s(frozen=True)
class MacroArg:
@@ -32,13 +21,28 @@ class MacroArg:
Escaped argument syntax: {{5}}
"""
# The starting index of this argument in the macro value
- start_index = attr.ib(validator=attr.validators.instance_of(int), type=int)
+ start_index = attr.ib(validator=attr.validators.instance_of(int))
- # The number that appears between the braces
- number = attr.ib(validator=attr.validators.instance_of(int), type=int)
+ # The number string that appears between the braces
+ # This is a string instead of an int because we support unicode digits and must be able
+ # to reproduce this string later
+ number_str = attr.ib(validator=attr.validators.instance_of(str))
# Tells if this argument is escaped and therefore needs to be unescaped
- is_escaped = attr.ib(validator=attr.validators.instance_of(bool), type=bool)
+ is_escaped = attr.ib(validator=attr.validators.instance_of(bool))
+
+ # Pattern used to find normal argument
+ # Digits surrounded by exactly 1 brace on a side and 1 or more braces on the opposite side
+ # Match strings like: {5}, {{{{{4}, {2}}}}}
+ macro_normal_arg_pattern = re.compile(r'(?<!\{)\{\d+\}|\{\d+\}(?!\})')
+
+ # Pattern used to find escaped arguments
+ # Digits surrounded by 2 or more braces on both sides
+ # Match strings like: {{5}}, {{{{{4}}, {{2}}}}}
+ macro_escaped_arg_pattern = re.compile(r'\{{2}\d+\}{2}')
+
+ # Finds a string of digits
+ digit_pattern = re.compile(r'\d+')
@attr.s(frozen=True)
@@ -46,16 +50,16 @@ class Macro:
"""Defines a cmd2 macro"""
# Name of the macro
- name = attr.ib(validator=attr.validators.instance_of(str), type=str)
+ name = attr.ib(validator=attr.validators.instance_of(str))
# The string the macro resolves to
- value = attr.ib(validator=attr.validators.instance_of(str), type=str)
+ value = attr.ib(validator=attr.validators.instance_of(str))
# The required number of args the user has to pass to this macro
- required_arg_count = attr.ib(validator=attr.validators.instance_of(int), type=int)
+ required_arg_count = attr.ib(validator=attr.validators.instance_of(int))
# Used to fill in argument placeholders in the macro
- arg_list = attr.ib(factory=list, validator=attr.validators.instance_of(list), type=List[MacroArg])
+ arg_list = attr.ib(factory=list, validator=attr.validators.instance_of(list))
@attr.s(frozen=True)