f
This commit is contained in:
117
CLI.py
117
CLI.py
@@ -419,16 +419,16 @@ class CmdletCompleter(Completer):
|
||||
return
|
||||
|
||||
arg_names = CmdletIntrospection.cmdlet_args(cmd_name, config)
|
||||
logical_seen: Set[str] = set()
|
||||
seen_logicals: Set[str] = set()
|
||||
for arg in arg_names:
|
||||
arg_low = arg.lower()
|
||||
if arg_low.startswith("--"):
|
||||
continue
|
||||
logical = arg.lstrip("-").lower()
|
||||
if logical in logical_seen:
|
||||
if logical in seen_logicals:
|
||||
continue
|
||||
yield Completion(arg, start_position=0)
|
||||
logical_seen.add(logical)
|
||||
seen_logicals.add(logical)
|
||||
|
||||
yield Completion("-help", start_position=0)
|
||||
return
|
||||
@@ -541,117 +541,6 @@ class CmdletCompleter(Completer):
|
||||
yield Completion("-help", start_position=-len(current_token))
|
||||
|
||||
|
||||
# Lexer implementation removed; use `MedeiaLexer` from `SYS.cli_parsing` instead.
|
||||
|
||||
line = document.lines[lineno]
|
||||
tokens: List[tuple[str, str]] = []
|
||||
|
||||
pattern = re.compile(
|
||||
r"""
|
||||
(\s+) | # 1. Whitespace
|
||||
(\|) | # 2. Pipe
|
||||
("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*') | # 3. Quoted string
|
||||
([^\s\|]+) # 4. Word
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
is_cmdlet = True
|
||||
|
||||
def _emit_keyed_value(word: str) -> bool:
|
||||
"""Emit `key:` prefixes (comma-separated) as argument tokens.
|
||||
|
||||
Designed for values like:
|
||||
clip:3m4s-3m14s,1h22m-1h33m,item:2-3
|
||||
|
||||
Avoids special-casing URLs (://) and Windows drive paths (C:\\...).
|
||||
Returns True if it handled the token.
|
||||
"""
|
||||
if not word or ":" not in word:
|
||||
return False
|
||||
# Avoid URLs and common scheme patterns.
|
||||
if "://" in word:
|
||||
return False
|
||||
# Avoid Windows drive paths (e.g., C:\foo or D:/bar)
|
||||
if re.match(r"^[A-Za-z]:[\\/]", word):
|
||||
return False
|
||||
|
||||
key_prefix = re.compile(r"^([A-Za-z_][A-Za-z0-9_-]*:)(.*)$")
|
||||
parts = word.split(",")
|
||||
handled_any = False
|
||||
for i, part in enumerate(parts):
|
||||
if i > 0:
|
||||
tokens.append(("class:value", ","))
|
||||
if part == "":
|
||||
continue
|
||||
m = key_prefix.match(part)
|
||||
if m:
|
||||
tokens.append(("class:argument", m.group(1)))
|
||||
if m.group(2):
|
||||
tokens.append(("class:value", m.group(2)))
|
||||
handled_any = True
|
||||
else:
|
||||
tokens.append(("class:value", part))
|
||||
handled_any = True
|
||||
|
||||
return handled_any
|
||||
|
||||
for match in pattern.finditer(line):
|
||||
ws, pipe, quote, word = match.groups()
|
||||
if ws:
|
||||
tokens.append(("", ws))
|
||||
continue
|
||||
if pipe:
|
||||
tokens.append(("class:pipe", pipe))
|
||||
is_cmdlet = True
|
||||
continue
|
||||
if quote:
|
||||
# If the quoted token contains a keyed spec (clip:/item:/hash:),
|
||||
# highlight the `key:` portion in argument-blue even inside quotes.
|
||||
if len(quote) >= 2 and quote[0] == quote[-1] and quote[0] in ('"',
|
||||
"'"):
|
||||
q = quote[0]
|
||||
inner = quote[1:-1]
|
||||
start_index = len(tokens)
|
||||
if _emit_keyed_value(inner):
|
||||
# _emit_keyed_value already appended tokens for inner; insert opening quote
|
||||
# before that chunk, then add the closing quote.
|
||||
tokens.insert(start_index, ("class:string", q))
|
||||
tokens.append(("class:string", q))
|
||||
is_cmdlet = False
|
||||
continue
|
||||
|
||||
tokens.append(("class:string", quote))
|
||||
is_cmdlet = False
|
||||
continue
|
||||
if not word:
|
||||
continue
|
||||
|
||||
if word.startswith("@"): # selection tokens
|
||||
rest = word[1:]
|
||||
if rest and re.fullmatch(r"[0-9\-\*,]+", rest):
|
||||
tokens.append(("class:selection_at", "@"))
|
||||
tokens.append(("class:selection_range", rest))
|
||||
is_cmdlet = False
|
||||
continue
|
||||
if rest == "":
|
||||
tokens.append(("class:selection_at", "@"))
|
||||
is_cmdlet = False
|
||||
continue
|
||||
|
||||
if is_cmdlet:
|
||||
tokens.append(("class:cmdlet", word))
|
||||
is_cmdlet = False
|
||||
elif word.startswith("-"):
|
||||
tokens.append(("class:argument", word))
|
||||
else:
|
||||
if not _emit_keyed_value(word):
|
||||
tokens.append(("class:value", word))
|
||||
|
||||
return tokens
|
||||
|
||||
return get_line
|
||||
|
||||
|
||||
class ConfigLoader:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user