5

I'd like to use FZF to search for files and then have them open in an editor of my choice e.g. Sublime, Atom. I'm not sure how to configure my shell for this, I've tried the below but I can't get it to work.

Can you help?

Thanks!

fe() {
local files
  IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
  [[ -n "$files" ]] && ${EDITOR:-atom} "${files[@]}"
}
Alistair Colling
  • 1,363
  • 2
  • 19
  • 29

4 Answers4

4

I wrote a function that I keep in my .bashrc which you can use to select any files through fzf and have them passed to whatever program you want (so not only sublime, but any GUI program you add to the function's list) and it also works with command line tools like cd, cat, tail, head and so on. Also you can cycle back through your history and find the command as it was expanded after fzf did its thing. If you configure fzf to look in many common places on the file system by default (or see here) this function really shines. I use it many times every day, mainly to change directory (f cd) or open files.

In your case you would just type in the terminal:

f sublime

and fzf would launch, after you select your file(s) sublime would open them.

I put the function below, and I got inspiration for it here

#!/bin/bash

# Run command/application and choose paths/files with fzf.
# Always return control of the terminal to user (e.g. when opening GUIs).
# The full command that was used will appear in your history just like any
# other (N.B. to achieve this I write the shell's active history to
# ~/.bash_history)
#
# Usage:
# f cd [OPTION]... (hit enter, choose path)
# f cat [OPTION]... (hit enter, choose files)
# f vim [OPTION]... (hit enter, choose files)
# f vlc [OPTION]... (hit enter, choose files)

f() {
    # if no arguments passed, just lauch fzf
    if [ $# -eq 0 ]
    then
        fzf | sort
        return 0
    fi

    # store the program
    program="$1"

    # remove first argument off the list
    shift

    # store any option flags
    options="$@"

    # store the arguments from fzf
    arguments=$(fzf --multi)

    # if no arguments passed (e.g. if Esc pressed), return to terminal
    if [ -z "${arguments}" ]; then
        return 1
    fi

    # sanitise the command:
    # put an extra single quote next to any pre-existing single quotes
    # put single quotes around each argument
    # put them all on one line.
    for arg in "${arguments[@]}"; do
        arguments=$(echo "$arg" | sed "s/'/''/g;
                                       s/.*/'&'/g;
                                       s/\n//g"
                   )
    done

    # if the program is on the GUI list, add a '&'
    if [[ "$program" =~ ^(nautilus|zathura|evince|vlc|eog|kolourpaint)$ ]]; then
        arguments="$arguments &"
    fi

    # write the shell's active history to ~/.bash_history.
    history -w

    # add the command with the sanitised arguments to .bash_history
    echo $program $options $arguments >> ~/.bash_history

    # reload the ~/.bash_history into the shell's active history
    history -r

    # execute the last command in history
    fc -s -1
}
mattb
  • 2,787
  • 2
  • 6
  • 20
3

Based on your comments, it is possible the only problem comes from this part :

${EDITOR:-atom}

This expands to the content of variable EDITOR if has a non-null value, and to atom if it is null or unset. It is likely you have that variable initialized to something else than atom. Try using simply atom instead, like this:

fe() {
local files
  IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
  [[ -n "$files" ]] && atom "${files[@]}"
}

Of course, you can also keep the function as it already is, but make sure your environment contains something like EDITOR=atom.

Fred
  • 6,590
  • 9
  • 20
3

For those seeking for a general way to open results in MacOS:

Define this alias to open file by os default app (based on selected file type):

alias f='open "$(fzf)"'

Then type f command, find your file and hit ENTER.

Sabrina
  • 2,531
  • 1
  • 32
  • 30
0

oneliner (basically) I just copied from my .zshrc:

f() {
    $1 $(fd -H . | fzf-tmux -u 30% --query="$2" -m --height=~30% --layout=reverse --border=rounded --margin=0,1 --info=right --separator== --scrollbar=↓ --select-1 --exit-0)
}

Its kinda blunt, but it does the job exactly how I need it to. The code should be pretty self-explanatory. With this code you can do stuff like:

$ f nvim "'init.lua"

which would bring you directly to your nvim config. There are of course many other use cases, but I like this one ;) (though it has a tun of issues: doesn't work w/ aliases, etc.)