From 78e80ba3d4675bf64bcfbb4bb181407b0c5621ec Mon Sep 17 00:00:00 2001 From: Shawn Anderson Date: Mon, 28 Sep 2020 18:46:10 -0700 Subject: [PATCH] Super supe up my fish with fzf. Batteries are now included. --- dotfiles/.config/fish/conf.d/fzf.fish | 106 ++++++++++++++++++ dotfiles/.config/fish/config.fish | 2 +- .../__fzf_display_value_or_error.fish | 10 ++ .../fish/functions/__fzf_preview_file.fish | 28 +++++ .../functions/__fzf_report_file_type.fish | 6 + .../functions/__fzf_search_current_dir.fish | 16 +++ .../fish/functions/__fzf_search_git_log.fish | 20 ++++ .../functions/__fzf_search_git_status.fish | 29 +++++ .../fish/functions/__fzf_search_history.fish | 17 +++ .../__fzf_search_shell_variables.fish | 21 ++++ .../fish/functions/__github_add_org.fish | 9 ++ .../functions/__github_get_org_repos.fish | 9 ++ dotfiles/.config/fish/functions/fcd.fish | 19 ++++ dotfiles/.config/fish/functions/fclone.fish | 17 +++ dotfiles/.config/fish/functions/fhub.fish | 17 +++ dotfiles/.config/fish/functions/fkill.fish | 7 ++ .../.config/fish/functions/forgit.plugin.fish | 73 ------------ .../fish/functions/fzf-bcd-widget.fish | 6 + .../fish/functions/fzf-cdhist-widget.fish | 15 +++ .../.config/fish/functions/fzf-complete.fish | 46 ++++++++ .../.config/fish/functions/fzf-select.fish | 8 ++ .../.config/fish/functions/uninstall.fish | 14 +++ dotfiles/.local/share/fzf/github_orgs | 3 + 23 files changed, 424 insertions(+), 74 deletions(-) create mode 100644 dotfiles/.config/fish/conf.d/fzf.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_display_value_or_error.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_preview_file.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_report_file_type.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_search_current_dir.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_search_git_log.fish create mode 100755 dotfiles/.config/fish/functions/__fzf_search_git_status.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_search_history.fish create mode 100644 dotfiles/.config/fish/functions/__fzf_search_shell_variables.fish create mode 100644 dotfiles/.config/fish/functions/__github_add_org.fish create mode 100644 dotfiles/.config/fish/functions/__github_get_org_repos.fish create mode 100644 dotfiles/.config/fish/functions/fcd.fish create mode 100644 dotfiles/.config/fish/functions/fclone.fish create mode 100644 dotfiles/.config/fish/functions/fhub.fish create mode 100644 dotfiles/.config/fish/functions/fkill.fish create mode 100644 dotfiles/.config/fish/functions/fzf-bcd-widget.fish create mode 100644 dotfiles/.config/fish/functions/fzf-cdhist-widget.fish create mode 100644 dotfiles/.config/fish/functions/fzf-complete.fish create mode 100644 dotfiles/.config/fish/functions/fzf-select.fish create mode 100644 dotfiles/.config/fish/functions/uninstall.fish create mode 100644 dotfiles/.local/share/fzf/github_orgs diff --git a/dotfiles/.config/fish/conf.d/fzf.fish b/dotfiles/.config/fish/conf.d/fzf.fish new file mode 100644 index 0000000..63afc8c --- /dev/null +++ b/dotfiles/.config/fish/conf.d/fzf.fish @@ -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 + diff --git a/dotfiles/.config/fish/config.fish b/dotfiles/.config/fish/config.fish index e3abdab..c2b962a 100644 --- a/dotfiles/.config/fish/config.fish +++ b/dotfiles/.config/fish/config.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_display_value_or_error.fish b/dotfiles/.config/fish/functions/__fzf_display_value_or_error.fish new file mode 100644 index 0000000..6d10f0a --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_display_value_or_error.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_preview_file.fish b/dotfiles/.config/fish/functions/__fzf_preview_file.fish new file mode 100644 index 0000000..d0a9a95 --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_preview_file.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_report_file_type.fish b/dotfiles/.config/fish/functions/__fzf_report_file_type.fish new file mode 100644 index 0000000..e92eb02 --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_report_file_type.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_search_current_dir.fish b/dotfiles/.config/fish/functions/__fzf_search_current_dir.fish new file mode 100644 index 0000000..9435434 --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_search_current_dir.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_search_git_log.fish b/dotfiles/.config/fish/functions/__fzf_search_git_log.fish new file mode 100644 index 0000000..ffc7286 --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_search_git_log.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_search_git_status.fish b/dotfiles/.config/fish/functions/__fzf_search_git_status.fish new file mode 100755 index 0000000..153b95a --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_search_git_status.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_search_history.fish b/dotfiles/.config/fish/functions/__fzf_search_history.fish new file mode 100644 index 0000000..843a55b --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_search_history.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__fzf_search_shell_variables.fish b/dotfiles/.config/fish/functions/__fzf_search_shell_variables.fish new file mode 100644 index 0000000..906a395 --- /dev/null +++ b/dotfiles/.config/fish/functions/__fzf_search_shell_variables.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__github_add_org.fish b/dotfiles/.config/fish/functions/__github_add_org.fish new file mode 100644 index 0000000..3e7237a --- /dev/null +++ b/dotfiles/.config/fish/functions/__github_add_org.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/__github_get_org_repos.fish b/dotfiles/.config/fish/functions/__github_get_org_repos.fish new file mode 100644 index 0000000..870e195 --- /dev/null +++ b/dotfiles/.config/fish/functions/__github_get_org_repos.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fcd.fish b/dotfiles/.config/fish/functions/fcd.fish new file mode 100644 index 0000000..e779b74 --- /dev/null +++ b/dotfiles/.config/fish/functions/fcd.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fclone.fish b/dotfiles/.config/fish/functions/fclone.fish new file mode 100644 index 0000000..998079c --- /dev/null +++ b/dotfiles/.config/fish/functions/fclone.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fhub.fish b/dotfiles/.config/fish/functions/fhub.fish new file mode 100644 index 0000000..0a8310b --- /dev/null +++ b/dotfiles/.config/fish/functions/fhub.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fkill.fish b/dotfiles/.config/fish/functions/fkill.fish new file mode 100644 index 0000000..04cd1a1 --- /dev/null +++ b/dotfiles/.config/fish/functions/fkill.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/forgit.plugin.fish b/dotfiles/.config/fish/functions/forgit.plugin.fish index 2e9662b..4deb289 100644 --- a/dotfiles/.config/fish/functions/forgit.plugin.fish +++ b/dotfiles/.config/fish/functions/forgit.plugin.fish @@ -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 - diff --git a/dotfiles/.config/fish/functions/fzf-bcd-widget.fish b/dotfiles/.config/fish/functions/fzf-bcd-widget.fish new file mode 100644 index 0000000..07dc544 --- /dev/null +++ b/dotfiles/.config/fish/functions/fzf-bcd-widget.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fzf-cdhist-widget.fish b/dotfiles/.config/fish/functions/fzf-cdhist-widget.fish new file mode 100644 index 0000000..31bd6f7 --- /dev/null +++ b/dotfiles/.config/fish/functions/fzf-cdhist-widget.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fzf-complete.fish b/dotfiles/.config/fish/functions/fzf-complete.fish new file mode 100644 index 0000000..0ca0484 --- /dev/null +++ b/dotfiles/.config/fish/functions/fzf-complete.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/fzf-select.fish b/dotfiles/.config/fish/functions/fzf-select.fish new file mode 100644 index 0000000..88eab28 --- /dev/null +++ b/dotfiles/.config/fish/functions/fzf-select.fish @@ -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 diff --git a/dotfiles/.config/fish/functions/uninstall.fish b/dotfiles/.config/fish/functions/uninstall.fish new file mode 100644 index 0000000..bf450db --- /dev/null +++ b/dotfiles/.config/fish/functions/uninstall.fish @@ -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 diff --git a/dotfiles/.local/share/fzf/github_orgs b/dotfiles/.local/share/fzf/github_orgs new file mode 100644 index 0000000..c54682c --- /dev/null +++ b/dotfiles/.local/share/fzf/github_orgs @@ -0,0 +1,3 @@ +longtailfinancial +holoviz +longtailfinancial