mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-20 15:35:03 +02:00
Work on parsing copy instructions
This commit is contained in:
@@ -2,5 +2,70 @@
|
|||||||
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
class CopyInstruction:
|
import glob
|
||||||
|
import os
|
||||||
|
import shlex
|
||||||
|
from typing import Iterable, Iterator, List, Optional, Sequence, Tuple
|
||||||
|
|
||||||
|
from kitty.cli import parse_args
|
||||||
|
from kitty.cli_stub import CopyCLIOptions
|
||||||
|
from kitty.types import run_once
|
||||||
|
|
||||||
|
|
||||||
|
@run_once
|
||||||
|
def option_text() -> str:
|
||||||
|
return '''
|
||||||
|
--glob
|
||||||
|
type=bool-set
|
||||||
|
Interpret file arguments as glob patterns.
|
||||||
|
|
||||||
|
|
||||||
|
--dest
|
||||||
|
The destination on the remote computer to copy to. Relative paths are resolved
|
||||||
|
relative to HOME on the remote machine. When this option is not specified, the
|
||||||
|
local file path is used as the remote destination (with the HOME directory
|
||||||
|
getting automatically replaced by the remote HOME). Note that enviroment
|
||||||
|
variables and ~ are not expanded.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def parse_copy_args(args: Optional[Sequence[str]] = None) -> Tuple[CopyCLIOptions, List[str]]:
|
||||||
|
args = list(args or ())
|
||||||
|
try:
|
||||||
|
opts, args = parse_args(result_class=CopyCLIOptions, args=args, ospec=option_text)
|
||||||
|
except SystemExit as e:
|
||||||
|
raise CopyCLIError from e
|
||||||
|
return opts, args
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_file_spec(spec: str, is_glob: bool) -> Iterator[str]:
|
||||||
|
ans = os.path.expandvars(os.path.expanduser(spec))
|
||||||
|
if not os.path.isabs(ans):
|
||||||
|
ans = os.path.expanduser(f'~/{ans}')
|
||||||
|
if is_glob:
|
||||||
|
files = glob.glob(ans)
|
||||||
|
if not files:
|
||||||
|
raise CopyCLIError(f'{spec} does not exist')
|
||||||
|
else:
|
||||||
|
if not os.path.exists(ans):
|
||||||
|
raise CopyCLIError(f'{spec} does not exist')
|
||||||
|
files = [ans]
|
||||||
|
for x in files:
|
||||||
|
yield os.path.normpath(x).replace(os.sep, '/')
|
||||||
|
|
||||||
|
|
||||||
|
class CopyCLIError(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def parse_copy_instructions(val: str) -> Iterable[Tuple[str, CopyCLIOptions]]:
|
||||||
|
opts, args = parse_copy_args(shlex.split(val))
|
||||||
|
locations: List[str] = []
|
||||||
|
for a in args:
|
||||||
|
locations.extend(resolve_file_spec(a, opts.glob))
|
||||||
|
if not locations:
|
||||||
|
raise CopyCLIError('No files to copy specified')
|
||||||
|
if len(locations) > 1 and opts.dest:
|
||||||
|
raise CopyCLIError('Specifying a remote location with more than one file is not supported')
|
||||||
|
for loc in locations:
|
||||||
|
yield loc, opts
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# generated by gen-config.py DO NOT edit
|
# generated by gen-config.py DO NOT edit
|
||||||
|
|
||||||
import typing
|
import typing
|
||||||
import kittens.ssh.copy
|
import kitty.cli_stub
|
||||||
|
|
||||||
|
|
||||||
option_names = ( # {{{
|
option_names = ( # {{{
|
||||||
@@ -12,7 +12,7 @@ class Options:
|
|||||||
hostname: str = '*'
|
hostname: str = '*'
|
||||||
remote_dir: str = '.local/share/kitty-ssh-kitten'
|
remote_dir: str = '.local/share/kitty-ssh-kitten'
|
||||||
shell_integration: str = 'inherit'
|
shell_integration: str = 'inherit'
|
||||||
copy: typing.Dict[str, kittens.ssh.copy.CopyInstruction] = {}
|
copy: typing.Dict[str, kitty.cli_stub.CLIOptions] = {}
|
||||||
env: typing.Dict[str, str] = {}
|
env: typing.Dict[str, str] = {}
|
||||||
config_paths: typing.Tuple[str, ...] = ()
|
config_paths: typing.Tuple[str, ...] = ()
|
||||||
config_overrides: typing.Tuple[str, ...] = ()
|
config_overrides: typing.Tuple[str, ...] = ()
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
from typing import Any, Dict, Optional, Iterable, Tuple
|
|
||||||
import posixpath
|
import posixpath
|
||||||
|
from typing import Any, Dict, Iterable, Optional, Tuple
|
||||||
|
|
||||||
from ..copy import CopyInstruction
|
from kitty.cli_stub import CopyCLIOptions
|
||||||
|
|
||||||
|
from ..copy import parse_copy_instructions
|
||||||
|
|
||||||
DELETE_ENV_VAR = '_delete_this_env_var_'
|
DELETE_ENV_VAR = '_delete_this_env_var_'
|
||||||
|
|
||||||
@@ -32,8 +33,8 @@ def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
|
|||||||
yield val, DELETE_ENV_VAR
|
yield val, DELETE_ENV_VAR
|
||||||
|
|
||||||
|
|
||||||
def copy(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, CopyInstruction]]:
|
def copy(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, CopyCLIOptions]]:
|
||||||
pass
|
yield from parse_copy_instructions(val)
|
||||||
|
|
||||||
|
|
||||||
def init_results_dict(ans: Dict[str, Any]) -> Dict[str, Any]:
|
def init_results_dict(ans: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ LaunchCLIOptions = AskCLIOptions = ClipboardCLIOptions = DiffCLIOptions = CLIOpt
|
|||||||
HintsCLIOptions = IcatCLIOptions = PanelCLIOptions = ResizeCLIOptions = CLIOptions
|
HintsCLIOptions = IcatCLIOptions = PanelCLIOptions = ResizeCLIOptions = CLIOptions
|
||||||
ErrorCLIOptions = UnicodeCLIOptions = RCOptions = RemoteFileCLIOptions = CLIOptions
|
ErrorCLIOptions = UnicodeCLIOptions = RCOptions = RemoteFileCLIOptions = CLIOptions
|
||||||
QueryTerminalCLIOptions = BroadcastCLIOptions = ShowKeyCLIOptions = CLIOptions
|
QueryTerminalCLIOptions = BroadcastCLIOptions = ShowKeyCLIOptions = CLIOptions
|
||||||
ThemesCLIOptions = TransferCLIOptions = CLIOptions
|
ThemesCLIOptions = TransferCLIOptions = CopyCLIOptions = CLIOptions
|
||||||
|
|
||||||
|
|
||||||
def generate_stub() -> None:
|
def generate_stub() -> None:
|
||||||
@@ -78,6 +78,9 @@ def generate_stub() -> None:
|
|||||||
from kittens.transfer.main import option_text as OPTIONS
|
from kittens.transfer.main import option_text as OPTIONS
|
||||||
do(OPTIONS(), 'TransferCLIOptions')
|
do(OPTIONS(), 'TransferCLIOptions')
|
||||||
|
|
||||||
|
from kittens.ssh.copy import option_text as OPTIONS
|
||||||
|
do(OPTIONS(), 'CopyCLIOptions')
|
||||||
|
|
||||||
from kitty.rc.base import all_command_names, command_for_name
|
from kitty.rc.base import all_command_names, command_for_name
|
||||||
for cmd_name in all_command_names():
|
for cmd_name in all_command_names():
|
||||||
cmd = command_for_name(cmd_name)
|
cmd = command_for_name(cmd_name)
|
||||||
|
|||||||
Reference in New Issue
Block a user