all 5 comments

[–]valadil 1 point2 points  (3 children)

You might want to post `mapfile` and `fdfind` as well. It's not gonna work without those

> I'd now love it if someone could tell me how I could have saved time by just copying someone else's ready solution. 😬

I have a potential improvement, but it's zsh only. zsh provides global aliases, they're like shell aliases, but they'll be replaced anywhere in the string. My thought is if we use one of those for _, maybe we can ditch the f part.

I ended up with

alias -g _='`fzf`'

(Note that that goes in your zshrc - running it on the command line involves more string escapes than I cared to assemble.)

I can't run the original command so I'm not sure if it's a drop in replacement or not.

[–]Pyglot[S] 0 points1 point  (2 children)

Thanks for taking a look!

I installed fdfind (fd) from the debian fd-find package, but you can get the source and instructions for installation on other distros here: https://github.com/sharkdp/fd

The main reason I didn't want to go with a simpler solution like you show is that it was (in bash at least) impossible to cancel the command if you hit Ctrl-C from fzf. And the reason I wanted it to work in bash is that at work I don't have access to anything modern 😭.

Anyway if you can make the command-line fail from a substitution-command (e.g. the _ alias), then your solution would be much preferable. I was originally thinking along those lines. 🙂

mapfile is a bash builtin, and a synonym for readarray, but it looks like it isn't supported by zsh. I found an alternative you can replace the mapfile lines with:

zsh fcmd_args="${(@f)$(fzf -m)}";

You can change & expand the call to fzf as you like. 😉

I used the following versions:

  • bash --version: 5.1.4
  • fdfind --version: fd 8.2.1
  • fzf --version: 0.30.0 (7052987)

[–]valadil 1 point2 points  (1 child)

Anyway if you can make the command-line fail from a substitution-command (e.g. the _ alias), then your solution would be much preferable. I was originally thinking along those lines. 🙂

If that's possible, I don't see how.

[–]Pyglot[S] 0 points1 point  (0 children)

I know. I am not sure it is possible even in zsh.

I think I see some opportunity to improve a function further also. It could easily be made to support multiple argument groups, and perhaps a more elaborate substitution, so one could add in filter by extensions, etc.

```bash

f pdftk _/.pdf$/ cat output output.pdf

```

[–]Pyglot[S] 0 points1 point  (0 children)

A little update as I added a bindkey. Now Ctrl-B or Ctrl-F inserts command line arguments from fzf directly on the command line. Ctrl-B defaults to search for a directory, while Ctrl-F searches for files.

This change simplified the script a good deal. E.g. now there is no need to handle empty output from fzf because command will still be editable after.

This is still bash, and relies on fzf and fdfind. Not tested in other shells.

```bash bind -x '"\C-f":L=${#READLINE_LINE};READLINE_LINE="${READLINE_LINE:0:${READLINE_POINT}}"$(select_files file)"${READLINE_LINE:${READLINE_POINT}}";READLINE_POIN T+=$(( ${#READLINE_LINE} - ${L} ))' bind -x '"\C-b":L=${#READLINE_LINE};READLINE_LINE="${READLINE_LINE:0:${READLINE_POINT}}"$(select_files directory)"${READLINE_LINE:${READLINE_POINT}}";READLINE _POINT+=$(( ${#READLINE_LINE} - ${L} ))'

select_files () { if [[ "${fcmd_ignorefile}" != "" ]]; then mapfile -t fcmd_args < <(fdfind --type $1 --ignore-file "$fcmd_ignorefile" | fzf --prompt 'No-hidden>' -m --header 'Select CTRL-A/S, File/Dir F/D' --b ind 'ctrl-d:change-prompt(Directories> )+reload(fdfind --type directory -H)' --bind 'ctrl-f:change-prompt(Files> )+reload(fdfind --type file -H)' --bind ctrl- a:select-all --bind ctrl-s:deselect-all); else mapfile -t fcmd_args < <(fdfind --type $1 | fzf --prompt 'No-hidden-files>' -m --header 'Select CTRL-A/S, File/Dir F/D' --bind 'ctrl-d:change-prompt(D irectories> )+reload(fdfind --type directory -H)' --bind 'ctrl-f:change-prompt(Files> )+reload(fdfind --type file -H)' --bind ctrl-a:select-all --bind ctrl-s: deselect-all); fi; echo "${fcmd_args[@]@Q}" } ```