Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 52 additions & 8 deletions src/tmuxp/cli/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
import logging
import os
import pathlib
import sys
import typing as t

from libtmux.server import Server

from tmuxp import util
from tmuxp import exc, util
from tmuxp._compat import PY3, PYMINOR

from ._colors import Colors, build_description, get_color_mode
from .utils import tmuxp_echo
from .utils import prompt_yes_no, tmuxp_echo

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -65,6 +66,7 @@ class CLIShellNamespace(argparse.Namespace):
shell: CLIShellLiteral | None
use_pythonrc: bool
use_vi_mode: bool
answer_yes: bool


def create_shell_subparser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
Expand Down Expand Up @@ -169,6 +171,14 @@ def create_shell_subparser(parser: argparse.ArgumentParser) -> argparse.Argument
help="use vi-mode in ptpython/ptipython",
default=False,
)
parser.add_argument(
"-y",
"--yes",
dest="answer_yes",
action="store_true",
help="answer yes on attach/create prompts (server, session)",
default=False,
)
return parser


Expand Down Expand Up @@ -201,15 +211,49 @@ def command_shell(

server = Server(socket_name=args.socket_name, socket_path=args.socket_path)

server.raise_if_dead()
interactive = sys.stdin.isatty()

try:
server.raise_if_dead()
except Exception:
if not args.answer_yes and not interactive:
raise
if not (
args.answer_yes
or prompt_yes_no(
"No tmux server running. Start one?",
default=True,
color_mode=color_mode,
)
):
return
server.new_session(session_name=args.session_name or "tmuxp shell")

current_pane = util.get_current_pane(server=server)

session = util.get_session(
server=server,
session_name=args.session_name,
current_pane=current_pane,
)
try:
session = util.get_session(
server=server,
session_name=args.session_name,
current_pane=current_pane,
)
except exc.SessionNotFound:
if not args.answer_yes and not interactive:
raise
target = (
f"Session {args.session_name} does not exist. Create?"
if args.session_name
else "Session does not exist. Create?"
)
if not (
args.answer_yes
or prompt_yes_no(target, default=True, color_mode=color_mode)
):
return
session = server.new_session(session_name=args.session_name)

if current_pane is not None and current_pane.session_id != session.id:
current_pane = None

window = util.get_window(
session=session,
Expand Down
57 changes: 57 additions & 0 deletions tests/cli/test_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,60 @@ def test_shell_interactive(

result = capsys.readouterr()
assert message.format(**template_ctx) in result.err


def test_shell_yes_creates_missing_session(
server: Server,
session: Session,
tmp_path: pathlib.Path,
monkeypatch: pytest.MonkeyPatch,
capsys: pytest.CaptureFixture[str],
) -> None:
"""``tmuxp shell --yes`` creates a missing session instead of raising."""
monkeypatch.setenv("HOME", str(tmp_path))
monkeypatch.delenv("TMUX_PANE", raising=False)
monkeypatch.delenv("TMUX", raising=False)

assert server.socket_name is not None
new_session_name = "shell_prompt_yes_creates"
assert not server.has_session(new_session_name)

cli_args = [
"shell",
f"-L{server.socket_name}",
new_session_name,
"--yes",
"-c",
"print(session.name)",
]

monkeypatch.chdir(tmp_path)
cli.cli(cli_args)

result = capsys.readouterr()
assert new_session_name in result.out
assert server.has_session(new_session_name)


def test_shell_no_yes_non_interactive_raises_for_missing_session(
server: Server,
session: Session,
tmp_path: pathlib.Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Without ``--yes`` and no TTY, a missing session still raises."""
monkeypatch.setenv("HOME", str(tmp_path))
monkeypatch.delenv("TMUX_PANE", raising=False)
monkeypatch.delenv("TMUX", raising=False)
monkeypatch.chdir(tmp_path)

assert server.socket_name is not None
cli_args = [
"shell",
f"-L{server.socket_name}",
"definitely_not_a_session",
"-c",
"print(session.name)",
]
with pytest.raises(exc.TmuxpException, match="Session not found"):
cli.cli(cli_args)
Loading