Skip to content

Commit

Permalink
✨ let find_shortcut return trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Oct 22, 2024
1 parent 6cf69bc commit be89b14
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 13 deletions.
10 changes: 6 additions & 4 deletions src/arclet/alconna/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
InvalidHeader,
PauseTriggered,
)
from .shortcut import wrap_shortcut, InnerShortcutArgs, ShortcutRegWrapper, find_shortcut
from .shortcut import wrap_shortcut, InnerShortcutArgs, ShortcutRegWrapper
from .completion import prompt, comp_ctx
from .formatter import TextFormatter
from .manager import ShortcutArgs, command_manager
Expand Down Expand Up @@ -440,16 +440,18 @@ def _parse(self, message: TDC, ctx: dict[str, Any] | None = None) -> Arparma[TDC
if isinstance(exc, InvalidHeader):
trigger = exc.context_node
if trigger.__class__ is str and trigger:
argv.context[SHORTCUT_TRIGGER] = trigger
try:
rest, short, mat = command_manager.find_shortcut(self, [trigger] + argv.release(no_split=True))
key, rest, short, mat = command_manager.find_shortcut(self, [trigger] + argv.release(no_split=True))
argv.context[SHORTCUT_TRIGGER] = key
argv.context[SHORTCUT_ARGS] = short
argv.context[SHORTCUT_REST] = rest
argv.context[SHORTCUT_REGEX_MATCH] = mat
_origin = argv.origin
argv.reset()
argv.origin = _origin
argv.addon(wrap_shortcut(rest, short, mat, argv.context), merge_str=False)
analyser.header_result = analyse_header(self._header, argv)
analyser.header_result.origin = trigger
analyser.header_result.origin = key
if not (exc := analyser.process(argv)):
return analyser.export(argv)
except ValueError:
Expand Down
4 changes: 2 additions & 2 deletions src/arclet/alconna/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,15 @@ def get_shortcut(self, target: Alconna) -> dict[str, InnerShortcutArgs]:

def find_shortcut(
self, target: Alconna, data: list
) -> tuple[list, InnerShortcutArgs, Match[str] | None]:
) -> tuple[str, list, InnerShortcutArgs, Match[str] | None]:
"""查找快捷命令
Args:
target (Alconna): 目标命令对象
data (list): 传入的命令数据
Returns:
tuple[list, InnerShortcutArgs, re.Match[str]]: 返回匹配的快捷命令
tuple[str, list, InnerShortcutArgs, re.Match[str]]: 返回匹配的快捷命令
"""
namespace, name = self._command_part(target.path)
if not (_shortcut := self._shortcuts.get(f"{namespace}::{name}")):
Expand Down
14 changes: 8 additions & 6 deletions src/arclet/alconna/shortcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,18 +267,20 @@ def wrap_shortcut(


def find_shortcut(table: dict[str, InnerShortcutArgs], data: list, separators: str = " "):
query: str = data.pop(0)
query = data.pop(0)
if not isinstance(query, str):
return
while True:
if query in table:
return data, table[query], None
return query, data, table[query], None
for key, args in table.items():
if args.fuzzy and (mat := re.match(f"^{key}", query, args.flags)):
if len(query) > mat.span()[1]:
data.insert(0, query[mat.span()[1]:])
return data, args, mat
data.insert(0, query[mat.span()[1]:].lstrip(separators))
return query, data, args, mat
elif mat := re.fullmatch(key, query, args.flags):
if not (not args.fuzzy and data):
return data, table[key], mat
return query, data, table[key], mat
if not data:
break
next_data = data.pop(0)
Expand All @@ -301,5 +303,5 @@ def execute_shortcut(table: dict[str, InnerShortcutArgs], data: list, separators
list: 处理后的参数列表
"""
if res := find_shortcut(table, data.copy(), separators):
return wrap_shortcut(*res, ctx=ctx or {})
return wrap_shortcut(*res[1:], ctx=ctx or {})
return data
2 changes: 1 addition & 1 deletion tests/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ def test_shortcut():
alc16 = Alconna("core16", Args["foo", int], Option("bar", Args["baz", str]))
assert alc16.parse("core16 123 bar abcd").matched is True
# 构造体缩写传入;{i} 将被可能的正则匹配替换
alc16.shortcut(r"TEST(\d+)(.+)", {"args": ["{0}", "bar {1}"]})
alc16.shortcut(r"TEST(\d+)(\w+)", {"args": ["{0}", "bar {1}"]})
res = alc16.parse("TEST123aa")
assert res.header_match.origin == "TEST123aa"
assert res.matched is True
Expand Down

0 comments on commit be89b14

Please sign in to comment.