Have *_with_cwd work with the ssh kitten to open new windows auto-logged into the remote server at the current remote working directory
This commit is contained in:
parent
a216f6bd46
commit
ce1e22ac95
@ -27,6 +27,13 @@ rc files:
|
||||
|
||||
So you can now type just ``s hostname`` to connect.
|
||||
|
||||
If you define a mapping in :file:`kitty.conf` such as::
|
||||
|
||||
map f1 new_window_with_cwd
|
||||
|
||||
Then, pressing :kbd:`F1` will open a new window automatically logged
|
||||
into the same server using the ssh kitten, at the same directory.
|
||||
|
||||
The ssh kitten can be configured using the :file:`~/.config/kitty/ssh.conf`
|
||||
file where you can specify environment variables to set on the remote server
|
||||
and files to copy from your local machine to the remote server. Let's see a
|
||||
|
||||
@ -68,7 +68,10 @@ no-title
|
||||
setting functionality instead.
|
||||
|
||||
no-cwd
|
||||
Turn off reporting
|
||||
Turn off reporting the current working directory. This is used to allow
|
||||
:ref:`action-new_window_with_cwd` and similar to open windows logged
|
||||
into remote machines using the :doc:`ssh kitten <kitten/ssh>`
|
||||
automatically with the same working directory as the current window.
|
||||
|
||||
no-prompt-mark
|
||||
Turn off marking of prompts. This disables jumping to prompt, browsing
|
||||
|
||||
@ -42,6 +42,27 @@ from .copy import CopyInstruction
|
||||
from .options.types import Options as SSHOptions
|
||||
from .options.utils import DELETE_ENV_VAR
|
||||
|
||||
|
||||
def is_kitten_cmdline(q: List[str]) -> bool:
|
||||
if len(q) < 4:
|
||||
return False
|
||||
if os.path.basename(q[0]).lower() != 'kitty':
|
||||
return False
|
||||
return q[1:3] == ['+kitten', 'ssh'] or q[1:4] == ['+', 'kitten', 'ssh']
|
||||
|
||||
|
||||
def set_cwd_in_cmdline(cwd: str, argv: List[str]) -> None:
|
||||
for i, arg in enumerate(tuple(argv)):
|
||||
if arg.startswith('--kitten=cwd'):
|
||||
argv[i] = f'--kitten=cwd={cwd}'
|
||||
return
|
||||
elif i > 0 and argv[i-1] == '--kitten' and (arg.startswith('cwd=') or arg.startswith('cwd ')):
|
||||
argv[i] = cwd
|
||||
return
|
||||
idx = argv.index('ssh')
|
||||
argv.insert(idx + 1, f'--kitten=cwd={cwd}')
|
||||
|
||||
|
||||
# See https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
|
||||
quote_pat = re.compile('([\\`"\n])')
|
||||
|
||||
|
||||
@ -201,7 +201,7 @@ class Child:
|
||||
self.argv = list(argv)
|
||||
if cwd_from is not None:
|
||||
try:
|
||||
cwd = cwd_from.cwd_of_child or cwd
|
||||
cwd = cwd_from.modify_argv_for_launch_with_cwd(self.argv) or cwd
|
||||
except Exception as err:
|
||||
log_error(f'Failed to read cwd of {cwd_from} with error: {err}')
|
||||
else:
|
||||
|
||||
@ -936,3 +936,12 @@ def cleanup_ssh_control_masters() -> None:
|
||||
for x in files:
|
||||
with suppress(OSError):
|
||||
os.remove(x)
|
||||
|
||||
|
||||
def path_from_osc7_url(url: str) -> str:
|
||||
if url.startswith('kitty-shell-cwd://'):
|
||||
return '/' + url.split('/', 3)[-1]
|
||||
if url.startswith('file://'):
|
||||
from urllib.parse import urlparse
|
||||
return urlparse(url).path
|
||||
return ''
|
||||
|
||||
@ -20,7 +20,7 @@ from typing import (
|
||||
from .child import ProcessDesc
|
||||
from .cli_stub import CLIOptions
|
||||
from .config import build_ansi_color_table
|
||||
from .constants import appname, is_macos, wakeup
|
||||
from .constants import appname, is_macos, shell_path, wakeup
|
||||
from .fast_data_types import (
|
||||
BGIMAGE_PROGRAM, BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM,
|
||||
CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CURSOR_BEAM, CURSOR_BLOCK,
|
||||
@ -46,8 +46,8 @@ from .types import MouseEvent, WindowGeometry, ac
|
||||
from .typing import BossType, ChildType, EdgeLiteral, TabType, TypedDict
|
||||
from .utils import (
|
||||
get_primary_selection, kitty_ansi_sanitizer_pat, load_shaders, log_error,
|
||||
open_cmd, open_url, parse_color_set, resolve_custom_file, sanitize_title,
|
||||
set_primary_selection
|
||||
open_cmd, open_url, parse_color_set, path_from_osc7_url,
|
||||
resolve_custom_file, sanitize_title, set_primary_selection
|
||||
)
|
||||
|
||||
MatchPatternType = Union[Pattern[str], Tuple[Pattern[str], Optional[Pattern[str]]]]
|
||||
@ -323,6 +323,7 @@ def cmd_output(screen: Screen, which: CommandOutput = CommandOutput.last_run, as
|
||||
|
||||
def process_remote_print(msg: str) -> str:
|
||||
from base64 import standard_b64decode
|
||||
|
||||
from .cli import green
|
||||
text = standard_b64decode(msg).decode('utf-8', 'replace')
|
||||
return text.replace('\x1b', green(r'\e')).replace('\a', green(r'\a')).replace('\0', green(r'\0'))
|
||||
@ -1138,6 +1139,23 @@ class Window:
|
||||
def cwd_of_child(self) -> Optional[str]:
|
||||
return self.child.foreground_cwd or self.child.current_cwd
|
||||
|
||||
def modify_argv_for_launch_with_cwd(self, argv: List[str]) -> str:
|
||||
if argv[0] != shell_path or not self.screen.last_reported_cwd:
|
||||
return self.cwd_of_child or ''
|
||||
from kittens.ssh.main import is_kitten_cmdline, set_cwd_in_cmdline
|
||||
ssh_kitten_cmdline: List[str] = []
|
||||
for p in self.child.foreground_processes:
|
||||
q = list(p['cmdline'] or ())
|
||||
if is_kitten_cmdline(q):
|
||||
ssh_kitten_cmdline = q
|
||||
break
|
||||
if ssh_kitten_cmdline:
|
||||
cwd = path_from_osc7_url(self.screen.last_reported_cwd)
|
||||
if cwd:
|
||||
set_cwd_in_cmdline(path_from_osc7_url(self.screen.last_reported_cwd), ssh_kitten_cmdline)
|
||||
argv[:] = ssh_kitten_cmdline
|
||||
return self.cwd_of_child or ''
|
||||
|
||||
def pipe_data(self, text: str, has_wrap_markers: bool = False) -> PipeData:
|
||||
text = text or ''
|
||||
if has_wrap_markers:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user