| from __future__ import annotations |
|
|
| from prompt_toolkit.completion.filesystem import ExecutableCompleter, PathCompleter |
| from prompt_toolkit.contrib.regular_languages.compiler import compile |
| from prompt_toolkit.contrib.regular_languages.completion import GrammarCompleter |
|
|
| __all__ = [ |
| "SystemCompleter", |
| ] |
|
|
|
|
| class SystemCompleter(GrammarCompleter): |
| """ |
| Completer for system commands. |
| """ |
|
|
| def __init__(self) -> None: |
| |
| g = compile( |
| r""" |
| # First we have an executable. |
| (?P<executable>[^\s]+) |
| |
| # Ignore literals in between. |
| ( |
| \s+ |
| ("[^"]*" | '[^']*' | [^'"]+ ) |
| )* |
| |
| \s+ |
| |
| # Filename as parameters. |
| ( |
| (?P<filename>[^\s]+) | |
| "(?P<double_quoted_filename>[^\s]+)" | |
| '(?P<single_quoted_filename>[^\s]+)' |
| ) |
| """, |
| escape_funcs={ |
| "double_quoted_filename": (lambda string: string.replace('"', '\\"')), |
| "single_quoted_filename": (lambda string: string.replace("'", "\\'")), |
| }, |
| unescape_funcs={ |
| "double_quoted_filename": ( |
| lambda string: string.replace('\\"', '"') |
| ), |
| "single_quoted_filename": (lambda string: string.replace("\\'", "'")), |
| }, |
| ) |
|
|
| |
| super().__init__( |
| g, |
| { |
| "executable": ExecutableCompleter(), |
| "filename": PathCompleter(only_directories=False, expanduser=True), |
| "double_quoted_filename": PathCompleter( |
| only_directories=False, expanduser=True |
| ), |
| "single_quoted_filename": PathCompleter( |
| only_directories=False, expanduser=True |
| ), |
| }, |
| ) |
|
|