From 55eeb9c11e0a1875a2efd7c7cd1beb0677de257b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 2 Jun 2022 08:08:33 +0530 Subject: [PATCH] Dont import kitty.complete in ssh.main --- kittens/ssh/completion.py | 42 +------------------------------------ kittens/ssh/main.py | 4 ++-- kittens/ssh/utils.py | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/kittens/ssh/completion.py b/kittens/ssh/completion.py index 6ac079263..6fe21f773 100644 --- a/kittens/ssh/completion.py +++ b/kittens/ssh/completion.py @@ -8,6 +8,7 @@ from typing import Callable, Dict, Iterable, Iterator, Sequence, Tuple from kitty.complete import Completions, complete_files_and_dirs, debug from kitty.types import run_once +from .utils import ssh_options debug @@ -71,47 +72,6 @@ def known_hosts() -> Tuple[str, ...]: return tuple(sorted(filter(lambda x: '*' not in x and '[' not in x, set(iter_known_hosts())))) -@run_once -def ssh_options() -> Dict[str, str]: - try: - p = subprocess.run(['ssh'], stderr=subprocess.PIPE, encoding='utf-8') - raw = p.stderr or '' - except FileNotFoundError: - return { - '4': '', '6': '', 'A': '', 'a': '', 'C': '', 'f': '', 'G': '', 'g': '', 'K': '', 'k': '', - 'M': '', 'N': '', 'n': '', 'q': '', 's': '', 'T': '', 't': '', 'V': '', 'v': '', 'X': '', - 'x': '', 'Y': '', 'y': '', 'B': 'bind_interface', 'b': 'bind_address', 'c': 'cipher_spec', - 'D': '[bind_address:]port', 'E': 'log_file', 'e': 'escape_char', 'F': 'configfile', 'I': 'pkcs11', - 'i': 'identity_file', 'J': '[user@]host[:port]', 'L': 'address', 'l': 'login_name', 'm': 'mac_spec', - 'O': 'ctl_cmd', 'o': 'option', 'p': 'port', 'Q': 'query_option', 'R': 'address', - 'S': 'ctl_path', 'W': 'host:port', 'w': 'local_tun[:remote_tun]' - } - - ans: Dict[str, str] = {} - pos = 0 - while True: - pos = raw.find('[', pos) - if pos < 0: - break - num = 1 - epos = pos - while num > 0: - epos += 1 - if raw[epos] not in '[]': - continue - num += 1 if raw[epos] == '[' else -1 - q = raw[pos+1:epos] - pos = epos - if len(q) < 2 or q[0] != '-': - continue - if ' ' in q: - opt, desc = q.split(' ', 1) - ans[opt[1:]] = desc - else: - ans.update(dict.fromkeys(q[1:], '')) - return ans - - # option help {{{ @run_once def option_help_map() -> Dict[str, str]: diff --git a/kittens/ssh/main.py b/kittens/ssh/main.py index 5090e5c24..7c6f729a2 100644 --- a/kittens/ssh/main.py +++ b/kittens/ssh/main.py @@ -41,12 +41,11 @@ from kitty.utils import ( set_echo as turn_off_echo, suppress_error_logging ) -from .completion import complete, ssh_options from .config import init_config from .copy import CopyInstruction from .options.types import Options as SSHOptions from .options.utils import DELETE_ENV_VAR -from .utils import create_shared_memory +from .utils import create_shared_memory, ssh_options @run_once @@ -735,6 +734,7 @@ def main(args: List[str]) -> NoReturn: if __name__ == '__main__': main(sys.argv) elif __name__ == '__completer__': + from .completion import complete setattr(sys, 'kitten_completer', complete) elif __name__ == '__conf__': from .options.definition import definition diff --git a/kittens/ssh/utils.py b/kittens/ssh/utils.py index 0f4fb3f50..1861102a9 100644 --- a/kittens/ssh/utils.py +++ b/kittens/ssh/utils.py @@ -3,8 +3,52 @@ import os +import subprocess from typing import Any, Dict, List +from kitty.types import run_once + + +@run_once +def ssh_options() -> Dict[str, str]: + try: + p = subprocess.run(['ssh'], stderr=subprocess.PIPE, encoding='utf-8') + raw = p.stderr or '' + except FileNotFoundError: + return { + '4': '', '6': '', 'A': '', 'a': '', 'C': '', 'f': '', 'G': '', 'g': '', 'K': '', 'k': '', + 'M': '', 'N': '', 'n': '', 'q': '', 's': '', 'T': '', 't': '', 'V': '', 'v': '', 'X': '', + 'x': '', 'Y': '', 'y': '', 'B': 'bind_interface', 'b': 'bind_address', 'c': 'cipher_spec', + 'D': '[bind_address:]port', 'E': 'log_file', 'e': 'escape_char', 'F': 'configfile', 'I': 'pkcs11', + 'i': 'identity_file', 'J': '[user@]host[:port]', 'L': 'address', 'l': 'login_name', 'm': 'mac_spec', + 'O': 'ctl_cmd', 'o': 'option', 'p': 'port', 'Q': 'query_option', 'R': 'address', + 'S': 'ctl_path', 'W': 'host:port', 'w': 'local_tun[:remote_tun]' + } + + ans: Dict[str, str] = {} + pos = 0 + while True: + pos = raw.find('[', pos) + if pos < 0: + break + num = 1 + epos = pos + while num > 0: + epos += 1 + if raw[epos] not in '[]': + continue + num += 1 if raw[epos] == '[' else -1 + q = raw[pos+1:epos] + pos = epos + if len(q) < 2 or q[0] != '-': + continue + if ' ' in q: + opt, desc = q.split(' ', 1) + ans[opt[1:]] = desc + else: + ans.update(dict.fromkeys(q[1:], '')) + return ans + def is_kitten_cmdline(q: List[str]) -> bool: if len(q) < 4: