Skip to content

Instantly share code, notes, and snippets.

@gitaarik
Last active October 16, 2022 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gitaarik/bc7c6724a1868f8d89f5a97f794f14f2 to your computer and use it in GitHub Desktop.
Save gitaarik/bc7c6724a1868f8d89f5a97f794f14f2 to your computer and use it in GitHub Desktop.
fzf_preview_include - include normally ignored paths in fzf-preview
#!/usr/bin/zsh
#
# fzf_preview_include - include normally ignored paths in fzf-preview
#
# Dependencies: zsh and ripgrep
#
# This command enables you to include extra dirs and files in fzf-preview, that
# would normally be ignored by git or ripgrep. This can be handy for when you
# use another git repository inside a parent one, or if you regularly edit
# files that are ignored by git / ripgrep.
#
# It works by adding a `.fzf_preview_include` file inside your project root.
# In the file you list the paths you want to include, separated by newlines.
# These paths will be additionally searched along the project root, using the
# `fzf_preview_include` command in this file.
#
# When the `fzf_preview_include` command is executed in a subdirectory of a
# project where you have a `.fzf_preview_include`, it will find that file and
# include only the paths that also appear in that subdirectory.
#
# To use:
# - Put this file somewhere on your `$PATH`.
# - Make it executable with `chmod +x fzf_preview_include`.
# - Configure it in your nvim config like this:
#
# " Commands used to get the file list from project
# let g:fzf_preview_filelist_command = 'fzf_preview_include'
#
# " Commands used to get the file list from git repository
# let g:fzf_preview_git_files_command = 'fzf_preview_include'
#
# " Commands used to get the file list from current directory
# let g:fzf_preview_directory_files_command = 'fzf_preview_include'
#
# Relevant docs of these fzf-preview commands:
# https://github.com/yuki-yano/fzf-preview.vim#customization
project_files() {
# Find files within a project dir
# This will be used for the project root and every directory in the
# `.fzf_preview_include` file.
rg --files --hidden --follow --no-messages -g \!"* *"
}
all_project_files() {
# Find all files within project, including paths in `.fzf_preview_include`.
# First print files of current directory
project_files
# Find the first `.fzf_preview_include` file we can find, checking
# current working dir and all parent dirs.
configfile_path=$(findconfig .fzf_preview_include)
if [[ -z "$configfile_path" ]] ; then
# If there's no `.fzf_preview_include` config file found, then we
# don't have to do additional work.
exit
fi
# Loop through the paths listed inside the config file
for dir_name in $(cat "$configfile_path") ; do
# Absolute search path
search_path_abs="$(dirname $configfile_path)/$dir_name"
# Seach path relative from current dir
search_path_rel=$(echo "${search_path_abs#$PWD}" | cut -c 2-)
if [[ -f "$search_path_abs" ]] ; then
# If search path is a file, then we can print it right away and
# continue to the next item.
echo "$search_path_rel"
continue
fi
if [[ ! -d "$search_path_abs" ]] ; then
# Ignore if the search path is not an existing dir
continue;
fi
if [[ $search_path_abs != $PWD/* ]]; then
# Check if $search_path_abs is within $PWD
# https://unix.stackexchange.com/a/6454/39618
# If the search path is not a subdir of current working dir, then we
# don't want to show these files.
continue;
fi
# Get paths from project files at search path
# The extra parentheses around the expression are necessary to make the
# string an interable array.
files=($(cd "$search_path_abs" && project_files))
# The paths of $files are relative to the search path, so we'll prepend
# the search path itself, to show the files with a path relative from
# the current working directory.
for file in $files ; do
echo "$search_path_rel$file"
done
done
}
findconfig() {
# Print path of first found config file, checking current working dir and
# traversing up all parent dirs.
# Source: https://unix.stackexchange.com/a/293477/39618
if [ -f "$1" ]; then
# If we found a config file, print it
printf '%s\n' "${PWD%/}/$1"
elif [ "$PWD" = / ]; then
# If we're at root and no config file has been found, stop
false
else
# Go up a dir and try again.
# Use a subshell (the parentheses) so that we don't affect the caller's
# $PWD.
(cd .. && findconfig "$1")
fi
}
# Remove any duplicates
all_project_files | sort | uniq
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment