Skip to content

fix(tmux): fix usage parsing with git master tmux #1381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
45 changes: 40 additions & 5 deletions completions/tmux
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,25 @@ _comp_cmd_tmux__options()
done
}

# Complete arguments to a nested command.
#
# @param $1 the arg type of the command, e.g., command or shell-command
# @param $2... args to the command, starting with the command itself, ending
# before the current word to complete
_comp_cmd_tmux__nested_arguments()
{
local arg_type="$1"
shift
_comp_cmd_tmux__log \
"Attempting completion for arguments to '$1' of type '$arg_type'"

case $arg_type in
command)
_comp_cmd_tmux__subcommand "$@"
;;
esac
}

# Complete arguments to a subcommand.
#
# @param $@ the subcommand followed by its args, ending before the current word
Expand Down Expand Up @@ -239,12 +258,28 @@ _comp_cmd_tmux__subcommand()
# above.
_comp_cmd_tmux__value "$subcommand" "$prev_arg_type"
return
elif [[ $arg_type == argument ]]; then
# New-style usage after
# https://github.com/tmux/tmux/commit/68ffe654990764ed5bdb7efb88e4d01b921fd3d5
# (2025-04-09) ends in `argument ...`
if ((usage_args_index == ${#args[@]} - 2)) &&
[[ ${args[-1]-} == *("[")...*("]") ]]; then
_comp_cmd_tmux__nested_arguments \
"$prev_arg_type" \
"${subcommand_args[@]:args_index-1}"
return
else
_comp_cmd_tmux__log \
"'tmux $subcommand' has unsupported 'argument' in usage"
return
fi
elif [[ $arg_type == arguments ]]; then
if [[ $prev_arg_type == command ]] &&
((usage_args_index == ${#args[@]} - 1)); then
# The usage ends in `command arguments`, so recurse to the new
# subcommand.
_comp_cmd_tmux__subcommand \
# Old-style usage before
# https://github.com/tmux/tmux/commit/68ffe654990764ed5bdb7efb88e4d01b921fd3d5
# (2025-04-09) ends in `arguments`
if ((usage_args_index == ${#args[@]} - 1)); then
_comp_cmd_tmux__nested_arguments \
"$prev_arg_type" \
"${subcommand_args[@]:args_index-1}"
return
else
Expand Down
16 changes: 9 additions & 7 deletions test/t/test_tmux.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ def test_option_without_value(self, completion):
def test_option_multiple_without_value(self, completion):
assert "new-session" in completion

# Tests for _comp_cmd_tmux__nested_arguments()

@pytest.mark.complete(
"tmux bind-key C-a new-window -c ",
cwd="shared/default",
)
def test_nested_arguments_tmux_subcommand(self, completion):
assert completion == ["bar bar.d/", "foo.d/"]

# Tests for _comp_cmd_tmux__subcommand()

@pytest.mark.complete("tmux this-is-not-a-real-subcommand-i-hope ")
Expand All @@ -93,13 +102,6 @@ def test_subcommand_no_positional_arg_completion(self, completion):
def test_subcommand_repetition(self, completion):
assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"]

@pytest.mark.complete(
"tmux bind-key C-a new-window -c ",
cwd="shared/default",
)
def test_subcommand_recursion(self, completion):
assert completion == ["bar bar.d/", "foo.d/"]

@pytest.mark.complete("tmux source-file ", cwd="shared/default")
def test_subcommand_positional_arg_1(self, completion):
assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"]
Expand Down
Loading