Fzf: __fzf_cd__: initial backslash before ~ means alt-c chdir fails

Created on 16 Oct 2017  Â·  4Comments  Â·  Source: junegunn/fzf

  • Category

    • [ ] fzf binary

    • [ ] fzf-tmux script

    • [ ] Key bindings

    • [x] Completion

    • [ ] Vim

    • [ ] Neovim

    • [ ] Etc.

  • OS

    • [ ] Linux

    • [x] Mac OS X

    • [ ] Windows

    • [ ] Windows Subsystem for Linux

    • [ ] Etc.

  • Shell

    • [x] bash

    • [ ] zsh

    • [ ] fish

On ALT-C chdir completion:

selecting the desired directory:
in ~ directory
folder structure
~/wibble wobble/foo

ALT-C wibb wob foo -> Enter

__fzf_cd__
$ cd \~/wibble\ wobble/foo
-bash: cd: ~/wibble wobble/foo: Not a directory

the issue seems to be the initial escaping of the ~ character

Most helpful comment

The contract of FZF_ALT_C_COMMAND has been that it has to generate a list of unescaped paths (e.g. whitespaces, $, ~, !, etc.). Because most (as far as I know "all") directory traversal programs do not "shell-escape" paths.

$ mkdir /tmp/test
$ cd /tmp/test/
$ mkdir 'foo bar'
$ touch 'foo bar/$baz'

$ find .
.
./foo bar
./foo bar/$baz

$ rg --files
foo bar/$baz

$ ag -g ''
foo bar/$baz

$ git init
Initialized empty Git repository in /private/tmp/test/.git/
$ git add .
$ git ls-files
foo bar/$baz

And we have to escape the raw string before passing it to cd.

$ file foo bar/$baz
foo:  cannot open `foo' (No such file or directory)
bar/: cannot open `bar/' (No such file or directory)

$ file foo\ bar/\$baz
foo bar/$baz: empty

It's clear that the example in that blog post is not compatible with the current implementation of ALT-C. So you have three options:

  1. Do not use the example. Use commands that print relative paths to the current working directory. ALT-C was specifically designed for that purpose. To cd into a directory not under the current directory, use fuzzy cd completion.
cd **<tab>
cd ~/**<tab>
cd /tmp/**<tab>
  1. Replace ~ with the absolute path of your home directory as suggested above. I believe you can even hide the common prefix with the combination of --delimiter / and --with-nth 4..

  2. Write your own ALT-C implementation, and override the default version with it. It's actually trivial if you know how to write shell scripts. https://github.com/junegunn/fzf/blob/eaf6eb897879becff31ea9b27046c0eff9e1e646/shell/key-bindings.bash#L47-L52

All 4 comments

Do you use a custom FZF_ALT_C_COMMAND? The default command shouldn't print ~.

> cd ~
> mkdir -p "foo bar"/baz
> [ALT-C]
> cd foo\ bar/baz
/Users/jg/foo bar/baz

I have the same problem on linux with bash when I use export FZF_ALT_C_COMMAND="cd ~/; bfs -type d -nohidden | sed s/^\./~/" , as described in FZF and RipGrep – Navigate with bash faster than ever before. It's like ~ is not expanded to $HOME anymore, and escaped. With zsh, no error is reported but the directory is not changed.

same, can confirm that this change fixes it:

declare -x FZF_ALT_C_COMMAND="cd ~/; bfs -type d -nohidden | sed 's/^\\./\\/Users\\/me\\//'"

thanks

The contract of FZF_ALT_C_COMMAND has been that it has to generate a list of unescaped paths (e.g. whitespaces, $, ~, !, etc.). Because most (as far as I know "all") directory traversal programs do not "shell-escape" paths.

$ mkdir /tmp/test
$ cd /tmp/test/
$ mkdir 'foo bar'
$ touch 'foo bar/$baz'

$ find .
.
./foo bar
./foo bar/$baz

$ rg --files
foo bar/$baz

$ ag -g ''
foo bar/$baz

$ git init
Initialized empty Git repository in /private/tmp/test/.git/
$ git add .
$ git ls-files
foo bar/$baz

And we have to escape the raw string before passing it to cd.

$ file foo bar/$baz
foo:  cannot open `foo' (No such file or directory)
bar/: cannot open `bar/' (No such file or directory)

$ file foo\ bar/\$baz
foo bar/$baz: empty

It's clear that the example in that blog post is not compatible with the current implementation of ALT-C. So you have three options:

  1. Do not use the example. Use commands that print relative paths to the current working directory. ALT-C was specifically designed for that purpose. To cd into a directory not under the current directory, use fuzzy cd completion.
cd **<tab>
cd ~/**<tab>
cd /tmp/**<tab>
  1. Replace ~ with the absolute path of your home directory as suggested above. I believe you can even hide the common prefix with the combination of --delimiter / and --with-nth 4..

  2. Write your own ALT-C implementation, and override the default version with it. It's actually trivial if you know how to write shell scripts. https://github.com/junegunn/fzf/blob/eaf6eb897879becff31ea9b27046c0eff9e1e646/shell/key-bindings.bash#L47-L52

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nordlow picture nordlow  Â·  3Comments

chrisamow picture chrisamow  Â·  3Comments

aleclarson picture aleclarson  Â·  3Comments

firedev picture firedev  Â·  3Comments

erusev picture erusev  Â·  3Comments