-
Notifications
You must be signed in to change notification settings - Fork 88
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
[Search files] fix preview for paths containing spaces #137
Conversation
So the whole point of these changes is just to pass expanded and escaped token to __fzf_preview_file.
Again I'm not seeing better improvements, please read my comment in #133 (comment) and decide whether way you want. |
Is that the only problem you see with this PR? Cause I don't mind not supporting that. When would the user by typing in '~/foo` and expecting the ~ to be expanded. Most users would know that tildes don't expand inside a string so why expect fzf.fish to expand it? |
@kidonng yeah I still can't figure out why a user would have their current token be a string containing ~. Autocomplete wouldn't quote it and users should know better than to quote ~. I'm going to merge this unless I hear from you tomorrow. |
Please ignore that bad example. To be clear, I'm OK with these changes, but it doesn't fix the issue. To quote my self:
|
Thanks for explaining it the quotes and the all the interpolation and escaping logic going on in fzf_seatch_current_dir. It makes sense to me now. I agree that this change you're making now is the easiest way to fix the bug in its current state. However, that's not to say we can't do some refactoring to make the code more readable as it is. Which is why I'd still like to merge this. |
Then please include the escapes in this PR or else it won't match the title (and description). |
Done. Thanks. I just realized we were miscommunicating for a long long time because there were actually 2 different bugs and I was talking about one (__fzf_preview_file receiving unescaped token) and you were talking about the other (eval receiving file_path as multiple args). |
As far as I can see there's no issue with it (and whether you change it or not doesn't matter). |
Did you try to repro it using the 4 steps I outlined above in my first post? |
I see, I fixed this in my PR previously (by using |
Oh yes, that was the other thing that made our communication difficult! I thought your original solution was very complicated and that's why I said "the multiple levels of interpolation and evaluation of strings and commands and arguments in this file is mind boggling". Man it's quite hard to communicate on GitHub. Anyway, appreciate your patience and our cooperation on this. |
Ah, wait, I did realize they are two different bugs: #133 (comment). And I kinda got confused by the whole discussion |
Oh you're right, I think I must've had a hard time understanding it, glossed over it, and assumed it was just one bug. |
Well, though laborious, these discussions are fruitful:
All things should be clear know, we should focus on gettings the bugs fixed and feature delivered. |
@@ -4,7 +4,8 @@ function __fzf_preview_file --argument-names file_path --description "Print a pr | |||
bat --style=numbers --color=always "$file_path" | |||
else if test -d "$file_path" # directory | |||
if set --query fzf_preview_dir_cmd | |||
eval $fzf_preview_dir_cmd "$file_path" | |||
# need to escape quotes to make sure eval receives file_path as a single arg | |||
eval $fzf_preview_dir_cmd \"$file_path\" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the fix for bug 2.
@@ -28,6 +29,6 @@ function __fzf_preview_file --argument-names file_path --description "Print a pr | |||
else if test -p "$file_path" | |||
__fzf_report_file_type "$file_path" "named pipe" | |||
else | |||
echo "File doesn't exist or is empty." >&2 | |||
echo "$file_path doesn't exist." >&2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outputting file_path because it helps with debugging.
Removing the "is empty" part because empty files count as regular files and so will result in an empty preview.
7079640
to
0c2c387
Compare
# use the directory name as fzf's prompt to indicate the search is limited to that directory | ||
set --append fzf_arguments --prompt=$token --preview="__fzf_preview_file $token{}" | ||
set file_paths_selected $expanded_token(fd $fd_opts 2>/dev/null | fzf $fzf_arguments) | ||
set --append fzf_arguments --prompt="$unescaped_exp_token" --preview="__fzf_preview_file $expanded_token{}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's bugfix 2: we need to pass the expanded but not yet unescaped token to __fzf_preview_file
in order for the preview to work for paths containing spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of using expanded token as prompt since it looks bloated... But given we will be adding variable expanding soon and it's better explicit than implicit, I will pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I actually had your PR in mind when I changed it.
set fzf_preview_dir_cmd ls | ||
|
||
set actual (__fzf_preview_file "$multi_word_dir") | ||
@test "correctly uses custom command to preview directories" "$actual" = "file 1.txt file 2.txt" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test protects against a regression of bug 2
|
||
set actual (__fzf_search_current_dir) | ||
set expected "'tests/_resources/multi word dir/file 1.txt' 'tests/_resources/multi word dir/file 2.txt'" | ||
@test "uses current token as base directory if it ends in / and is a directory" "$actual" = $expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test doesn't protect against bug 1 (it's impossible to test preview functionality in scripts AFAIK) but should prevent other regressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized we never really fixed bug 1.
EDIT: actually I can't reproduce this anymore, using 3c3ba4f on fish 3.2.2. Now I tend to believe bug 1 is actually fixed in this PR 🤷♀️. I have posted my new summary below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you modify the test to catch this new case? I don't understand why it wasn't caught.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unable to repro this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you modify the test to catch this new case? I don't understand why it wasn't caught.
Not to my knowledge, sorry. May take a look when I get the time.
I'm unable to repro this
I can confirm it's not related to my shell profile. Can you reproduce with the same condition as the screenshot (i.e. mkdir 'with spaces'
, type ./with\ spaces/
and trigger the function)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Crazy I made the PR about fixing this bug but I didn't actually fix it 🤦♂️
Well I was quite confused I didn't notice it either back then.
A good lesson on always testing changes manually if possible 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nvm I see that the test doesn't test the preview function, which I don't know how to do.
Maybe replace the preview function file with a test function, which tests if the command output is expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe replace the preview function file with a test function, which tests if the command output is expected.
I can't get fzf to execute the search function in scripted mode. It'd have to not exit automatically, but if it doesn't exit automatically, how do I make it exit so that the test can continue to run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Start a background shell, sleep for a few seconds and kill the fzf
processes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the idea. I might use it if depending on what happens to this issue junegunn/fzf#2442.
@@ -28,8 +28,15 @@ jobs: | |||
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf | |||
~/.fzf/install | |||
|
|||
- name: Install fd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to add installation of fd because one of the new tests had to make full of it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you can use Homebrew on both macOS and Linux in GitHub Actions, so these can be simplified into brew install fzf fd
Good work 👍 |
# use the directory name as fzf's prompt to indicate the search is limited to that directory | ||
set --append fzf_arguments --prompt=$token --preview="__fzf_preview_file $token{}" | ||
set file_paths_selected $expanded_token(fd $fd_opts 2>/dev/null | fzf $fzf_arguments) | ||
set --append fzf_arguments --prompt="$unescaped_exp_token" --preview="__fzf_preview_file $expanded_token{}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filename should have been quoted here:
set --append fzf_arguments --prompt="$unescaped_exp_token" --preview="__fzf_preview_file $expanded_token{}" | |
set --append fzf_arguments --prompt="$unescaped_exp_token" --preview="__fzf_preview_file '$expanded_token{}'" |
Apparently, I didn't actually fix this bug when I tried to fix it in #137.
This PR fixes two different bugs around the search files feature and paths containing spaces. # Bug 1 This bug happens when the current token is a directory and fzf.fish uses it as the base directory to search for files in. e.g. 1. create dir named "folder with spaces" 2. add a file in that folder with some text 3. type in "folder with spaces/" and with the cursor on that token, execute search files 4. notice the preview function doesn't work on the file in the folder # Bug 2 This bug was found by @kidonng. When using a custom preview directory command (`$fzf_preview_dir_cmd`) is set, this line from `__fzf_preview_file.fish` ``` eval $fzf_preview_dir_cmd "$file_path" ``` results in this code being executed: ``` $fzf_preview_dir_cmd $file_path ``` Notice there are no quotes around `file_path`, which means if `file_path` is more than one word, it gets broken up into multiple args. The solution is to escape the quotes around `file_path` to make sure eval understands it is to be passed as a single arg to `$fzf_preview_dir_cmd`.
Apparently, I didn't actually fix this bug when I tried to fix it in PatrickF1#137.
Post mortem:
|
@kidonng and I separately found two different bugs around paths containing spaces. Boy this search files code is getting complicated!
Bug 1
This bug happens when the current token is a directory and fzf.fish uses it as the base directory to search for files in.
e.g.
Bug 2
This bug was found by @kidonng. When using a custom preview directory command (
$fzf_preview_dir_cmd
) is set, this line from__fzf_preview_file.fish
results in this code being executed:
Notice there are no quotes around
file_path
, which means iffile_path
is more than one word, it gets broken up into multiple args.The solution is to escape the quotes around
file_path
to make sure eval understands it is to be passed as a single arg to$fzf_preview_dir_cmd
.