0

How do I get the FZF Preview Window to Display Functions from my Current Bash Environment?

I want to list my custom bash functions using FZF, and view the code of a selected function in the FZF Preview Window.

However, it does not appear that the bash enviroment used by FZF to execute my command can see the functions in my terminal bash environment. For example:

$ declare -F | fzf --preview="type {3}"

/bin/bash: line 1: type: g: not found

enter image description here

However, the following works:

$ declare -F

declare -f fcd
declare -f fz
declare -f g

$ type g
g is a function
g ()
{
    search="";
    for term in $@;
    do
        search="$search%20$term";
    done;
    nohup google-chrome --app-url "http://www.google.com/search?q=$search" > /dev/null 2>&1 &
}

declare -F | fzf --preview="echo {3}"

g # my function g()

One reason I suspect that the FZF Preview Window environment may not be able to see my terminal environment is because they have different process ID's.

$ echo $BASHPID

1129439

$ declare -F | fzf --preview="echo $BASHPID"

1208203

How do I get the FZF Preview Window to Display Functions from my Current Bash Environment?

4
  • 1
    The pipe | will make it run in a subshell. Have you tried fzf --preview="type {3}" < <(declare -F) instead?
    – frabjous
    Oct 21, 2022 at 15:27
  • That'll make the BASHPID match, but I think fzf is still running a separate process for the preview which won't have access to your bash functions.
    – frabjous
    Oct 21, 2022 at 15:33
  • Thanks for the reminder that pipe | will run in a subshell. fzf --preview="type {3}" < <(declare -F) returns /bin/bash: line 1: type: g: not found Oct 21, 2022 at 16:44
  • Per github.com/junegunn/fzf, Preview window: When the --preview option is set, fzf automatically starts an external process with the current line as the argument and shows the result in the split window. Your $SHELL is used to execute the command with $SHELL -c COMMAND. Oct 21, 2022 at 17:46

2 Answers 2

0

You need to export your functions so they can be inherited by subshells. Here's an example:

#!/usr/bin/env bash
header_info='CTRL+D or ESCAPE to exit, ENTER attaches to a Detached screen'
export FZF_DEFAULT_COMMAND="list_screens"
export FZF_DEFAULT_OPTS="--info=inline --header '${header_info}' --preview 'screen_peek {1}' --preview-window top,80%,follow "
function screen_peek() {
  local screen=$1
  local pipe="/tmp/${RANDOM}-$(date +%s).peek"
  mkfifo "${pipe}"
  screen -S "${screen}" -X hardcopy "${pipe}"
  cat "${pipe}" | sed -e '/./,$!d' -e :a -e '/^\n*$/{$d;N;};/\n$/ba'
  rm -f "${pipe}"
}

function list_screens() {
  screen -ls | column -t | grep tached
}
export -f screen_peek
export -f list_screens
screen_id=$(list_screens | fzf | awk '{print $1}')
[[ "${screen_id}" ]] && screen -x "${screen_id}"
0

This is indeed possible and good way of reciewing text files/blocks.

You need to make your functions known to the shell used by fzf. You do that by sourcing the file that contains your functions with a bash command inside the preview windows. Here is an example:

$ compgen -c | fzf --preview='bash -c "source ~/bin/all-my-functions.sh;type {}"'

replace ~/bin/all-my-functions.sh by the full path of the executable file that contains your functions.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .