Super supe up my fish with fzf. Batteries are now included.

This commit is contained in:
Shawn Anderson 2020-09-28 18:46:10 -07:00
parent 4778b198d2
commit 78e80ba3d4
23 changed files with 424 additions and 74 deletions

View File

@ -0,0 +1,106 @@
# From https://github.com/patrickf3139/fzf.fish/blob/main/conf.d/fzf.fish
# Set up the default, mnemonic key bindings unless the user has chosen to customize them
if not set --query fzf_fish_custom_keybindings
# \cf is Ctrl+f
bind \cj '__fzf_search_current_dir'
#bind \cr '__fzf_search_history'
bind \cv '__fzf_search_shell_variables'
# The following two key binding use Alt as an additional modifier key to avoid conflicts
bind \e\cl '__fzf_search_git_log'
bind \e\cs '__fzf_search_git_status'
# set up the same key bindings for insert mode if using fish_vi_key_bindings
if [ "$fish_key_bindings" = 'fish_vi_key_bindings' ]
bind --mode insert \cf '__fzf_search_current_dir'
bind --mode insert \cr '__fzf_search_history'
bind --mode insert \cv '__fzf_search_shell_variables'
bind --mode insert \e\cl '__fzf_search_git_log'
bind --mode insert \e\cs '__fzf_search_git_status'
end
end
# If FZF_DEFAULT_OPTS is not set, then set some sane defaults. This also affects fzf outside of this plugin.
# See https://github.com/junegunn/fzf#environment-variables
if not set --query FZF_DEFAULT_OPTS
# cycle makes scrolling easier
# reverse layout is more familiar as it mimicks the layout of git log, history, and env
# border makes clear where the fzf window ends
# height 75% allows you to view what you were doing and stay in context of your work
# preview-window wrap wraps long lines in the preview window
set --export FZF_DEFAULT_OPTS '--cycle --layout=reverse --border --height 75% --preview-window=wrap'
end
# Forgit configuration
set FORGIT_FZF_DEFAULT_OPTS "
$FZF_DEFAULT_OPTS
--ansi
--height='80%'
--bind='alt-k:preview-up,alt-p:preview-up'
--bind='alt-j:preview-down,alt-n:preview-down'
--bind='ctrl-r:toggle-all'
--bind='ctrl-s:toggle-sort'
--bind='?:toggle-preview'
--bind='alt-w:toggle-preview-wrap'
--preview-window='right:60%'
+1
$FORGIT_FZF_DEFAULT_OPTS
"
# register aliases
if test -z "$FORGIT_NO_ALIASES"
if test -n "$forgit_add"
alias $forgit_add 'forgit::add'
else
alias ga 'forgit::add'
end
if test -n "$forgit_reset_head"
alias $forgit_reset_head 'forgit::reset::head'
else
alias grh 'forgit::reset::head'
end
if test -n "$forgit_log"
alias $forgit_log 'forgit::log'
else
alias glo 'forgit::log'
end
if test -n "$forgit_diff"
alias $forgit_diff 'forgit::diff'
else
alias gd 'forgit::diff'
end
if test -n "$forgit_ignore"
alias $forgit_ignore 'forgit::ignore'
else
alias gi 'forgit::ignore'
end
if test -n "$forgit_restore"
alias $forgit_restore 'forgit::checkout_file'
else
alias gcf 'forgit::checkout_file'
end
if test -n "$forgit_clean"
alias $forgit_clean 'forgit::clean'
else
alias gclean 'forgit::clean'
end
if test -n "$forgit_stash_show"
alias $forgit_stash_show 'forgit::stash::show'
else
alias gss 'forgit::stash::show'
end
if test -n "$forgit_cherry_pick"
alias $forgit_cherry_pick 'forgit::cherry::pick'
else
alias gcp 'forgit::cherry::pick'
end
end

View File

@ -51,4 +51,4 @@ bind \ea beginning-of-line
#-------------------------------------------------------------------------------
# Forgit plugin requires sourcing to activate abbreviations
# From https://github.com/wfxr/forgit
source ./functions/forgit.plugin.fish
source ~/.config/fish/functions/forgit.plugin.fish

View File

@ -0,0 +1,10 @@
# helper function for __fzf_search_shell_variables
function __fzf_display_value_or_error --argument-names variable_name --description "Displays either the value of the variable passed in, or an informative message if it is not available."
if set --query $variable_name
echo $$variable_name
else
set_color red
echo "$variable_name was not exported to this process so its value cannot be displayed." >&2
set_color normal
end
end

View File

@ -0,0 +1,28 @@
# helper function for __fzf_search_current_dir
function __fzf_preview_file --argument-names file_path --description "Prints a preview for the given file based on its file type."
if test -f "$file_path" # regular file
bat --style=numbers --color=always "$file_path"
else if test -d "$file_path" # directory
set --local CLICOLOR_FORCE true
ls -a "$file_path"
else if test -L "$file_path" # symlink
# notify user and recurse on the target of the symlink, which can be any of these file types
set -l target_path (realpath $file_path)
set_color yellow
echo "'$file_path' is a symlink to '$target_path'."
set_color normal
__fzf_preview_file "$target_path"
else if test -c "$file_path"
__fzf_report_file_type "$file_path" "character device file"
else if test -b "$file_path"
__fzf_report_file_type "$file_path" "block device file"
else if test -S "$file_path"
__fzf_report_file_type "$file_path" "socket"
else if test -p "$file_path"
__fzf_report_file_type "$file_path" "named pipe"
else
echo "Unexpected file symbol $file_type_char. Please open an issue at https://github.com/patrickf3139/fzf.fish." >&2
end
end

View File

@ -0,0 +1,6 @@
# helper function for __fzf_preview_file
function __fzf_report_file_type --argument-names file_path file_type --description "Explain the file type for a file."
set_color red
echo "Cannot preview '$file_path': it is a $file_type."
set_color normal
end

View File

@ -0,0 +1,16 @@
# originally implemented and transposed from https://github.com/patrickf3139/dotfiles/pull/11
function __fzf_search_current_dir --description "Search the current directory using fzf and fd. Insert the selected relative file path into the commandline at the cursor."
# Make sure that fzf uses fish to execute __fzf_preview_file.
# See similar comment in __fzf_search_shell_variables.fish.
set --local --export SHELL (command --search fish)
set file_path_selected (
fd --hidden --follow --color=always --exclude=.git 2> /dev/null |
fzf --ansi --preview='__fzf_preview_file {}'
)
if test $status -eq 0
commandline --insert (echo $file_path_selected | string escape)
end
commandline --function repaint
end

View File

@ -0,0 +1,20 @@
# Originally implemented in and transposed from https://github.com/patrickf3139/dotfiles/pull/2
function __fzf_search_git_log --description "Search the git log of the current git repository. Insert the selected commit hash into the commandline at the cursor."
if not git rev-parse --git-dir >/dev/null 2>&1
echo '__fzf_search_git_log: Not in a git repository.' >&2
else
set selected_log_line (
# see documentation for git format placeholders at https://git-scm.com/docs/git-log#Documentation/git-log.txt-emnem
# %h gives you the abbreviated commit hash, which is useful for saving screen space, but we will have to expand it later below
git log --color=always --format=format:'%C(bold blue)%h%C(reset) - %C(cyan)%as%C(reset) %C(yellow)%d%C(reset) %C(normal)%s%C(reset) %C(dim normal)[%an]%C(reset)' | \
fzf --ansi --tiebreak=index --preview='git show --color=always (string split --max 1 " " {})[1]'
)
if test $status -eq 0
set abbreviated_commit_hash (string split --max 1 " " $selected_log_line)[1]
set commit_hash (git rev-parse $abbreviated_commit_hash)
commandline --insert $commit_hash
end
end
commandline --function repaint
end

View File

@ -0,0 +1,29 @@
function __fzf_search_git_status --description "Search the git status of the current git repository. Insert the selected file paths into the commandline at the cursor."
if not git rev-parse --git-dir >/dev/null 2>&1
echo '__fzf_search_git_status: Not in a git repository.' >&2
else
set selected_paths (
# Pass configuration color.status=always to force status to use colors even though output is sent to a pipe
git -c color.status=always status --short |
fzf --ansi --multi
)
if test $status -eq 0
# git status --short automatically escapes the paths of most files for us so not going to bother trying to handle
# the few edges cases of weird file names that should be extremely rare (e.g. "this;needs;escaping")
for path in $selected_paths
if test (string sub --length 1 $path) = 'R'
# path has been renamed and looks like "R LICENSE -> LICENSE.md"
# extract the path to use from after the arrow
set cleaned_path (string split -- "-> " $path)[-1]
else
set cleaned_path (string sub --start=4 $path)
end
# add a space after each path to keep them separated when inserted
set cleaned_path_padded "$cleaned_path "
commandline --insert $cleaned_path_padded
end
end
commandline --function repaint
end
end

View File

@ -0,0 +1,17 @@
# originally implemented and transposed from https://github.com/patrickf3139/dotfiles/pull/11
function __fzf_search_history --description "Search command history using fzf. Replace the commandline with the selected command."
# history merge incorporates history changes from other fish sessions
history merge
set command_with_ts (
# Reference https://devhints.io/strftime to understand strftime format symbols
history --null --show-time="%m/%e %H:%M:%S | " |
fzf --read0 --tiebreak=index --query=(commandline)
)
if test $status -eq 0
set command_selected (string split --max 1 " | " $command_with_ts)[2]
commandline --replace $command_selected
end
commandline --function repaint
end

View File

@ -0,0 +1,21 @@
function __fzf_search_shell_variables --description "Search and inspect shell variables using fzf. Insert the selected variable into the commandline at the cursor."
# Make sure that fzf uses fish to execute __echo_value_or_print_message, which
# is an autoloaded fish function so doesn't exist in other shells.
# Using --local so that it does not clobber SHELL outside of this function.
set --local --export SHELL (command --search fish)
# Pipe the names of all shell variables to fzf and attempt to display the value
# of the selected variable in fzf's preview window.
# Non-exported variables will not be accessible to the fzf process, in which case
# __echo_value_or_print_message will print an informative message in lieu of the value.
set variable_name (
set --names |
fzf --preview '__fzf_display_value_or_error {}'
)
if test $status -eq 0
commandline --insert $variable_name
end
commandline --function repaint
end

View File

@ -0,0 +1,9 @@
# Defined in /tmp/fish.azx9vq/__github_add_org.fish @ line 1
function __github_add_org --description 'Add an organization name to the local share fzf file.' --argument org
if ! test -n "$org"
echo "Please provide and org name!"
return 1
else
echo $org >> ~/.local/share/fzf/github_orgs
end
end

View File

@ -0,0 +1,9 @@
# Defined in /tmp/fish.mAOD6Y/__github_get_org_repos.fish @ line 2
function __github_get_org_repos --description 'Return a list of all the github repos owned by a github organization.' --argument org
if ! test -n "$org"
echo "Please provide a github organization name."
return 1
else
curl "https://api.github.com/orgs/$org/repos?per_page=100&page=1" | jq '.[].full_name' | awk -F'"' '{print $2}'
end
end

View File

@ -0,0 +1,19 @@
function -d "Fuzzy change directory" fcd
if set -q argv[1]
set searchdir $argv[1]
else
set searchdir $HOME
end
# https://github.com/fish-shell/fish-shell/issues/1362
set -l tmpfile (mktemp)
find $searchdir \( ! -regex '.*/\..*' \) ! -name __pycache__ -type d | fzf > $tmpfile
set -l destdir (cat $tmpfile)
rm -f $tmpfile
if test -z "$destdir"
return 1
end
cd $destdir
end

View File

@ -0,0 +1,17 @@
# Defined in /tmp/fish.yoQzI0/fclone.fish @ line 2
function fclone --argument org
if ! test -n "$org"
set org_file ~/.local/share/fzf/github_orgs
if ! test -e $org_file
echo -n "Please provide an organization name either as an argument to this command or in a list at $org_file"
return 1
else
set org (cat $org_file | fzf-tmux -e --header="Please select an organization. Set additional orgs in $org_file")
end
end
set repo (__github_get_org_repos $org | fzf-tmux --header="Please select a repository to clone.")
if test -n "$repo"
echo "Cloning '$repo' from Github"
git clone "https://github.com/$repo.git"
end
end

View File

@ -0,0 +1,17 @@
# Defined in /tmp/fish.T4Z5Kp/fclone.fish @ line 2
function fhub --argument org
if ! test -n "$org"
set org_file ~/.local/share/fzf/github_orgs
if ! test -e $org_file
echo -n "Please provide an organization name either as an argument to this command or in a list at $org_file"
return 1
else
set org (cat $org_file | fzf-tmux -e --header="Please select an organization. Set additional orgs in $org_file")
end
end
set repo (__github_get_org_repos $org | fzf-tmux --header="Please select a repository to clone.")
if test -n "$repo"
echo "Opening '$repo' in Web Browser"
hub browse $repo
end
end

View File

@ -0,0 +1,7 @@
function fkill -d "Fuzzy kill"
set pid (ps -ef | sed 1d | fzf -m | awk '{print $2}')
if test -n "$pid"
echo $pid | xargs kill -9
end
end

View File

@ -297,76 +297,3 @@ function forgit::ignore::clean
setopt localoptions rmstarsilent
[[ -d "$FORGIT_GI_REPO_LOCAL" ]] && rm -rf "$FORGIT_GI_REPO_LOCAL"
end
set FORGIT_FZF_DEFAULT_OPTS "
$FZF_DEFAULT_OPTS
--ansi
--height='80%'
--bind='alt-k:preview-up,alt-p:preview-up'
--bind='alt-j:preview-down,alt-n:preview-down'
--bind='ctrl-r:toggle-all'
--bind='ctrl-s:toggle-sort'
--bind='?:toggle-preview'
--bind='alt-w:toggle-preview-wrap'
--preview-window='right:60%'
+1
$FORGIT_FZF_DEFAULT_OPTS
"
# register aliases
if test -z "$FORGIT_NO_ALIASES"
if test -n "$forgit_add"
alias $forgit_add 'forgit::add'
else
alias ga 'forgit::add'
end
if test -n "$forgit_reset_head"
alias $forgit_reset_head 'forgit::reset::head'
else
alias grh 'forgit::reset::head'
end
if test -n "$forgit_log"
alias $forgit_log 'forgit::log'
else
alias glo 'forgit::log'
end
if test -n "$forgit_diff"
alias $forgit_diff 'forgit::diff'
else
alias gd 'forgit::diff'
end
if test -n "$forgit_ignore"
alias $forgit_ignore 'forgit::ignore'
else
alias gi 'forgit::ignore'
end
if test -n "$forgit_restore"
alias $forgit_restore 'forgit::checkout_file'
else
alias gcf 'forgit::checkout_file'
end
if test -n "$forgit_clean"
alias $forgit_clean 'forgit::clean'
else
alias gclean 'forgit::clean'
end
if test -n "$forgit_stash_show"
alias $forgit_stash_show 'forgit::stash::show'
else
alias gss 'forgit::stash::show'
end
if test -n "$forgit_cherry_pick"
alias $forgit_cherry_pick 'forgit::cherry::pick'
else
alias gcp 'forgit::cherry::pick'
end
end

View File

@ -0,0 +1,6 @@
# https://github.com/junegunn/fzf/wiki/Examples-(fish)
function fzf-bcd-widget -d 'cd backwards'
pwd | awk -v RS=/ '/\n/ {exit} {p=p $0 "/"; print p}' | tac | eval (__fzfcmd) +m --select-1 --exit-0 $FZF_BCD_OPTS | read -l result
[ "$result" ]; and cd $result
commandline -f repaint
end

View File

@ -0,0 +1,15 @@
# From https://github.com/junegunn/fzf/wiki/Examples-(fish)
function fzf-cdhist-widget -d 'cd to one of the previously visited locations'
# Clear non-existent folders from cdhist.
set -l buf
for i in (seq 1 (count $dirprev))
set -l dir $dirprev[$i]
if test -d $dir
set buf $buf $dir
end
end
set dirprev $buf
string join \n $dirprev | tac | sed 1d | eval (__fzfcmd) +m --tiebreak=index --toggle-sort=ctrl-r $FZF_CDHIST_OPTS | read -l result
[ "$result" ]; and cd $result
commandline -f repaint
end

View File

@ -0,0 +1,46 @@
# From https://github.com/junegunn/fzf/wiki/Examples-(fish)
function fzf-complete -d 'fzf completion and print selection back to commandline'
# As of 2.6, fish's "complete" function does not understand
# subcommands. Instead, we use the same hack as __fish_complete_subcommand and
# extract the subcommand manually.
set -l cmd (commandline -co) (commandline -ct)
switch $cmd[1]
case env sudo
for i in (seq 2 (count $cmd))
switch $cmd[$i]
case '-*'
case '*=*'
case '*'
set cmd $cmd[$i..-1]
break
end
end
end
set cmd (string join -- ' ' $cmd)
set -l complist (complete -C$cmd)
set -l result
string join -- \n $complist | sort | eval (__fzfcmd) -m --select-1 --exit-0 --header '(commandline)' | cut -f1 | while read -l r; set result $result $r; end
set prefix (string sub -s 1 -l 1 -- (commandline -t))
for i in (seq (count $result))
set -l r $result[$i]
switch $prefix
case "'"
commandline -t -- (string escape -- $r)
case '"'
if string match '*"*' -- $r >/dev/null
commandline -t -- (string escape -- $r)
else
commandline -t -- '"'$r'"'
end
case '~'
commandline -t -- (string sub -s 2 (string escape -n -- $r))
case '*'
commandline -t -- (string escape -n -- $r)
end
[ $i -lt (count $result) ]; and commandline -i ' '
end
commandline -f repaint
end

View File

@ -0,0 +1,8 @@
# From https://github.com/junegunn/fzf/wiki/Examples-(fish)
function fzf-select -d 'fzf commandline job and print unescaped selection back to commandline'
set -l cmd (commandline -j)
[ "$cmd" ]; or return
eval $cmd | eval (__fzfcmd) -m --tiebreak=index --select-1 --exit-0 | string join ' ' | read -l result
[ "$result" ]; and commandline -j -- $result
commandline -f repaint
end

View File

@ -0,0 +1,14 @@
#!/usr/bin/env fish
if not set --query fzf_fish_custom_keybindings
bind --erase --all \cf
bind --erase --all \cr
bind --erase --all \cv
bind --erase --all \e\cl
bind --erase --all \e\cs
set_color --italics cyan
echo "fzf.fish key bindings removed"
set_color normal
end
# Not going to erase FZF_DEFAULT_OPTS because too hard to tell if it was set by the user or by this plugin

View File

@ -0,0 +1,3 @@
longtailfinancial
holoviz
longtailfinancial