Start work on completion for ssh kitten

This commit is contained in:
Kovid Goyal 2021-06-25 10:48:58 +05:30
parent bd67899943
commit ec420b8012
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 74 additions and 14 deletions

65
kittens/ssh/completion.py Normal file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import os
import subprocess
from typing import Dict, Iterator, Tuple
from kitty.types import run_once
def iter_known_hosts() -> Iterator[str]:
try:
f = open(os.path.expanduser('~/.ssh/config'))
except OSError:
pass
else:
for line in f:
parts = line.split()
if parts and parts[0] == 'Host' and len(parts) > 1:
yield parts[1]
try:
f = open(os.path.expanduser('~/.ssh/known_hosts'))
except OSError:
pass
else:
for line in f:
parts = line.split()
if parts:
yield parts[0]
@run_once
def known_hosts() -> Tuple[str, ...]:
return tuple(iter_known_hosts())
@run_once
def ssh_options() -> Dict[str, str]:
stderr = subprocess.Popen(['ssh'], stderr=subprocess.PIPE).stderr
assert stderr is not None
raw = stderr.read().decode('utf-8')
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

View File

@ -3,12 +3,12 @@
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os import os
import re
import shlex import shlex
import subprocess import subprocess
import sys import sys
from contextlib import suppress from contextlib import suppress
from typing import List, NoReturn, Optional, Set, Tuple from typing import List, NoReturn, Optional, Set, Tuple
from .completion import ssh_options
from kitty.utils import SSHConnectionData from kitty.utils import SSHConnectionData
@ -129,20 +129,15 @@ os.execlp(shell_path, shell_name)
def get_ssh_cli() -> Tuple[Set[str], Set[str]]: def get_ssh_cli() -> Tuple[Set[str], Set[str]]:
other_ssh_args: List[str] = [] other_ssh_args: Set[str] = set()
boolean_ssh_args: List[str] = [] boolean_ssh_args: Set[str] = set()
stderr = subprocess.Popen(['ssh'], stderr=subprocess.PIPE).stderr for k, v in ssh_options().items():
assert stderr is not None k = '-' + k
raw = stderr.read().decode('utf-8') if v:
for m in re.finditer(r'\[(.+?)\]', raw): other_ssh_args.add(k)
q = m.group(1)
if len(q) < 2 or q[0] != '-':
continue
if ' ' in q:
other_ssh_args.append(q[1])
else: else:
boolean_ssh_args.extend(q[1:]) boolean_ssh_args.add(k)
return set('-' + x for x in boolean_ssh_args), set('-' + x for x in other_ssh_args) return boolean_ssh_args, other_ssh_args
def get_connection_data(args: List[str]) -> Optional[SSHConnectionData]: def get_connection_data(args: List[str]) -> Optional[SSHConnectionData]: