Resolve relative paths in command names for complete -p

Fixes #6001
This commit is contained in:
Karolina Gontarek 2021-05-11 23:02:15 +02:00 committed by Johannes Altmanninger
parent c38f4980f9
commit 31f3c16857
4 changed files with 37 additions and 5 deletions

View File

@ -69,6 +69,7 @@ Completions
- ``firewall-cmd`` (:issue:`7900`)
- Commands that wrap ``cd`` (using ``complete --wraps cd``) get the same completions as ``cd`` (:issue:`4693`).
- Completion defined with ``complete -p`` now also work when the commandline uses a relative path to the command (:issue:`6001`).
Improved terminal support
^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -573,9 +573,13 @@ void complete_remove_all(const wcstring &cmd, bool cmd_is_path) {
/// Find the full path and commandname from a command string 'str'.
static void parse_cmd_string(const wcstring &str, wcstring *path, wcstring *cmd,
const environment_t &vars) {
if (!path_get_path(str, path, vars)) {
/// Use the empty string as the 'path' for commands that can not be found.
path->clear();
bool found = path_get_path(str, path, vars);
// If the command was not found, 'path' is the empty string.
// Resolve commands that use relative paths because we compare full paths with "complete -p".
if (found && !str.empty() && str.at(0) != L'/') {
if (auto full_path = wrealpath(*path)) {
path->assign(full_path.acquire());
}
}
// Make sure the path is not included in the command.

View File

@ -41,11 +41,11 @@ int path_get_config_is_remote();
class env_stack_t;
void path_emit_config_directory_messages(env_stack_t &vars);
/// Finds the full path of an executable.
/// Finds the path of an executable.
///
/// Args:
/// cmd - The name of the executable.
/// output_or_NULL - If non-NULL, store the full path.
/// output_or_NULL - If non-NULL, store the path.
/// vars - The environment variables to use
///
/// Returns:

View File

@ -396,3 +396,30 @@ complete -C'fudge eat yummyin'
cd -
rm -r $dir
set -l dir (mktemp -d)
cd $dir
cd -
: >command-not-in-path
chmod +x command-not-in-path
complete -p $PWD/command-not-in-path -xa relative-path
complete -C './command-not-in-path '
# CHECK: relative-path
# Non-canonical command path
mkdir -p subdir
: >subdir/command-in-subdir
chmod +x subdir/command-in-subdir
complete -p "$PWD/subdir/command-in-subdir" -xa custom-completions
complete -C './subdir/../subdir/command-in-subdir '
# CHECK: custom-completions
# Relative $PATH
begin
set -lx PATH subdir $PATH
complete -C 'command-in-subdir '
# CHECK: custom-completions
end
rm -r $dir