Start work on completion for ssh kitten
This commit is contained in:
parent
bd67899943
commit
ec420b8012
65
kittens/ssh/completion.py
Normal file
65
kittens/ssh/completion.py
Normal 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
|
||||||
@ -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]:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user