mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-09 03:51:20 -03:00
Teach cd completions about logical paths
Prior to this fix, cding into a symlink and then completing .. would complete from the physical directory instead of the logical directory, which could not actually be cd'd to. Teach cd completiond to use the logical directory.
This commit is contained in:
@@ -45,7 +45,7 @@ enum {
|
||||
/// EXPAND_FUZZY_MATCH is set.
|
||||
EXPAND_NO_FUZZY_DIRECTORIES = 1 << 10,
|
||||
/// Do expansions specifically to support cd. This means using CDPATH as a list of potential
|
||||
/// working directories.
|
||||
/// working directories, and to use logical instead of physical paths.
|
||||
EXPAND_SPECIAL_FOR_CD = 1 << 11,
|
||||
/// Do expansions specifically for cd autosuggestion. This is to differentiate between cd
|
||||
/// completions and cd autosuggestions.
|
||||
|
||||
@@ -574,6 +574,9 @@ class wildcard_expander_t {
|
||||
wcstring abs_path = this->working_directory;
|
||||
append_path_component(abs_path, filepath);
|
||||
|
||||
// We must normalize the path to allow 'cd ..' to operate on logical paths.
|
||||
if (flags & EXPAND_SPECIAL_FOR_CD) abs_path = normalize_path(abs_path);
|
||||
|
||||
size_t before = this->resolved_completions->size();
|
||||
if (wildcard_test_flags_then_complete(abs_path, filename, wildcard.c_str(), this->flags,
|
||||
this->resolved_completions)) {
|
||||
@@ -591,8 +594,7 @@ class wildcard_expander_t {
|
||||
}
|
||||
|
||||
// Implement EXPAND_SPECIAL_FOR_CD_AUTOSUGGEST by descending the deepest unique
|
||||
// hierarchy we
|
||||
// can, and then appending any components to each new result.
|
||||
// hierarchy we can, and then appending any components to each new result.
|
||||
// Only descend deepest unique for cd autosuggest and not for cd tab completion
|
||||
// (issue #4402).
|
||||
if (flags & EXPAND_SPECIAL_FOR_CD_AUTOSUGGEST) {
|
||||
@@ -613,6 +615,16 @@ class wildcard_expander_t {
|
||||
DIR *open_dir(const wcstring &base_dir) const {
|
||||
wcstring path = this->working_directory;
|
||||
append_path_component(path, base_dir);
|
||||
if (flags & EXPAND_SPECIAL_FOR_CD) {
|
||||
// cd operates on logical paths.
|
||||
// for example, cd ../<tab> should complete "without resolving symlinks".
|
||||
path = normalize_path(path);
|
||||
} else {
|
||||
// Other commands operate on physical paths.
|
||||
if (auto tmp = wrealpath(path)) {
|
||||
path = tmp.acquire();
|
||||
}
|
||||
}
|
||||
return wopendir(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
####################
|
||||
# cd symlink non-resolution
|
||||
|
||||
####################
|
||||
# cd symlink completion
|
||||
|
||||
29
tests/cd.in
29
tests/cd.in
@@ -7,3 +7,32 @@ test "$PWD" = "$link" || echo "\$PWD != \$link:"\n "\$PWD: $PWD"\n "\$link:
|
||||
test (pwd) = "$link" || echo "(pwd) != \$link:"\n "\$PWD: "(pwd)\n "\$link: $link"\n
|
||||
test (pwd -P) = "$real" || echo "(pwd -P) != \$real:"\n "\$PWD: $PWD"\n "\$real: $real"\n
|
||||
test (pwd -P -L) = "$link" || echo "(pwd -P -L) != \$link:"\n "\$PWD: $PWD"\n "\$link: $link"\n
|
||||
|
||||
logmsg cd symlink completion
|
||||
|
||||
# Create a symlink and verify logical completion.
|
||||
# create directory $base/through/the/looking/glass
|
||||
# symlink $base/somewhere/teleport -> $base/through/the/looking/glass
|
||||
# verify that .. completions work
|
||||
set -l base /tmp/cdcomp_test/
|
||||
rm -Rf $base
|
||||
mkdir -p $base
|
||||
cd $base
|
||||
mkdir -p $base/through/the/looking/glass
|
||||
|
||||
mkdir -p $base/somewhere
|
||||
mkdir $base/somewhere/a1
|
||||
mkdir $base/somewhere/a2
|
||||
mkdir $base/somewhere/a3
|
||||
touch $base/through/the/looking/b(seq 1 3)
|
||||
mkdir $base/through/the/looking/d1
|
||||
mkdir $base/through/the/looking/d2
|
||||
mkdir $base/through/the/looking/d3
|
||||
ln -s $base/through/the/looking/glass $base/somewhere/rabbithole
|
||||
|
||||
cd $base/somewhere/rabbithole
|
||||
echo "ls:"
|
||||
complete -C'ls ../'
|
||||
echo "cd:"
|
||||
complete -C'cd ../'
|
||||
rm -Rf $base
|
||||
|
||||
16
tests/cd.out
16
tests/cd.out
@@ -1,3 +1,19 @@
|
||||
|
||||
####################
|
||||
# cd symlink non-resolution
|
||||
|
||||
####################
|
||||
# cd symlink completion
|
||||
ls:
|
||||
../b1
|
||||
../b2
|
||||
../b3
|
||||
../d1/
|
||||
../d2/
|
||||
../d3/
|
||||
../glass/
|
||||
cd:
|
||||
../a1/
|
||||
../a2/
|
||||
../a3/
|
||||
../rabbithole/
|
||||
|
||||
Reference in New Issue
Block a user