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.
|
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`
|
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
|
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
|
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.
|
setting functionality instead.
|
||||||
|
|
||||||
no-cwd
|
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
|
no-prompt-mark
|
||||||
Turn off marking of prompts. This disables jumping to prompt, browsing
|
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.types import Options as SSHOptions
|
||||||
from .options.utils import DELETE_ENV_VAR
|
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
|
# See https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
|
||||||
quote_pat = re.compile('([\\`"\n])')
|
quote_pat = re.compile('([\\`"\n])')
|
||||||
|
|
||||||
|
|||||||
@ -201,7 +201,7 @@ class Child:
|
|||||||
self.argv = list(argv)
|
self.argv = list(argv)
|
||||||
if cwd_from is not None:
|
if cwd_from is not None:
|
||||||
try:
|
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:
|
except Exception as err:
|
||||||
log_error(f'Failed to read cwd of {cwd_from} with error: {err}')
|
log_error(f'Failed to read cwd of {cwd_from} with error: {err}')
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -936,3 +936,12 @@ def cleanup_ssh_control_masters() -> None:
|
|||||||
for x in files:
|
for x in files:
|
||||||
with suppress(OSError):
|
with suppress(OSError):
|
||||||
os.remove(x)
|
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 .child import ProcessDesc
|
||||||
from .cli_stub import CLIOptions
|
from .cli_stub import CLIOptions
|
||||||
from .config import build_ansi_color_table
|
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 (
|
from .fast_data_types import (
|
||||||
BGIMAGE_PROGRAM, BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM,
|
BGIMAGE_PROGRAM, BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM,
|
||||||
CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CURSOR_BEAM, CURSOR_BLOCK,
|
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 .typing import BossType, ChildType, EdgeLiteral, TabType, TypedDict
|
||||||
from .utils import (
|
from .utils import (
|
||||||
get_primary_selection, kitty_ansi_sanitizer_pat, load_shaders, log_error,
|
get_primary_selection, kitty_ansi_sanitizer_pat, load_shaders, log_error,
|
||||||
open_cmd, open_url, parse_color_set, resolve_custom_file, sanitize_title,
|
open_cmd, open_url, parse_color_set, path_from_osc7_url,
|
||||||
set_primary_selection
|
resolve_custom_file, sanitize_title, set_primary_selection
|
||||||
)
|
)
|
||||||
|
|
||||||
MatchPatternType = Union[Pattern[str], Tuple[Pattern[str], Optional[Pattern[str]]]]
|
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:
|
def process_remote_print(msg: str) -> str:
|
||||||
from base64 import standard_b64decode
|
from base64 import standard_b64decode
|
||||||
|
|
||||||
from .cli import green
|
from .cli import green
|
||||||
text = standard_b64decode(msg).decode('utf-8', 'replace')
|
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'))
|
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]:
|
def cwd_of_child(self) -> Optional[str]:
|
||||||
return self.child.foreground_cwd or self.child.current_cwd
|
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:
|
def pipe_data(self, text: str, has_wrap_markers: bool = False) -> PipeData:
|
||||||
text = text or ''
|
text = text or ''
|
||||||
if has_wrap_markers:
|
if has_wrap_markers:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user