From 6bd0783c11f72019ffe222f7088ba408fc407278 Mon Sep 17 00:00:00 2001 From: Stoiko Ivanov Date: Tue, 30 Jul 2019 14:42:12 +0200 Subject: [PATCH] CLIHandler: consider valid prefixes for completion With the change introduced in 57c0d0c69c687f2dff876aa81369622d0ae0a841 completion of partial commands stopped working (e.g. typing qm res yields nothing instead of 'reset resize resume rescan') By returning undef as 'ref' 'print_bash_completion' has no reference of the available (sub) commands anymore. By checking if the current argument is a valid prefix of a possible command, and conditionally not setting the 'ref' hash to undef, the functionality is restored. Additionally a small whitespace glitch was fixed. Signed-off-by: Stoiko Ivanov --- src/PVE/CLIHandler.pm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/PVE/CLIHandler.pm b/src/PVE/CLIHandler.pm index 802ce87..7e87a40 100644 --- a/src/PVE/CLIHandler.pm +++ b/src/PVE/CLIHandler.pm @@ -108,13 +108,15 @@ my $abort = sub { }; my $expand_command_name = sub { - my ($def, $cmd) = @_; + my ($def, $cmd, $enforce_exact) = @_; return $cmd if exists $def->{$cmd}; # command is already complete my $is_alias = sub { ref($_[0]) eq 'HASH' && exists($_[0]->{alias}) }; my @expanded = grep { /^\Q$cmd\E/ && !$is_alias->($def->{$_}) } keys %$def; + return @expanded if !$enforce_exact; + return $expanded[0] if scalar(@expanded) == 1; # enforce exact match return undef; @@ -143,18 +145,23 @@ sub resolve_cmd { my $last_arg_id = scalar(@$argv) - 1; for my $i (0..$last_arg_id) { - $cmd = $expand_command_name->($def, $argv->[$i]); + $cmd = $expand_command_name->($def, $argv->[$i], 1); if (defined($cmd)) { # If the argument was expanded (or was already complete) and it # is the final argument, tell our caller about it: $expanded_last_arg = $cmd if $i == $last_arg_id; } else { # Otherwise continue with the unexpanded version of it. - $cmd = $argv->[$i]; + $cmd = $argv->[$i]; } $cmdstr .= " $cmd"; + if (!defined($def->{$cmd})) { + # $cmd still could be a valid prefix for bash_completion + # in that case keep $def as it is, else set it to undef + $def = undef if !$expand_command_name->($def, $cmd); + last; + } $def = $def->{$cmd}; - last if !defined($def); if (ref($def) eq 'ARRAY') { # could expand to a real command, rest of $argv are its arguments -- 2.39.2