diff --git a/.tool-versions b/.tool-versions index f2a971a..d554c9c 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -ruby 3.2.2 +ruby 3.3.3 diff --git a/Rakefile b/Rakefile index 2b4906e..8ce228a 100644 --- a/Rakefile +++ b/Rakefile @@ -136,7 +136,15 @@ namespace 'dot' do sp1 = @multi_spinner.register '[:spinner] Dependencies' sp1.auto_spin + run_apt_get 'asdf', lvl: 1 + run_apt_get 'autoconf', lvl: 1 + run_apt_get 'automake', lvl: 1 run_apt_get 'asciinema', lvl: 1 + run_apt_get 'cmake', lvl: 1 + run_apt_get 'cmatrix', lvl: 1 + run_apt_get 'git-delta', lvl: 1 + run_apt_get 'git-fixup', lvl: 1 + run_apt_get 'gitup', lvl: 1 run_apt_get 'fzf', lvl: 1 run_apt_get 'bat', lvl: 1 run_apt_get 'fd', lvl: 1 @@ -144,6 +152,8 @@ namespace 'dot' do run_apt_get 'neofetch', lvl: 1 run_apt_get 'bat', lvl: 1 run_apt_get 'neovim', lvl: 1 + run_apt_get 'lazydocker', lvl: 1 + run_apt_get 'lazygit', lvl: 1 sp1.success 'COMPLETE'.green end diff --git a/config/direnv/config.toml b/config/direnv/config.toml new file mode 120000 index 0000000..cda1479 --- /dev/null +++ b/config/direnv/config.toml @@ -0,0 +1 @@ +direnv.toml \ No newline at end of file diff --git a/config/direnv/direnv.toml b/config/direnv/direnv.toml index 1df214d..8b94c01 100644 --- a/config/direnv/direnv.toml +++ b/config/direnv/direnv.toml @@ -1,5 +1,5 @@ [whitelist] -prefix = [ "/Volumes/Workspace/achievemore/" ] +prefix = [ "~/projetos/achievemore/" ] [global] load_dotenv = true diff --git a/config/fish/completions/_git-forgit b/config/fish/completions/_git-forgit index 35919e7..7760511 100644 --- a/config/fish/completions/_git-forgit +++ b/config/fish/completions/_git-forgit @@ -1,12 +1,10 @@ -#compdef git-forgit +#compdef git-forgit -p forgit::* #description Utility tool for using git interactively # # forgit completions for zsh # # Place this file in your $fpath (e.g. /usr/share/zsh/site-functions) to enable -# tab completions for forgit as a git subcommmand. When using forgit as a shell -# plugin, additionally source completions/git-forgit.zsh after -# forgit.plugin.zsh to enable tab completion for shell functions and aliases. +# tab completions for forgit. _git-branches() { _alternative "branches:branchname:($(git branch -a --format '%(refname:short)'))" @@ -37,22 +35,26 @@ _git-staged() { _alternative "files:filename:($(git diff --name-only --staged))" } +_git-forgit-reflog() { + declare -a cmds + cmds=('expire:prune old reflog entries' 'delete:delete entries from reflog' 'show:show log of ref' 'exists:check whether a ref has a reflog') + _alternative 'cmds:: _describe -t cmds cmd cmds' 'refs:: __git_references' +} + _git-forgit() { - local subcommand cword cmd + local subcommand cmd subcommand="${words[1]}" - if [[ "$subcommand" != "forgit" ]]; then + if [[ "$subcommand" != "forgit"* ]]; then # Forgit is obviously called via a git alias. Get the original # aliased subcommand and proceed as if it was the previous word. cmd=$(git config --get "alias.$subcommand" | cut -d ' ' -f 2) - cword=$((CURRENT + 1)) else - cword=$CURRENT - cmd=${words[2]} + # The last word is the relevant command + cmd=${words[(( ${#words} - 1 ))]} fi - - case ${cword} in - 1) ;; - 2) + + case ${cmd} in + forgit) local -a subcommands subcommands=( 'add:git add selector' @@ -69,6 +71,7 @@ _git-forgit() { 'fixup:git fixup' 'ignore:git ignore generator' 'log:git commit viewer' + 'reflog:git reflog viewer' 'rebase:git rebase' 'reset_head:git reset HEAD (unstage) selector' 'revert_commit:git revert commit selector' @@ -77,25 +80,52 @@ _git-forgit() { ) _describe -t commands 'git forgit' subcommands ;; - *) - case ${cmd} in - add) _git-add ;; - branch_delete) _git-branches ;; - checkout_branch) _git-branches ;; - checkout_commit) __git_recent_commits ;; - checkout_file) _git-checkout-file ;; - checkout_tag) __git_tags ;; - cherry_pick) _git-cherry-pick ;; - cherry_pick_from_branch) _git-branches ;; - clean) _git-clean ;; - diff) _git-forgit-diff ;; - fixup) __git_branch_names ;; - log) _git-log ;; - rebase) _git-rebase ;; - reset_head) _git-staged ;; - revert_commit) __git_recent_commits ;; - stash_show) _git-stash-show ;; - esac - ;; + add) _git-add ;; + branch_delete) _git-branches ;; + checkout_branch) _git-branches ;; + checkout_commit) __git_recent_commits ;; + checkout_file) _git-checkout-file ;; + checkout_tag) __git_tags ;; + cherry_pick) _git-cherry-pick ;; + cherry_pick_from_branch) _git-branches ;; + clean) _git-clean ;; + diff) _git-forgit-diff ;; + fixup) __git_branch_names ;; + log) _git-log ;; + reflog) _git-forgit-reflog ;; + rebase) _git-rebase ;; + reset_head) _git-staged ;; + revert_commit) __git_recent_commits ;; + stash_show) _git-stash-show ;; esac } + +# We're reusing existing completion functions, so load those first +# if not already loaded and check if completion function exists afterwards. +(( $+functions[_git-add] )) || _git +(( $+functions[_git-add] )) || return 1 +# Completions for forgit plugin shell functions (also works for aliases) +compdef _git-add forgit::add +compdef _git-branches forgit::branch::delete +compdef _git-branches forgit::checkout::branch +compdef __git_recent_commits forgit::checkout::commit +compdef _git-checkout-file forgit::checkout::file +compdef __git_tags forgit::checkout::tag +compdef _git-cherry-pick forgit::cherry::pick +compdef _git-branches forgit::cherry::pick::from::branch +compdef _git-clean forgit::clean +compdef _git-forgit-diff forgit::diff +compdef __git_branch_names forgit::fixup +compdef _git-log forgit::log +compdef _git-reflog forgit::reflog +compdef _git-rebase forgit::rebase +compdef _git-staged forgit::reset::head +compdef __git_recent_commits forgit::revert::commit +compdef _git-stash-show forgit::stash::show + +# this is the case of calling the command and pressing tab +# the very first time of a shell session, we have to manually +# call the dispatch function +if [[ $funcstack[1] == "_git-forgit" ]]; then + _git-forgit "$@" +fi diff --git a/config/fish/completions/aws.fish b/config/fish/completions/aws.fish deleted file mode 100644 index fc75188..0000000 --- a/config/fish/completions/aws.fish +++ /dev/null @@ -1,16 +0,0 @@ -function __aws_complete - if set -q aws_completer_path - set -lx COMP_SHELL fish - set -lx COMP_LINE (commandline -opc) - - if string match -q -- "-*" (commandline -opt) - set COMP_LINE $COMP_LINE - - end - - eval $aws_completer_path | command sed 's/ $//' - end -end - -complete --command aws --no-files --arguments '(__aws_complete)' -complete --command aws --no-files --condition 'test (count (commandline -opc)) -lt 2' --arguments profile -d 'Get or set current profile' -complete --command aws --no-files --condition '__fish_seen_subcommand_from profile' --arguments '(aws profiles)' diff --git a/config/fish/completions/direnv.fish b/config/fish/completions/direnv.fish index 37c81dd..d010328 100644 --- a/config/fish/completions/direnv.fish +++ b/config/fish/completions/direnv.fish @@ -1,3 +1,5 @@ +# These completions are from https://github.com/halostatue/fish-direnv + complete --erase --command direnv set -l file_commands allow permit grant block deny revoke edit diff --git a/config/fish/completions/docker.fish b/config/fish/completions/docker.fish new file mode 100644 index 0000000..24b8f4e --- /dev/null +++ b/config/fish/completions/docker.fish @@ -0,0 +1,235 @@ +# fish completion for docker -*- shell-script -*- + +function __docker_debug + set -l file "$BASH_COMP_DEBUG_FILE" + if test -n "$file" + echo "$argv" >> $file + end +end + +function __docker_perform_completion + __docker_debug "Starting __docker_perform_completion" + + # Extract all args except the last one + set -l args (commandline -opc) + # Extract the last arg and escape it in case it is a space + set -l lastArg (string escape -- (commandline -ct)) + + __docker_debug "args: $args" + __docker_debug "last arg: $lastArg" + + # Disable ActiveHelp which is not supported for fish shell + set -l requestComp "DOCKER_ACTIVE_HELP=0 $args[1] __completeNoDesc $args[2..-1] $lastArg" + + __docker_debug "Calling $requestComp" + set -l results (eval $requestComp 2> /dev/null) + + # Some programs may output extra empty lines after the directive. + # Let's ignore them or else it will break completion. + # Ref: https://github.com/spf13/cobra/issues/1279 + for line in $results[-1..1] + if test (string trim -- $line) = "" + # Found an empty line, remove it + set results $results[1..-2] + else + # Found non-empty line, we have our proper output + break + end + end + + set -l comps $results[1..-2] + set -l directiveLine $results[-1] + + # For Fish, when completing a flag with an = (e.g., -n=) + # completions must be prefixed with the flag + set -l flagPrefix (string match -r -- '-.*=' "$lastArg") + + __docker_debug "Comps: $comps" + __docker_debug "DirectiveLine: $directiveLine" + __docker_debug "flagPrefix: $flagPrefix" + + for comp in $comps + printf "%s%s\n" "$flagPrefix" "$comp" + end + + printf "%s\n" "$directiveLine" +end + +# this function limits calls to __docker_perform_completion, by caching the result behind $__docker_perform_completion_once_result +function __docker_perform_completion_once + __docker_debug "Starting __docker_perform_completion_once" + + if test -n "$__docker_perform_completion_once_result" + __docker_debug "Seems like a valid result already exists, skipping __docker_perform_completion" + return 0 + end + + set --global __docker_perform_completion_once_result (__docker_perform_completion) + if test -z "$__docker_perform_completion_once_result" + __docker_debug "No completions, probably due to a failure" + return 1 + end + + __docker_debug "Performed completions and set __docker_perform_completion_once_result" + return 0 +end + +# this function is used to clear the $__docker_perform_completion_once_result variable after completions are run +function __docker_clear_perform_completion_once_result + __docker_debug "" + __docker_debug "========= clearing previously set __docker_perform_completion_once_result variable ==========" + set --erase __docker_perform_completion_once_result + __docker_debug "Succesfully erased the variable __docker_perform_completion_once_result" +end + +function __docker_requires_order_preservation + __docker_debug "" + __docker_debug "========= checking if order preservation is required ==========" + + __docker_perform_completion_once + if test -z "$__docker_perform_completion_once_result" + __docker_debug "Error determining if order preservation is required" + return 1 + end + + set -l directive (string sub --start 2 $__docker_perform_completion_once_result[-1]) + __docker_debug "Directive is: $directive" + + set -l shellCompDirectiveKeepOrder 32 + set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2) + __docker_debug "Keeporder is: $keeporder" + + if test $keeporder -ne 0 + __docker_debug "This does require order preservation" + return 0 + end + + __docker_debug "This doesn't require order preservation" + return 1 +end + + +# This function does two things: +# - Obtain the completions and store them in the global __docker_comp_results +# - Return false if file completion should be performed +function __docker_prepare_completions + __docker_debug "" + __docker_debug "========= starting completion logic ==========" + + # Start fresh + set --erase __docker_comp_results + + __docker_perform_completion_once + __docker_debug "Completion results: $__docker_perform_completion_once_result" + + if test -z "$__docker_perform_completion_once_result" + __docker_debug "No completion, probably due to a failure" + # Might as well do file completion, in case it helps + return 1 + end + + set -l directive (string sub --start 2 $__docker_perform_completion_once_result[-1]) + set --global __docker_comp_results $__docker_perform_completion_once_result[1..-2] + + __docker_debug "Completions are: $__docker_comp_results" + __docker_debug "Directive is: $directive" + + set -l shellCompDirectiveError 1 + set -l shellCompDirectiveNoSpace 2 + set -l shellCompDirectiveNoFileComp 4 + set -l shellCompDirectiveFilterFileExt 8 + set -l shellCompDirectiveFilterDirs 16 + + if test -z "$directive" + set directive 0 + end + + set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2) + if test $compErr -eq 1 + __docker_debug "Received error directive: aborting." + # Might as well do file completion, in case it helps + return 1 + end + + set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2) + set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2) + if test $filefilter -eq 1; or test $dirfilter -eq 1 + __docker_debug "File extension filtering or directory filtering not supported" + # Do full file completion instead + return 1 + end + + set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2) + set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2) + + __docker_debug "nospace: $nospace, nofiles: $nofiles" + + # If we want to prevent a space, or if file completion is NOT disabled, + # we need to count the number of valid completions. + # To do so, we will filter on prefix as the completions we have received + # may not already be filtered so as to allow fish to match on different + # criteria than the prefix. + if test $nospace -ne 0; or test $nofiles -eq 0 + set -l prefix (commandline -t | string escape --style=regex) + __docker_debug "prefix: $prefix" + + set -l completions (string match -r -- "^$prefix.*" $__docker_comp_results) + set --global __docker_comp_results $completions + __docker_debug "Filtered completions are: $__docker_comp_results" + + # Important not to quote the variable for count to work + set -l numComps (count $__docker_comp_results) + __docker_debug "numComps: $numComps" + + if test $numComps -eq 1; and test $nospace -ne 0 + # We must first split on \t to get rid of the descriptions to be + # able to check what the actual completion will be. + # We don't need descriptions anyway since there is only a single + # real completion which the shell will expand immediately. + set -l split (string split --max 1 \t $__docker_comp_results[1]) + + # Fish won't add a space if the completion ends with any + # of the following characters: @=/:., + set -l lastChar (string sub -s -1 -- $split) + if not string match -r -q "[@=/:.,]" -- "$lastChar" + # In other cases, to support the "nospace" directive we trick the shell + # by outputting an extra, longer completion. + __docker_debug "Adding second completion to perform nospace directive" + set --global __docker_comp_results $split[1] $split[1]. + __docker_debug "Completions are now: $__docker_comp_results" + end + end + + if test $numComps -eq 0; and test $nofiles -eq 0 + # To be consistent with bash and zsh, we only trigger file + # completion when there are no other completions + __docker_debug "Requesting file completion" + return 1 + end + end + + return 0 +end + +# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves +# so we can properly delete any completions provided by another script. +# Only do this if the program can be found, or else fish may print some errors; besides, +# the existing completions will only be loaded if the program can be found. +if type -q "docker" + # The space after the program name is essential to trigger completion for the program + # and not completion of the program name itself. + # Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish. + complete --do-complete "docker " > /dev/null 2>&1 +end + +# Remove any pre-existing completions for the program since we will be handling all of them. +complete -c docker -e + +# this will get called after the two calls below and clear the $__docker_perform_completion_once_result global +complete -c docker -n '__docker_clear_perform_completion_once_result' +# The call to __docker_prepare_completions will setup __docker_comp_results +# which provides the program's completion choices. +# If this doesn't require order preservation, we don't use the -k flag +complete -c docker -n 'not __docker_requires_order_preservation && __docker_prepare_completions' -f -a '$__docker_comp_results' +# otherwise we use the -k flag +complete -k -c docker -n '__docker_requires_order_preservation && __docker_prepare_completions' -f -a '$__docker_comp_results' diff --git a/config/fish/completions/git-forgit.bash b/config/fish/completions/git-forgit.bash index 43d0a99..9f500a8 100755 --- a/config/fish/completions/git-forgit.bash +++ b/config/fish/completions/git-forgit.bash @@ -71,6 +71,7 @@ _git_forgit() fixup ignore log + reflog rebase reset_head revert_commit @@ -96,6 +97,7 @@ _git_forgit() diff) _git_diff ;; fixup) _git_branch ;; log) _git_log ;; + reflog) _git_reflog ;; rebase) _git_rebase ;; reset_head) _git_reset ;; revert_commit) _git_revert ;; @@ -129,6 +131,7 @@ then __git_complete forgit::diff _git_diff __git_complete forgit::fixup _git_branch __git_complete forgit::log _git_log + __git_complete forgit::reflog _git_reflog __git_complete forgit::rebase _git_rebase __git_complete forgit::reset::head _git_reset __git_complete forgit::revert::commit _git_revert @@ -147,6 +150,7 @@ then __git_complete "${forgit_diff}" _git_diff __git_complete "${forgit_fixup}" _git_branch __git_complete "${forgit_log}" _git_log + __git_complete "${forgit_reflog}" _git_reflog __git_complete "${forgit_rebase}" _git_rebase __git_complete "${forgit_reset_head}" _git_reset __git_complete "${forgit_revert_commit}" _git_revert diff --git a/config/fish/completions/git-forgit.fish b/config/fish/completions/git-forgit.fish new file mode 100644 index 0000000..72c896b --- /dev/null +++ b/config/fish/completions/git-forgit.fish @@ -0,0 +1,61 @@ +# +# forgit completions for fish plugin +# +# Place this file inside your /completions/ directory. +# It's usually located at ~/.config/fish/completions/. The file is lazily +# sourced when git-forgit command or forgit subcommand of git is invoked. + +function __fish_forgit_needs_subcommand + for subcmd in add blame branch_delete checkout_branch checkout_commit checkout_file checkout_tag \ + cherry_pick cherry_pick_from_branch clean diff fixup ignore log reflog rebase reset_head \ + revert_commit stash_show stash_push + if contains -- $subcmd (commandline -opc) + return 1 + end + end + return 0 +end + +# Load helper functions in git completion file +not functions -q __fish_git && source $__fish_data_dir/completions/git.fish + +# No file completion by default +complete -c git-forgit -x + +complete -c git-forgit -n __fish_forgit_needs_subcommand -a add -d 'git add selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a blame -d 'git blame viewer' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a branch_delete -d 'git branch deletion selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a checkout_branch -d 'git checkout branch selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a checkout_commit -d 'git checkout commit selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a checkout_file -d 'git checkout-file selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a checkout_tag -d 'git checkout tag selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a cherry_pick -d 'git cherry-picking' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a cherry_pick_from_branch -d 'git cherry-picking with interactive branch selection' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a clean -d 'git clean selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a diff -d 'git diff viewer' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a fixup -d 'git fixup' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a ignore -d 'git ignore generator' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a log -d 'git commit viewer' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a reflog -d 'git reflog viewer' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a rebase -d 'git rebase' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a reset_head -d 'git reset HEAD (unstage) selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a revert_commit -d 'git revert commit selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a stash_show -d 'git stash viewer' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a stash_push -d 'git stash push selector' + +complete -c git-forgit -n '__fish_seen_subcommand_from add' -a "(complete -C 'git add ')" +complete -c git-forgit -n '__fish_seen_subcommand_from branch_delete' -a "(__fish_git_local_branches)" +complete -c git-forgit -n '__fish_seen_subcommand_from checkout_branch' -a "(complete -C 'git switch ')" +complete -c git-forgit -n '__fish_seen_subcommand_from checkout_commit' -a "(__fish_git_commits)" +complete -c git-forgit -n '__fish_seen_subcommand_from checkout_file' -a "(__fish_git_files modified)" +complete -c git-forgit -n '__fish_seen_subcommand_from checkout_tag' -a "(__fish_git_tags)" -d Tag +complete -c git-forgit -n '__fish_seen_subcommand_from cherry_pick' -a "(complete -C 'git cherry-pick ')" +complete -c git-forgit -n '__fish_seen_subcommand_from clean' -a "(__fish_git_files untracked ignored)" +complete -c git-forgit -n '__fish_seen_subcommand_from fixup' -a "(__fish_git_local_branches)" +complete -c git-forgit -n '__fish_seen_subcommand_from log' -a "(complete -C 'git log ')" +complete -c git-forgit -n '__fish_seen_subcommand_from reflog' -a "(complete -C 'git reflog ')" +complete -c git-forgit -n '__fish_seen_subcommand_from rebase' -a "(complete -C 'git rebase ')" +complete -c git-forgit -n '__fish_seen_subcommand_from reset_head' -a "(__fish_git_files all-staged)" +complete -c git-forgit -n '__fish_seen_subcommand_from revert_commit' -a "(__fish_git_commits)" +complete -c git-forgit -n '__fish_seen_subcommand_from stash_show' -a "(__fish_git_complete_stashes)" +complete -c git-forgit -n '__fish_seen_subcommand_from stash_push' -a "(__fish_git_files modified deleted modified-staged-deleted)" diff --git a/config/fish/completions/git-forgit.zsh b/config/fish/completions/git-forgit.zsh deleted file mode 100644 index 60f3f73..0000000 --- a/config/fish/completions/git-forgit.zsh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/zsh -# -# forgit completions for zsh plugin -# -# When using forgit via the shell plugin, place completions/_git-forgit in your -# $fpath (e.g. /usr/share/zsh/site-functions) and source this file after -# forgit.plugin.zsh to enable tab completion for shell functions and aliases. - -# Check if forgit plugin is loaded -if (( $+functions[forgit::add] )); then - # We're reusing existing completion functions, so load those first - # if not already loaded and check if completion function exists afterwards. - (( $+functions[_git-add] )) || _git - (( $+functions[_git-add] )) || return 1 - (( $+functions[_git-branches] )) || _git-forgit - (( $+functions[_git-branches] )) || return 1 - # Completions for forgit plugin shell functions (also works for aliases) - compdef _git-add forgit::add - compdef _git-branches forgit::branch::delete - compdef _git-branches forgit::checkout::branch - compdef __git_recent_commits forgit::checkout::commit - compdef _git-checkout-file forgit::checkout::file - compdef __git_tags forgit::checkout::tag - compdef _git-cherry-pick forgit::cherry::pick - compdef _git-branches forgit::cherry::pick::from::branch - compdef _git-clean forgit::clean - compdef _git-forgit-diff forgit::diff - compdef __git_branch_names forgit::fixup - compdef _git-log forgit::log - compdef _git-rebase forgit::rebase - compdef _git-staged forgit::reset::head - compdef __git_recent_commits forgit::revert::commit - compdef _git-stash-show forgit::stash::show -fi diff --git a/config/fish/conf.d/aws.fish b/config/fish/conf.d/aws.fish deleted file mode 100644 index ad7e53f..0000000 --- a/config/fish/conf.d/aws.fish +++ /dev/null @@ -1,6 +0,0 @@ -set -e aws_profile - -if not set -q aws_completer_path - set -g aws_completer_path (type -P aws_completer 2> /dev/null) - or echo "aws: unable to find aws_completer, completions unavaliable" -end diff --git a/config/fish/conf.d/bin/git-forgit b/config/fish/conf.d/bin/git-forgit index 780ad18..7f96f9d 100755 --- a/config/fish/conf.d/bin/git-forgit +++ b/config/fish/conf.d/bin/git-forgit @@ -53,44 +53,161 @@ _forgit_previous_commit() { fi } +_forgit_contains_non_flags() { + while (("$#")); do + case "$1" in + -*) shift ;; + *) + return 0 + ;; + esac + done + return 1 +} + # optional render emoji characters (https://github.com/wfxr/emoji-cli) -hash emojify &>/dev/null && _forgit_emojify='|emojify' +_forgit_emojify() { + if hash emojify &>/dev/null; then + emojify + else + cat + fi +} # extract the first git sha occurring in the input and strip trailing newline -_forgit_extract_sha="grep -Eo '[a-f0-9]+' | head -1 | tr -d '[:space:]'" +_forgit_extract_sha() { + grep -Eo '[a-f0-9]+' | head -1 | tr -d '[:space:]' +} + +# extract the first git sha and copy it to the clipboard +_forgit_yank_sha() { + echo "$1" | _forgit_extract_sha | ${FORGIT_COPY_CMD:-pbcopy} +} -_forgit_pager=${FORGIT_PAGER:-$(git config core.pager || echo 'cat')} -_forgit_show_pager=${FORGIT_SHOW_PAGER:-$(git config pager.show || echo "$_forgit_pager")} -_forgit_diff_pager=${FORGIT_DIFF_PAGER:-$(git config pager.diff || echo "$_forgit_pager")} -_forgit_ignore_pager=${FORGIT_IGNORE_PAGER:-$(hash bat &>/dev/null && echo 'bat -l gitignore --color=always' || echo 'cat')} -_forgit_blame_pager=${FORGIT_BLAME_PAGER:-$(git config pager.blame || echo "$_forgit_pager")} -_forgit_enter_pager=${FORGIT_ENTER_PAGER:-"LESS='-r' less"} +# extract the first stash name in the input +_forgit_extract_stash_name() { + cut -d: -f1 | tr -d '[:space:]' +} + +# extract the first stash name and copy it to the clipboard +_forgit_yank_stash_name() { + echo "$1" | _forgit_extract_stash_name | ${FORGIT_COPY_CMD:-pbcopy} +} + +# parse a space separated string into an array +# arrays parsed with this function are global +_forgit_parse_array() { + ${IFS+"false"} && unset old_IFS || old_IFS="$IFS" + # read the value of the second argument + # into an array that has the name of the first argument + IFS=" " read -r -a "$1" <<< "$2" + ${old_IFS+"false"} && unset IFS || IFS="$old_IFS" +} + +# parse the input arguments and print only those after the "--" +# separator as a single line of quoted arguments to stdout +_forgit_quote_files() { + local files add + files=() + add=false + while (( "$#" )); do + case "$1" in + --) + add=true + shift + ;; + *) + if [ $add == true ]; then + files+=("'$1'") + fi + shift + ;; + esac + done + echo "${files[*]}" +} +_forgit_log_graph_enable=${FORGIT_LOG_GRAPH_ENABLE:-"true"} _forgit_log_format=${FORGIT_LOG_FORMAT:-%C(auto)%h%d %s %C(black)%C(bold)%cr%Creset} -_forgit_log_preview_options="--graph --pretty=format:'$_forgit_log_format' --color=always --abbrev-commit --date=relative" +_forgit_log_preview_options=("--graph" "--pretty=format:$_forgit_log_format" "--color=always" "--abbrev-commit" "--date=relative") _forgit_fullscreen_context=${FORGIT_FULLSCREEN_CONTEXT:-10} _forgit_preview_context=${FORGIT_PREVIEW_CONTEXT:-3} -_forgit_is_file_tracked="(git ls-files {} --error-unmatch) &> /dev/null" +_forgit_dir_view=${FORGIT_DIR_VIEW:-$(hash tree &> /dev/null && echo 'tree' || echo 'find')} + +_forgit_pager() { + local pager + pager=$(_forgit_get_pager "$1") + [[ -z "${pager}" ]] && exit 1 + eval "${pager} ${*:2}" +} + +_forgit_get_pager() { + local pager + pager=${1:-core} + case "$pager" in + core) echo -n "${FORGIT_PAGER:-$(git config core.pager || echo 'cat')}" ;; + show) echo -n "${FORGIT_SHOW_PAGER:-$(git config pager.show || _forgit_get_pager)}" ;; + diff) echo -n "${FORGIT_DIFF_PAGER:-$(git config pager.diff || _forgit_get_pager)}" ;; + ignore) echo -n "${FORGIT_IGNORE_PAGER:-$(hash bat &>/dev/null && echo 'bat -l gitignore --color=always' || echo 'cat')}" ;; + blame) echo -n "${FORGIT_BLAME_PAGER:-$(git config pager.blame || _forgit_get_pager)}" ;; + enter) echo -n "${FORGIT_ENTER_PAGER:-"LESS='-r' less"}" ;; + *) echo "pager not found: $1" >&2 ;; + esac +} + +_forgit_is_file_tracked() { + git ls-files "$1" --error-unmatch &> /dev/null +} + +_forgit_list_files() { + local rootdir + rootdir=$(git rev-parse --show-toplevel) + # git escapes special characters in it's output when core.quotePath is + # true or unset. Git always expects unquoted file paths as input. This + # leads to issues when we consume output from git and use it to build + # input for other git commands. Use the -z flag to ensure file paths are + # unquoted. + # uniq is necessary because unmerged files are printed once for each + # merge conflict. + # With the -z flag, git also uses \0 line termination, so we + # have to replace the terminators. + git ls-files -z "$@" "$rootdir" | tr '\0' '\n' | uniq +} + +_forgit_log_preview() { + local sha + sha=$(echo "$1" | _forgit_extract_sha) + shift + echo "$sha" | xargs -I% git show --color=always -U"$_forgit_preview_context" % -- "$@" | _forgit_pager show +} + +_forgit_log_enter() { + local sha + sha=$(echo "$1" | _forgit_extract_sha) + shift + echo "$sha" | xargs -I% "${FORGIT}" diff %^! "$@" +} # git commit viewer _forgit_log() { _forgit_inside_work_tree || return 1 - local opts graph files log_format preview_cmd enter_cmd - files=$(sed -nE 's/.*-- (.*)/\1/p' <<< "$*") # extract files parameters for `git show` command - preview_cmd="echo {} | $_forgit_extract_sha | xargs -I% git show --color=always -U$_forgit_preview_context % -- $files | $_forgit_show_pager" - enter_cmd="echo {} | $_forgit_extract_sha | xargs -I% ${FORGIT} diff %^! $files" + local opts graph quoted_files log_format + quoted_files=$(_forgit_quote_files "$@") opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index - --bind=\"enter:execute($enter_cmd)\" - --bind=\"ctrl-y:execute-silent(echo {} | $_forgit_extract_sha | ${FORGIT_COPY_CMD:-pbcopy})\" - --preview=\"$preview_cmd\" + --bind=\"enter:execute($FORGIT log_enter {} $quoted_files)\" + --bind=\"ctrl-y:execute-silent($FORGIT yank_sha {})\" + --preview=\"$FORGIT log_preview {} $quoted_files\" $FORGIT_LOG_FZF_OPTS " - graph=--graph - [[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph= + graph=() + [[ $_forgit_log_graph_enable == true ]] && graph=(--graph) log_format=${FORGIT_GLO_FORMAT:-$_forgit_log_format} - eval "git log $graph --color=always --format='$log_format' $FORGIT_LOG_GIT_OPTS $* $_forgit_emojify" | + _forgit_log_git_opts=() + _forgit_parse_array _forgit_log_git_opts "$FORGIT_LOG_GIT_OPTS" + git log "${graph[@]}" --color=always --format="$log_format" "${_forgit_log_git_opts[@]}" "$@" | + _forgit_emojify | FZF_DEFAULT_OPTS="$opts" fzf fzf_exit_code=$? # exit successfully on 130 (ctrl-c/esc) @@ -98,22 +215,32 @@ _forgit_log() { return $fzf_exit_code } -# git diff viewer -_forgit_diff() { +# git reflog viewer +_forgit_reflog() { _forgit_inside_work_tree || return 1 - local files opts commits repo get_files preview_cmd enter_cmd - [[ $# -ne 0 ]] && { - if git rev-parse "$1" -- &>/dev/null ; then - if [[ $# -gt 1 ]] && git rev-parse "$2" -- &>/dev/null; then - commits="$1 $2" && files=("${@:3}") - else - commits="$1" && files=("${@:2}") - fi - else - files=("$@") - fi - } - repo="$(git rev-parse --show-toplevel)" + _forgit_contains_non_flags "$@" && { git reflog "$@"; return $?; } + local opts reflog_format + opts=" + $FORGIT_FZF_DEFAULT_OPTS + +s +m --tiebreak=index + --bind=\"enter:execute($FORGIT log_enter {})\" + --bind=\"ctrl-y:execute-silent($FORGIT yank_sha {})\" + --preview=\"$FORGIT log_preview {}\" + $FORGIT_REFLOG_FZF_OPTS + " + reflog_format=${FORGIT_GRL_FORMAT:-$_forgit_log_format} + _forgit_reflog_git_opts=() + _forgit_parse_array _forgit_reflog_git_opts "$FORGIT_REFLOG_GIT_OPTS" + git reflog show --color=always --format="$reflog_format" "${_forgit_reflog_git_opts[@]}" "$@" | + _forgit_emojify | + FZF_DEFAULT_OPTS="$opts" fzf + fzf_exit_code=$? + # exit successfully on 130 (ctrl-c/esc) + [[ $fzf_exit_code == 130 ]] && return 0 + return $fzf_exit_code +} + +_forgit_get_files_from_diff_line() { # Construct a null-terminated list of the filenames # The input looks like one of these lines: # [R100] file -> another file @@ -125,24 +252,85 @@ _forgit_diff() { # oldfile\0 # We have to do a two-step sed -> tr pipe because OSX's sed implementation does # not support the null-character directly. - get_files="echo {} | sed 's/.*] *//' | sed 's/ -> /\\\n/' | tr '\\\n' '\\\0'" + sed 's/^[[:space:]]*\[[A-Z0-9]*\][[:space:]]*//' | sed 's/ -> /\n/' | tr '\n' '\0' +} + +_forgit_get_single_file_from_diff_line() { + # Similar to the function above, but only gets a single file from a single line + # Gets the new name of renamed files + sed 's/^[[:space:]]*\[[A-Z0-9]*\][[:space:]]*//' | sed 's/.*-> //' +} + +_forgit_exec_diff() { + _forgit_diff_git_opts=() + _forgit_parse_array _forgit_diff_git_opts "$FORGIT_DIFF_GIT_OPTS" + git diff --color=always "${_forgit_diff_git_opts[@]}" "$@" +} + +_forgit_diff_view() { + local input_line=$1 + local diff_context=$2 + local repo + local commits=() + repo=$(git rev-parse --show-toplevel) + cd "$repo" || return 1 + if [ $# -gt 2 ]; then + IFS=" " read -r -a commits <<< "${*:3}" + fi + echo "$input_line" | _forgit_get_files_from_diff_line | xargs -0 \ + "$FORGIT" exec_diff "${commits[@]}" -U"$diff_context" -- | _forgit_pager diff +} + +_forgit_edit_diffed_file() { + local input_line rootdir + input_line=$1 + rootdir=$(git rev-parse --show-toplevel) + filename=$(echo "$input_line" | _forgit_get_single_file_from_diff_line) + $EDITOR "$rootdir/$filename" >/dev/tty /dev/null ; then + if [[ $# -gt 1 ]] && git rev-parse "$2" -- &>/dev/null; then + commits=("$1" "$2") && files=("${@:3}") + else + commits=("$1") && files=("${@:2}") + fi + else + files=("$@") + fi + } # Git stashes are named "stash@{x}", which contains the fzf placeholder "{x}". # In order to support passing stashes as arguments to _forgit_diff, we have to # prevent fzf from interpreting this substring by escaping the opening bracket. # The string is evaluated a few subsequent times, so we need multiple escapes. - escaped_commits=${commits//\{/\\\\\{} - git_diff="git diff --color=always $FORGIT_DIFF_GIT_OPTS $escaped_commits" - preview_cmd="cd '$repo' && $get_files | xargs -0 $git_diff -U$_forgit_preview_context -- | $_forgit_diff_pager" - enter_cmd="cd '$repo' && $get_files | xargs -0 $git_diff -U$_forgit_fullscreen_context -- | $_forgit_diff_pager" + for commit in "${commits[@]}"; do + escaped_commits+="'${commit//\{/\\\\\{}' " + done opts=" $FORGIT_FZF_DEFAULT_OPTS - +m -0 --bind=\"enter:execute($enter_cmd | $_forgit_enter_pager)\" - --preview=\"$preview_cmd\" - --bind=\"alt-e:execute-silent($EDITOR \$\($get_files\) >/dev/tty \" + --prompt=\"${commits[*]} > \" " - eval "git diff --name-status $FORGIT_DIFF_GIT_OPTS $commits -- ${files[*]} | sed -E 's/^([[:alnum:]]+)[[:space:]]+(.*)$/[\1] \2/'" | + _forgit_diff_git_opts=() + _forgit_parse_array _forgit_diff_git_opts "$FORGIT_DIFF_GIT_OPTS" + git diff --name-status "${_forgit_diff_git_opts[@]}" "${commits[@]}" -- "${files[@]}" | + sed -E 's/^([[:alnum:]]+)[[:space:]]+(.*)$/[\1] \2/' | sed 's/ / -> /2' | expand -t 8 | FZF_DEFAULT_OPTS="$opts" fzf fzf_exit_code=$? @@ -151,93 +339,150 @@ _forgit_diff() { return $fzf_exit_code } +_forgit_add_preview() { + file=$(echo "$1" | _forgit_get_single_file_from_add_line) + if (git status -s -- "$file" | grep '^??') &>/dev/null; then # diff with /dev/null for untracked files + git diff --color=always --no-index -- /dev/null "$file" | _forgit_pager diff | sed '2 s/added:/untracked:/' + else + git diff --color=always -- "$file" | _forgit_pager diff + fi +} + +_forgit_git_add() { + _forgit_add_git_opts=() + _forgit_parse_array _forgit_add_git_opts "$FORGIT_ADD_GIT_OPTS" + git add "${_forgit_add_git_opts[@]}" "$@" +} + +_forgit_get_single_file_from_add_line() { + # NOTE: paths listed by 'git status -su' mixed with quoted and unquoted style + # remove indicators | remove original path for rename case | remove surrounding quotes + sed 's/^.*] //' | + sed 's/.* -> //' | + sed -e 's/^\"//' -e 's/\"$//' +} + +_forgit_edit_add_file() { + local input_line=$1 + filename=$(echo "$input_line" | _forgit_get_single_file_from_add_line) + $EDITOR "$filename" >/dev/tty /dev/null; then # diff with /dev/null for untracked files - git diff --color=always --no-index -- /dev/null \\\"\$file\\\" | $_forgit_diff_pager | sed '2 s/added:/untracked:/' - else - git diff --color=always -- \\\"\$file\\\" | $_forgit_diff_pager - fi" opts=" $FORGIT_FZF_DEFAULT_OPTS -0 -m --nth 2..,.. - --preview=\"$preview\" - --bind=\"alt-e:execute-silent($EDITOR \$\(echo {} | $extract\) >/dev/tty /dev/null && return 0 - local git_clean files opts - git_clean="git clean $FORGIT_CLEAN_GIT_OPTS" + _forgit_contains_non_flags "$@" && { git clean -q "$@"; return $?; } + local files opts + _forgit_clean_git_opts=() + _forgit_parse_array _forgit_clean_git_opts "$FORGIT_CLEAN_GIT_OPTS" opts=" $FORGIT_FZF_DEFAULT_OPTS + --preview=\"$FORGIT clean_preview {}\" -m -0 $FORGIT_CLEAN_FZF_OPTS " # Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed. - files=$(git clean -xdffn "$@"| sed 's/^Would remove //' | FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') - # shellcheck disable=2086 - [[ -n "$files" ]] && echo "$files" | tr '\n' '\0' | xargs -0 -I% $git_clean -xdff '%' && git status --short && return + files=$(git -c core.quotePath=false clean -xdffn "$@"| sed 's/^Would remove //' | FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') + [[ -n "$files" ]] && echo "$files" | tr '\n' '\0' | xargs -0 -I% git clean "${_forgit_clean_git_opts[@]}" -xdff '%' && git status --short && return echo 'Nothing to clean.' } -_forgit_cherry_pick() { - local git_cherry_pick base target preview opts fzf_selection fzf_exitval +_forgit_cherry_pick_preview() { + echo "$1" | cut -f2- | _forgit_extract_sha | xargs -I% git show --color=always % | _forgit_pager show +} - git_cherry_pick="git cherry-pick $FORGIT_CHERRY_PICK_GIT_OPTS" +_forgit_cherry_pick() { + local base target opts fzf_selection fzf_exitval base=$(git branch --show-current) [[ -z "$base" ]] && echo "Current commit is not on a branch." && return 1 @@ -305,10 +561,9 @@ _forgit_cherry_pick() { # The instances of "cut", "nl" and "sort" all serve this purpose # Please see https://github.com/wfxr/forgit/issues/253 for more details - preview="echo {} | cut -f2- | $_forgit_extract_sha | xargs -I% git show --color=always % | $_forgit_show_pager" opts=" $FORGIT_FZF_DEFAULT_OPTS - --preview=\"$preview\" + --preview=\"$FORGIT cherry_pick_preview {}\" --multi --ansi --with-nth 2.. -0 --tiebreak=index $FORGIT_CHERRY_PICK_FZF_OPTS " @@ -320,19 +575,24 @@ _forgit_cherry_pick() { [[ $fzf_exitval != 0 ]] && return $fzf_exitval [[ -z "$fzf_selection" ]] && return $fzf_exitval - ${IFS+"false"} && unset old_IFS || old_IFS="$IFS" - IFS=$'\n' - # shellcheck disable=2207 - commits=($(echo "$fzf_selection" | sort --numeric-sort --key=1 | cut -f2 | cut -d' ' -f1 | _forgit_reverse_lines)) - ${old_IFS+"false"} && unset IFS || IFS="$old_IFS" + commits=() + while IFS='' read -r commit; do + commits+=("$commit") + done < <(echo "$fzf_selection" | sort -n -k 1 | cut -f2 | cut -d' ' -f1 | _forgit_reverse_lines) [ ${#commits[@]} -eq 0 ] && return 1 + + _forgit_cherry_pick_git_opts=() + _forgit_parse_array _forgit_cherry_pick_git_opts "$FORGIT_CHERRY_PICK_GIT_OPTS" + git cherry-pick "${_forgit_cherry_pick_git_opts[@]}" "${commits[@]}" +} - $git_cherry_pick "${commits[@]}" +_forgit_cherry_pick_from_branch_preview() { + git log --right-only --color=always --cherry-pick --oneline "$1"..."$2" } _forgit_cherry_pick_from_branch() { _forgit_inside_work_tree || return 1 - local cmd preview opts branch exitval input_branch args base + local opts branch exitval input_branch args base base=$(git branch --show-current) [[ -z "$base" ]] && echo "Current commit is not on a branch." && return 1 @@ -341,12 +601,10 @@ _forgit_cherry_pick_from_branch() { if [[ $# -ne 0 ]]; then input_branch=${args[0]} fi - cmd="git branch --color=always --all | LC_ALL=C sort -k1.1,1.1 -rs" - preview="git log --right-only --color=always --cherry-pick --oneline $base...{1}" opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index --header-lines=1 - --preview=\"$preview\" + --preview=\"$FORGIT cherry_pick_from_branch_preview '$base' {1}\" $FORGIT_CHERRY_PICK_FROM_BRANCH_FZF_OPTS " # loop until either the branch selector is closed or a commit to be cherry @@ -354,7 +612,10 @@ _forgit_cherry_pick_from_branch() { while true do if [[ -z $input_branch ]]; then - branch="$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $1}')" + branch="$(git branch --color=always --all | + LC_ALL=C sort -k1.1,1.1 -rs | + FZF_DEFAULT_OPTS="$opts" fzf | + awk '{print $1}')" else branch=$input_branch fi @@ -371,70 +632,99 @@ _forgit_cherry_pick_from_branch() { _forgit_rebase() { _forgit_inside_work_tree || return 1 - local git_rebase cmd preview opts graph files target_commit prev_commit - git_rebase="git rebase -i $FORGIT_REBASE_GIT_OPTS" - graph=--graph - [[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph= - cmd="git log $graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify" - files=$(sed -nE 's/.* -- (.*)/\1/p' <<< "$*") # extract files parameters for `git show` command - preview="echo {} | $_forgit_extract_sha | xargs -I% git show --color=always % -- $files | $_forgit_show_pager" + local opts graph quoted_files target_commit prev_commit + graph=() + [[ $_forgit_log_graph_enable == true ]] && graph=(--graph) + _forgit_rebase_git_opts=() + _forgit_parse_array _forgit_rebase_git_opts "$FORGIT_REBASE_GIT_OPTS" + quoted_files=$(_forgit_quote_files "$@") opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index - --bind=\"ctrl-y:execute-silent(echo {} | $_forgit_extract_sha | ${FORGIT_COPY_CMD:-pbcopy})\" - --preview=\"$preview\" + --bind=\"ctrl-y:execute-silent($FORGIT yank_sha {})\" + --preview=\"$FORGIT file_preview {} $quoted_files\" $FORGIT_REBASE_FZF_OPTS " - target_commit=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$_forgit_extract_sha") + target_commit=$( + git log "${graph[@]}" --color=always --format="$_forgit_log_format" "$@" | + _forgit_emojify | + FZF_DEFAULT_OPTS="$opts" fzf | + _forgit_extract_sha) if [[ -n "$target_commit" ]]; then prev_commit=$(_forgit_previous_commit "$target_commit") - - $git_rebase "$prev_commit" + git rebase -i "${_forgit_rebase_git_opts[@]}" "$prev_commit" fi } +_forgit_file_preview() { + local sha + sha=$(echo "$1" | _forgit_extract_sha) + shift + echo "$sha" | xargs -I% git show --color=always % -- "$@" | _forgit_pager show +} + _forgit_fixup() { _forgit_inside_work_tree || return 1 git diff --cached --quiet && echo 'Nothing to fixup: there are no staged changes.' && return 1 - local git_fixup cmd preview opts graph files target_commit prev_commit - git_fixup="git commit --fixup $FORGIT_FIXUP_GIT_OPTS" - graph=--graph - [[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph= - cmd="git log $graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify" - files=$(sed -nE 's/.* -- (.*)/\1/p' <<< "$*") - preview="echo {} | $_forgit_extract_sha | xargs -I% git show --color=always % -- $files | $_forgit_show_pager" + local opts graph quoted_files target_commit prev_commit + graph=() + [[ $_forgit_log_graph_enable == true ]] && graph=(--graph) + _forgit_fixup_git_opts=() + _forgit_parse_array _forgit_fixup_git_opts "$FORGIT_FIXUP_GIT_OPTS" + quoted_files=$(_forgit_quote_files "$@") opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index - --bind=\"ctrl-y:execute-silent(echo {} | $_forgit_extract_sha | ${FORGIT_COPY_CMD:-pbcopy})\" - --preview=\"$preview\" + --bind=\"ctrl-y:execute-silent($FORGIT yank_sha {})\" + --preview=\"$FORGIT file_preview {} $quoted_files\" $FORGIT_FIXUP_FZF_OPTS " - target_commit=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | eval "$_forgit_extract_sha") - if [[ -n "$target_commit" ]] && $git_fixup "$target_commit"; then + target_commit=$( + git log "${graph[@]}" --color=always --format="$_forgit_log_format" "$@" | + _forgit_emojify | + FZF_DEFAULT_OPTS="$opts" fzf | + _forgit_extract_sha) + if [[ -n "$target_commit" ]] && git commit "${_forgit_fixup_git_opts[@]}" --fixup "$target_commit"; then prev_commit=$(_forgit_previous_commit "$target_commit") # rebase will fail if there are unstaged changes so --autostash is needed to temporarily stash them # GIT_SEQUENCE_EDITOR=: is needed to skip the editor GIT_SEQUENCE_EDITOR=: git rebase --autostash -i --autosquash "$prev_commit" fi +} + +_forgit_checkout_file_preview() { + git diff --color=always -- "$1" | _forgit_pager diff +} +_forgit_git_checkout_file() { + _forgit_checkout_file_git_opts=() + _forgit_parse_array _forgit_checkout_file_git_opts "$FORGIT_CHECKOUT_FILE_GIT_OPTS" + git checkout "${_forgit_checkout_file_git_opts[@]}" "$@" } # git checkout-file selector _forgit_checkout_file() { _forgit_inside_work_tree || return 1 - local git_checkout cmd files opts - git_checkout="git checkout $FORGIT_CHECKOUT_FILE_GIT_OPTS" - [[ $# -ne 0 ]] && { $git_checkout -- "$@"; return $?; } - cmd="git diff --color=always -- {} | $_forgit_diff_pager" + local files opts + [[ $# -ne 0 ]] && { _forgit_git_checkout_file -- "$@"; return $?; } opts=" $FORGIT_FZF_DEFAULT_OPTS -m -0 - --preview=\"$cmd\" + --preview=\"$FORGIT checkout_file_preview {}\" $FORGIT_CHECKOUT_FILE_FZF_OPTS " - files="$(git ls-files --modified "$(git rev-parse --show-toplevel)"| FZF_DEFAULT_OPTS="$opts" fzf)" - [[ -n "$files" ]] && echo "$files" | tr '\n' '\0' | $git_checkout --pathspec-file-nul --pathspec-from-file - + files=() + while IFS='' read -r file; do + files+=("$file") + done < <(_forgit_list_files --modified | + FZF_DEFAULT_OPTS="$opts" fzf) + [[ "${#files[@]}" -gt 0 ]] && _forgit_git_checkout_file "${files[@]}" +} + +_forgit_git_checkout_branch() { + _forgit_checkout_branch_git_opts=() + _forgit_parse_array _forgit_checkout_branch_git_opts "$FORGIT_CHECKOUT_BRANCH_GIT_OPTS" + git checkout "${_forgit_checkout_branch_git_opts[@]}" "$@" } # git checkout-branch selector @@ -442,7 +732,7 @@ _forgit_checkout_branch() { _forgit_inside_work_tree || return 1 # if called with arguments, check if branch exists, else create a new one if [[ $# -ne 0 ]]; then - if git show-branch "$@" &>/dev/null; then + if [[ "$*" == "-" ]] || git show-branch "$@" &>/dev/null; then git switch "$@" else git switch -c "$@" @@ -452,153 +742,204 @@ _forgit_checkout_branch() { return $checkout_status fi - local git_checkout cmd preview opts branch - cmd="git branch --color=always ${FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS:---all} | LC_ALL=C sort -k1.1,1.1 -rs" - preview="git log {1} $_forgit_log_preview_options" + local opts branch opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index --header-lines=1 - --preview=\"$preview\" + --preview=\"$FORGIT branch_preview {1}\" $FORGIT_CHECKOUT_BRANCH_FZF_OPTS " - branch="$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $1}')" + _forgit_checkout_branch_branch_git_opts=() + _forgit_parse_array _forgit_checkout_branch_branch_git_opts "$FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS" + branch="$(git branch --color=always "${_forgit_checkout_branch_branch_git_opts[@]:---all}" | LC_ALL=C sort -k1.1,1.1 -rs | + FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $1}')" [[ -z "$branch" ]] && return 1 - git_checkout="git checkout $FORGIT_CHECKOUT_BRANCH_GIT_OPTS" # track the remote branch if possible if [[ "$branch" == "remotes/origin/"* ]]; then if git branch | grep -qw "${branch#remotes/origin/}"; then # hack to force creating a new branch which tracks the remote if a local branch already exists - $git_checkout -b "track/${branch#remotes/origin/}" --track "$branch" - elif ! $git_checkout --track "$branch" 2>/dev/null; then - $git_checkout "$branch" + _forgit_git_checkout_branch -b "track/${branch#remotes/origin/}" --track "$branch" + elif ! _forgit_git_checkout_branch --track "$branch" 2>/dev/null; then + _forgit_git_checkout_branch "$branch" fi else - $git_checkout "$branch" + _forgit_git_checkout_branch "$branch" fi } +_forgit_git_checkout_tag() { + _forgit_checkout_tag_git_opts=() + _forgit_parse_array _forgit_checkout_tag_git_opts "$FORGIT_CHECKOUT_TAG_GIT_OPTS" + git checkout "${_forgit_checkout_tag_git_opts[@]}" "$@" +} + # git checkout-tag selector _forgit_checkout_tag() { _forgit_inside_work_tree || return 1 - local git_checkout cmd opts preview - git_checkout="git checkout $FORGIT_CHECKOUT_TAG_GIT_OPTS" - [[ $# -ne 0 ]] && { $git_checkout "$@"; return $?; } - cmd="git tag -l --sort=-v:refname" - preview="git log {1} $_forgit_log_preview_options" + local opts + [[ $# -ne 0 ]] && { _forgit_git_checkout_tag "$@"; return $?; } opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index - --preview=\"$preview\" + --preview=\"$FORGIT branch_preview {}\" $FORGIT_CHECKOUT_TAG_FZF_OPTS " - tag="$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf)" + tag="$(git tag -l --sort=-v:refname | FZF_DEFAULT_OPTS="$opts" fzf)" [[ -z "$tag" ]] && return 1 - $git_checkout "$tag" + _forgit_git_checkout_tag "$tag" +} + +_forgit_checkout_commit_preview() { + echo "$1" | _forgit_extract_sha | xargs -I% git show --color=always % | _forgit_pager show +} + +_forgit_git_checkout_commit() { + _forgit_checkout_commit_git_opts=() + _forgit_parse_array _forgit_checkout_commit_git_opts "$FORGIT_CHECKOUT_COMMIT_GIT_OPTS" + git checkout "${_forgit_checkout_commit_git_opts[@]}" "$@" } # git checkout-commit selector _forgit_checkout_commit() { _forgit_inside_work_tree || return 1 - local git_checkout cmd opts graph - git_checkout="git checkout $FORGIT_CHECKOUT_COMMIT_GIT_OPTS" - [[ $# -ne 0 ]] && { $git_checkout "$@"; return $?; } - cmd="echo {} | $_forgit_extract_sha |xargs -I% git show --color=always % | $_forgit_show_pager" + local opts graph commit + [[ $# -ne 0 ]] && { _forgit_git_checkout_commit "$@"; return $?; } opts=" $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index - --bind=\"ctrl-y:execute-silent(echo {} | $_forgit_extract_sha | ${FORGIT_COPY_CMD:-pbcopy})\" - --preview=\"$cmd\" + --bind=\"ctrl-y:execute-silent($FORGIT yank_sha {})\" + --preview=\"$FORGIT checkout_commit_preview {}\" $FORGIT_CHECKOUT_COMMIT_FZF_OPTS " - graph=--graph - [[ $FORGIT_LOG_GRAPH_ENABLE == false ]] && graph= - # shellcheck disable=2086 - eval "git log $graph --color=always --format='$_forgit_log_format' $_forgit_emojify" | - FZF_DEFAULT_OPTS="$opts" fzf | eval "$_forgit_extract_sha" | xargs -I% $git_checkout % -- + graph=() + [[ $_forgit_log_graph_enable == true ]] && graph=(--graph) + commit="$(git log "${graph[@]}" --color=always --format="$_forgit_log_format" | + _forgit_emojify | + FZF_DEFAULT_OPTS="$opts" fzf | _forgit_extract_sha)" + _forgit_git_checkout_commit "$commit" +} + +_forgit_branch_preview() { + # the trailing '--' ensures that this works for branches that have a name + # that is identical to a file + git log "$1" "${_forgit_log_preview_options[@]}" -- +} + +_forgit_git_branch_delete() { + _forgit_branch_delete_git_opts=() + _forgit_parse_array _forgit_branch_delete_git_opts "$FORGIT_BRANCH_DELETE_GIT_OPTS" + git branch "${_forgit_branch_delete_git_opts[@]}" -D "$@" } _forgit_branch_delete() { _forgit_inside_work_tree || return 1 - local git_branch preview opts cmd branches - git_branch="git branch $FORGIT_BRANCH_DELETE_GIT_OPTS" - [[ $# -ne 0 ]] && $git_branch -D "$@" && return - preview="git log {1} $_forgit_log_preview_options" + local opts + [[ $# -ne 0 ]] && { _forgit_git_branch_delete "$@"; return $?; } opts=" $FORGIT_FZF_DEFAULT_OPTS +s --multi --tiebreak=index --header-lines=1 - --preview=\"$preview\" + --preview=\"$FORGIT branch_preview {1}\" $FORGIT_BRANCH_DELETE_FZF_OPTS " - cmd="git branch --color=always | LC_ALL=C sort -k1.1,1.1 -rs" - branches=$(eval "$cmd" | FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $1}') - # shellcheck disable=2086 - echo -n "$branches" | tr '\n' '\0' | xargs -I{} -0 $git_branch -D {} + for branch in $(git branch --color=always | + LC_ALL=C sort -k1.1,1.1 -rs | + FZF_DEFAULT_OPTS="$opts" fzf | + awk '{print $1}') + do + _forgit_git_branch_delete "$branch" + done +} + +_forgit_revert_preview() { + echo "$1" | + cut -f2- | + _forgit_extract_sha | + xargs -I% git show --color=always % | + _forgit_pager show +} + +_forgit_git_revert() { + _forgit_revert_commit_git_opts=() + _forgit_parse_array _forgit_revert_commit_git_opts "$FORGIT_REVERT_COMMIT_GIT_OPTS" + git revert "${_forgit_revert_commit_git_opts[@]}" "$@" } # git revert-commit selector _forgit_revert_commit() { _forgit_inside_work_tree || return 1 - local git_revert cmd opts files preview commits IFS - git_revert="git revert $FORGIT_REVERT_COMMIT_GIT_OPTS" - [[ $# -ne 0 ]] && { $git_revert "$@"; return $?; } + local opts commits IFS + [[ $# -ne 0 ]] && { _forgit_git_revert "$@"; return $?; } - cmd="git log --graph --color=always --format='$_forgit_log_format' $* $_forgit_emojify" opts=" $FORGIT_FZF_DEFAULT_OPTS - +s --tiebreak=index + -m +s --tiebreak=index --ansi --with-nth 2.. + --preview=\"$FORGIT revert_preview {}\" $FORGIT_REVERT_COMMIT_FZF_OPTS " + graph=() + [[ $_forgit_log_graph_enable == true ]] && graph=(--graph) # in this function, we do something interesting to maintain proper ordering as it's assumed # you generally want to revert newest->oldest when you multiselect # The instances of "cut", "nl" and "sort" all serve this purpose # Please see https://github.com/wfxr/forgit/issues/253 for more details - files=$(sed -nE 's/.* -- (.*)/\1/p' <<< "$*") # extract files parameters for `git show` command - preview="echo {} | cut -f2- | $_forgit_extract_sha | xargs -I% git show --color=always % -- $files | $_forgit_show_pager" - - ${IFS+"false"} && unset old_IFS || old_IFS="$IFS" - IFS=$'\n' - # shellcheck disable=2207 - commits=($(eval "$cmd" | + commits=() + while IFS='' read -r commit; do + commits+=("$commit") + done < <( + git log "${graph[@]}" --color=always --format="$_forgit_log_format" | + _forgit_emojify | nl | - FZF_DEFAULT_OPTS="$opts" fzf --preview="$preview" -m | - sort --numeric-sort --key=1 | + FZF_DEFAULT_OPTS="$opts" fzf | + sort -n -k 1 | cut -f2- | - sed 's/^[^a-f^0-9]*\([a-f0-9]*\).*/\1/')) - ${old_IFS+"false"} && unset IFS || IFS="$old_IFS" + sed 's/^[^a-f^0-9]*\([a-f0-9]*\).*/\1/') [ ${#commits[@]} -eq 0 ] && return 1 - $git_revert "${commits[@]}" + _forgit_git_revert "${commits[@]}" +} + +_forgit_blame_preview() { + if _forgit_is_file_tracked "$1"; then + _forgit_blame_git_opts=() + _forgit_parse_array _forgit_blame_git_opts "$FORGIT_BLAME_GIT_OPTS" + git blame --date=short "${_forgit_blame_git_opts[@]}" "$@" | _forgit_pager blame + else + echo "File not tracked" + fi +} + +_forgit_git_blame() { + _forgit_blame_git_opts=() + _forgit_parse_array _forgit_blame_git_opts "$FORGIT_BLAME_GIT_OPTS" + git blame "${_forgit_blame_git_opts[@]}" "$@" } # git blame viewer _forgit_blame() { _forgit_inside_work_tree || return 1 - local git_blame opts flags preview file - git_blame="git blame $FORGIT_BLAME_GIT_OPTS" - [[ $# -ne 0 ]] && $git_blame "$@" && return 0 + local opts flags file + _forgit_contains_non_flags "$@" && { _forgit_git_blame "$@"; return $?; } + flags=() + while IFS='' read -r flag; do + flags+=("$flag") + done < <(git rev-parse --flags "$@") opts=" $FORGIT_FZF_DEFAULT_OPTS + --preview=\"$FORGIT blame_preview {} ${flags[*]}\" $FORGIT_BLAME_FZF_OPTS " - flags=$(git rev-parse --flags "$@") - preview=" - if $_forgit_is_file_tracked; then - git blame {} --date=short $FORGIT_BLAME_GIT_OPTS $flags | $_forgit_blame_pager - else - echo File not tracked - fi - " - file=$(FZF_DEFAULT_OPTS="$opts" fzf --preview="$preview") + # flags is not quoted here, which is fine given that they are retrieved + # with git rev-parse and can only contain flags + file=$(FZF_DEFAULT_OPTS="$opts" fzf) [[ -z "$file" ]] && return 1 - # shellcheck disable=2086 - eval $git_blame "$file" "$flags" + _forgit_git_blame "$file" "${flags[@]}" } # git ignore generator @@ -606,25 +947,33 @@ export FORGIT_GI_REPO_REMOTE=${FORGIT_GI_REPO_REMOTE:-https://github.com/dvcs/gi export FORGIT_GI_REPO_LOCAL="${FORGIT_GI_REPO_LOCAL:-${XDG_CACHE_HOME:-$HOME/.cache}/forgit/gi/repos/dvcs/gitignore}" export FORGIT_GI_TEMPLATES=${FORGIT_GI_TEMPLATES:-$FORGIT_GI_REPO_LOCAL/templates} +_forgit_ignore_preview() { + quoted_files=() + for file in "$FORGIT_GI_TEMPLATES/$1"{,.gitignore}; do + quoted_files+=("'$file'") + done + _forgit_pager ignore "${quoted_files[@]}" 2>/dev/null +} + _forgit_ignore() { [ -d "$FORGIT_GI_REPO_LOCAL" ] || _forgit_ignore_update - local IFS cmd args opts - cmd="$_forgit_ignore_pager $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" + local IFS args opts opts=" $FORGIT_FZF_DEFAULT_OPTS -m --preview-window='right:70%' - --preview=\"eval $cmd\" + --preview=\"$FORGIT ignore_preview {2}\" $FORGIT_IGNORE_FZF_OPTS " - ${IFS+"false"} && unset old_IFS || old_IFS="$IFS" - IFS=$'\n' - # shellcheck disable=SC2206,2207 - args=($@) && [[ $# -eq 0 ]] && args=($(_forgit_ignore_list | nl -nrn -w4 -s' ' | - FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $2}')) - ${old_IFS+"false"} && unset IFS || IFS="$old_IFS" + args=("$@") + if [[ $# -eq 0 ]]; then + args=() + while IFS='' read -r arg; do + args+=("$arg") + done < <(_forgit_ignore_list | nl -w4 -s' ' | + FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $2}') + fi [ ${#args[@]} -eq 0 ] && return 1 - # shellcheck disable=SC2068 - _forgit_ignore_get ${args[@]} + _forgit_ignore_get "${args[@]}" } _forgit_ignore_update() { if [[ -d "$FORGIT_GI_REPO_LOCAL" ]]; then @@ -653,7 +1002,7 @@ _forgit_ignore_clean() { [[ -d "$FORGIT_GI_REPO_LOCAL" ]] && rm -rf "$FORGIT_GI_REPO_LOCAL" } -valid_commands=( +public_commands=( "add" "blame" "branch_delete" @@ -668,6 +1017,7 @@ valid_commands=( "fixup" "ignore" "log" + "reflog" "rebase" "reset_head" "revert_commit" @@ -675,18 +1025,45 @@ valid_commands=( "stash_push" ) +private_commands=( + "add_preview" + "blame_preview" + "branch_preview" + "checkout_commit_preview" + "checkout_file_preview" + "cherry_pick_from_branch_preview" + "cherry_pick_preview" + "clean_preview" + "diff_enter" + "file_preview" + "ignore_preview" + "revert_preview" + "reset_head_preview" + "stash_push_preview" + "stash_show_preview" + "yank_sha" + "yank_stash_name" + "log_preview" + "log_enter" + "exec_diff" + "diff_view" + "edit_diffed_file" + "edit_add_file" + "pager" +) + cmd="$1" shift # shellcheck disable=SC2076 -if [[ ! " ${valid_commands[*]} " =~ " ${cmd} " ]]; then +if [[ ! " ${public_commands[*]} " =~ " ${cmd} " ]] && [[ ! " ${private_commands[*]} " =~ " ${cmd} " ]]; then if [[ -z "$cmd" ]]; then printf "forgit: missing command\n\n" else printf "forgit: '%s' is not a valid forgit command.\n\n" "$cmd" fi printf "The following commands are supported:\n" - printf "\t%s\n" "${valid_commands[@]}" + printf "\t%s\n" "${public_commands[@]}" exit 1 fi diff --git a/config/fish/conf.d/forgit.plugin.fish b/config/fish/conf.d/forgit.plugin.fish index 48e3182..18761d0 100644 --- a/config/fish/conf.d/forgit.plugin.fish +++ b/config/fish/conf.d/forgit.plugin.fish @@ -1,10 +1,10 @@ # MIT (c) Chris Apple -set INSTALL_DIR (dirname (dirname (status -f))) -set -x FORGIT_INSTALL_DIR "$INSTALL_DIR/conf.d" +set -l install_dir (dirname (status dirname)) +set -x FORGIT_INSTALL_DIR "$install_dir/conf.d" set -x FORGIT "$FORGIT_INSTALL_DIR/bin/git-forgit" -if [ ! -e "$FORGIT" ] - set -x FORGIT_INSTALL_DIR "$INSTALL_DIR/vendor_conf.d" +if not test -e "$FORGIT" + set -x FORGIT_INSTALL_DIR "$install_dir/vendor_conf.d" set -x FORGIT "$FORGIT_INSTALL_DIR/bin/git-forgit" end @@ -27,206 +27,28 @@ set | awk -F ' ' '{ print $1 }' | grep FORGIT_ | while read var end end -function forgit::log -d "git commit viewer" - "$FORGIT" log $argv -end - -function forgit::diff -d "git diff viewer" --argument-names arg1 arg2 - "$FORGIT" diff $argv -end - -function forgit::add -d "git add selector" --wraps "git add" - "$FORGIT" add $argv -end - -function forgit::reset::head -d "git reset HEAD (unstage) selector" - "$FORGIT" reset_head $argv -end - -function forgit::stash::show -d "git stash viewer" - "$FORGIT" stash_show $argv -end - -function forgit::stash::push -d "git stash push selector" () - "$FORGIT" stash_push $argv -end - -function forgit::clean -d "git clean selector" - "$FORGIT" clean $argv -end - -function forgit::cherry::pick -d "git cherry-picking" --argument-names 'target' --wraps "git cherry-pick" - "$FORGIT" cherry_pick $argv -end - -function forgit::cherry::pick::from::branch -d "git cherry-picking with interactive branch selection" --wraps "git cherry-pick" - "$FORGIT" cherry_pick_from_branch $argv -end - -function forgit::rebase -d "git rebase" - "$FORGIT" rebase $argv -end - -function forgit::fixup -d "git fixup" - "$FORGIT" fixup $argv -end - -function forgit::checkout::file -d "git checkout-file selector" --argument-names 'file_name' --wraps "git checkout --" - "$FORGIT" checkout_file $argv -end - -function forgit::checkout::branch -d "git checkout branch selector" --argument-names 'input_branch_name' --wraps "git branch" - "$FORGIT" checkout_branch $argv -end - -function forgit::checkout::tag -d "git checkout tag selector" --argument-names 'tag_name' --wraps "git checkout" - "$FORGIT" checkout_tag $argv -end - -function forgit::checkout::commit -d "git checkout commit selector" --argument-names 'commit_id' --wraps "git checkout" - "$FORGIT" checkout_commit $argv -end - -function forgit::branch::delete -d "git branch deletion selector" --wraps "git branch --delete" - "$FORGIT" branch_delete $argv -end - -function forgit::revert::commit -d "git revert commit selector" --argument-names 'commit_hash' --wraps "git revert --" - "$FORGIT" revert_commit $argv -end - -function forgit::blame -d "git blame viewer" - "$FORGIT" blame $argv -end - -function forgit::ignore -d "git ignore generator" - "$FORGIT" ignore $argv -end - -function forgit::ignore::update - "$FORGIT" ignore_update $argv -end - -function forgit::ignore::get - "$FORGIT" ignore_get $argv -end +# alias `git-forgit` to the full-path of the command +alias git-forgit "$FORGIT" -function forgit::ignore::list - "$FORGIT" ignore_list $argv -end - -function forgit::ignore::clean - "$FORGIT" ignore_clean $argv -end - -# register aliases +# register abbreviations 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_checkout_file" - alias $forgit_checkout_file 'forgit::checkout::file' - else - alias gcf 'forgit::checkout::file' - end - - if test -n "$forgit_checkout_branch" - alias $forgit_checkout_branch 'forgit::checkout::branch' - else - alias gcb 'forgit::checkout::branch' - end - - if test -n "$forgit_branch_delete" - alias $forgit_branch_delete 'forgit::branch::delete' - else - alias gbd 'forgit::branch::delete' - 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_stash_push" - alias $forgit_stash_push 'forgit::stash::push' - else - alias gsp 'forgit::stash::push' - end - - if test -n "$forgit_cherry_pick" - alias $forgit_cherry_pick 'forgit::cherry::pick::from::branch' - else - alias gcp 'forgit::cherry::pick::from::branch' - end - - if test -n "$forgit_rebase" - alias $forgit_rebase 'forgit::rebase' - else - alias grb 'forgit::rebase' - end - - if test -n "$forgit_fixup" - alias $forgit_fixup 'forgit::fixup' - else - alias gfu 'forgit::fixup' - end - - if test -n "$forgit_checkout_commit" - alias $forgit_checkout_commit 'forgit::checkout::commit' - else - alias gco 'forgit::checkout::commit' - end - - if test -n "$forgit_revert_commit" - alias $forgit_revert_commit 'forgit::revert::commit' - else - alias grc 'forgit::revert::commit' - end - - if test -n "$forgit_blame" - alias $forgit_blame 'forgit::blame' - else - alias gbl 'forgit::blame' - end - - if test -n "$forgit_checkout_tag" - alias $forgit_checkout_tag 'forgit::checkout::tag' - else - alias gct 'forgit::checkout::tag' - end - + abbr -a -- (string collect $forgit_add; or string collect "ga") git-forgit add + abbr -a -- (string collect $forgit_reset_head; or string collect "grh") git-forgit reset_head + abbr -a -- (string collect $forgit_log; or string collect "glo") git-forgit log + abbr -a -- (string collect $forgit_reflog; or string collect "grl") git-forgit reflog + abbr -a -- (string collect $forgit_diff; or string collect "gd") git-forgit diff + abbr -a -- (string collect $forgit_ignore; or string collect "gi") git-forgit ignore + abbr -a -- (string collect $forgit_checkout_file; or string collect "gcf") git-forgit checkout_file + abbr -a -- (string collect $forgit_checkout_branch; or string collect "gcb") git-forgit checkout_branch + abbr -a -- (string collect $forgit_branch_delete; or string collect "gbd") git-forgit branch_delete + abbr -a -- (string collect $forgit_clean; or string collect "gclean") git-forgit clean + abbr -a -- (string collect $forgit_stash_show; or string collect "gss") git-forgit stash_show + abbr -a -- (string collect $forgit_stash_push; or string collect "gsp") git-forgit stash_push + abbr -a -- (string collect $forgit_cherry_pick; or string collect "gcp") git-forgit cherry_pick_from_branch + abbr -a -- (string collect $forgit_rebase; or string collect "grb") git-forgit rebase + abbr -a -- (string collect $forgit_fixup; or string collect "gfu") git-forgit fixup + abbr -a -- (string collect $forgit_checkout_commit; or string collect "gco") git-forgit checkout_commit + abbr -a -- (string collect $forgit_revert_commit; or string collect "grc") git-forgit revert_commit + abbr -a -- (string collect $forgit_blame; or string collect "gbl") git-forgit blame + abbr -a -- (string collect $forgit_checkout_tag; or string collect "gct") git-forgit checkout_tag end diff --git a/config/fish/config.fish b/config/fish/config.fish index 044e47d..16e5d4e 100644 --- a/config/fish/config.fish +++ b/config/fish/config.fish @@ -1,136 +1,125 @@ -function __fish_complete_aws - env COMP_LINE=(commandline -pc) aws_completer | tr -d ' ' -end - -complete -c aws -f -a "(__fish_complete_aws)" - if status is-interactive - # Commands to run in interactive sessions can go here - set -U fish_key_bindings fish_default_key_bindings + # Commands to run in interactive sessions can go here + set -U fish_key_bindings fish_default_key_bindings + # + set -g theme_display_ruby yes + set -g theme_color_scheme dark + set -g theme_nerd_fonts yes + set -g theme_powerline_fonts yes + set -g theme_date_timezone America/Sao_Paulo + + set -gx VIRTUAL_ENV_DISABLE_PROMPT 1 + # set -gx PROJECT_PATHS /Volumes/Workspace/ + set --universal tide_right_prompt_items status cmd_duration context jobs vi_mode virtual_env time + + set -g theme_display_virtualenv no + set -g theme_display_ruby no + set -g theme_title_use_abbreviated_path no + set -g theme_project_dir_length 1 + + set -g fish_prompt_pwd_dir_length 0 +end - set -g theme_display_ruby yes - set -g theme_color_scheme dark - set -g theme_nerd_fonts yes - set -g theme_powerline_fonts yes - set -g theme_date_timezone America/Sao_Paulo +# source ~/.iterm2_shell_integration.fish - set -gx VIRTUAL_ENV_DISABLE_PROMPT 1 - set -gx PROJECT_PATHS /Volumes/Workspace/ - set --universal tide_right_prompt_items status cmd_duration context jobs vi_mode virtual_env time +alias vim="nvim" - set -g theme_display_virtualenv no - set -g theme_display_ruby no - set -g theme_title_use_abbreviated_path no - set -g theme_project_dir_length 1 +fish_add_path -a "/home/linuxbrew/.linuxbrew/bin" +fish_add_path -a "$HOME/.pub-cache/bin" +fish_add_path -a /usr/local/opt/flutter/bin +fish_add_path -a "/Users/dlani/.cargo/bin" +fish_add_path -a "$HOME/.local/bin/" +fish_add_path -a /usr/local/sbin +fish_add_path -a "$HOME/bin" +fish_add_path -a "/home/linuxbrew/.linuxbrew/sbin" +fish_add_path -a "$HOME/.local/share/nvim/mason/bin" +fish_add_path -a "$HOME/.asdf/shims/" - set -g fish_prompt_pwd_dir_length 0 -end +# fzf --fish | source +fzf_configure_bindings --directory=\cf -# alias vim="lvim" -alias cat="bat" -set -gx PATH $PATH "$HOME/.pub-cache/bin" -set -gx PATH $PATH "/usr/local/opt/flutter/bin" -set -gx FLUTTER_ROOT (asdf where flutter) -set -gx PATH $PATH "/Users/dlani/.cargo/bin" -set -gx PATH $PATH "/Users/dlani/.local/bin/" -set -gx PATH $PATH "/usr/local/sbin" -set -gx PATH "$HOME/bin" $PATH set -gx GPG_TTY $(tty) -# set -gx USE_LIMA 1 -# set -gx BAT_THEME "base16" -# set -gx LS_COLORS $(gdircolors ~/.dir_colors | grep -o "\'.*\'" | grep -o '[0-9a-z:=;*.]\+') - -# set -gx LUA_PATH "/Users/dlani/.config/nvim/?.lua;/Users/dlani/.config/lvim/?.lua" - -set -gx FLUTTER_ROOT (asdf where flutter) -set -gx EDITOR "vim" +set -gx EDITOR vim set -gx HOMEBREW_NO_ENV_HINTS 1 -set -gx FORGIT_PAGER 'delta --side-by-side -w ${FZF_PREVIEW_COLUMNS:-$COLUMNS}' +set -gx FORGIT_PAGER 'delta --side-by-side -w ${FZF_PREVIEW_COLUMNS:-$COLUMNS}' -# done set -U __done_enabled 1 set -U __done_initial_window_id com.googlecode.iterm2 set -U __done_notification_command "terminal-notifier -sender com.googlecode.iterm2 -title \$title -message \$message" set -U __done_min_cmd_duration 5000 set -U __done_notify_sound 1 -# done - -source /usr/local/opt/asdf/libexec/asdf.fish -alias work="cd /Volumes/Workspace/" -alias mux="tmuxinator" +# alias work="cd /Volumes/Workspace/" +# alias mux="tmuxinator" alias top="htop" alias meuip="curl https://ipinfo.io/ip" -alias workspace="cd /Volumes/Workspace" -alias work="cd /Volumes/Workspace" +# alias workspace="cd /Volumes/Workspace" alias serve="browser-sync start -s -f . --no-notify --host 0.0.0.0 --port 9000" alias colortest="curl -s https://gist.githubusercontent.com/HaleTom/89ffe32783f89f403bba96bd7bcd1263/raw/ | bash" alias zev="zellij --layout dev" -# alias docker="lima nerdctl" -# alias task="dstask" -if type -q exa - alias ll "exa -l -g --icons --group-directories-first" - alias la "ll -a" - alias lk "ll --grid" +if type -q eza + alias ll "eza -l -g --icons --group-directories-first" + alias ll2 "eza -l -g --icons --group-directories-first --tree --level 2" + alias la "ll -a" + alias lk "ll --grid" end function fish_greeting - if test -z "$DISABLE_GREETING" - neofetch --ascii ~/.config/neofetch/cyberdyne - end + if test -z "$DISABLE_GREETING" + neofetch --ascii ~/.config/neofetch/cyberdyne + end end if status is-interactive # zellij setup --generate-auto-start fish | source end +set DIRENV_CONFIG $XDG_CONFIG_HOME/direnv/direnv.toml -# git-town completions fish | source +if type -q direnv + direnv hook fish | source +end -fzf_configure_bindings --directory=\cf +if type -q zoxide + zoxide init fish | source +end -# test -r ~/.dir_colors && eval $(/usr/local/Cellar/coreutils/9.1/libexec/gnubin/dircolors ~/.dir_colors -c) +for f in ~/.dotfiles/sources/* + cat "$f" | source +end -# fish_vi_key_bindings normal +if type -q ngrok + eval "$(ngrok completion)" +end +if type -q shadowenv + shadowenv init fish | source +end -# >>> conda initialize >>> -# !! Contents within this block are managed by 'conda init' !! -# if test -f /usr/local/Caskroom/miniconda/base/bin/conda -# eval /usr/local/Caskroom/miniconda/base/bin/conda "shell.fish" "hook" $argv | source -# end -# <<< conda initialize <<< +if test -d "/home/linuxbrew/.linuxbrew/share/fish/completions" + set -gx fish_complete_path $fish_complete_path /home/linuxbrew/.linuxbrew/share/fish/completions +end -direnv hook fish | source -# starship init fish | source -# dstask _completions fish | source -# ng completion script | source -zoxide init fish | source +if test -d "/home/linuxbrew/.linuxbrew/share/fish/vendor_completions.d" + set -gx fish_complete_path $fish_complete_path /home/linuxbrew/.linuxbrew/share/fish/vendor_completions.d +end -for f in ~/.dotfiles/sources/* - cat "$f" | source +if test -d "/home/linuxbrew/.linuxbrew/share/fish/completions" + source /home/linuxbrew/.linuxbrew/opt/asdf/libexec/asdf.fish end -# if command -v ngrok &>/dev/null; then - eval "$(ngrok completion)" -# fi - -# function cd -w='cd' -# builtin cd $argv || return -# check_directory_for_new_repository -# end - -# function check_directory_for_new_repository -# set current_repository (git rev-parse --show-toplevel 2> /dev/null) -# if [ "$current_repository" ] && \ -# [ "$current_repository" != "$last_repository" ] -# onefetch -# end -# set -gx last_repository $current_repository -# end - -# funcsave cd -# funcsave check_directory_for_new_repository +# >>> conda initialize >>> +# !! Contents within this block are managed by 'conda init' !! +if test -f /home/dlani/.asdf/installs/python/miniconda3-3.9-23.9.0-0/bin/conda + eval /home/dlani/.asdf/installs/python/miniconda3-3.9-23.9.0-0/bin/conda "shell.fish" "hook" $argv | source +else + if test -f "/home/dlani/.asdf/installs/python/miniconda3-3.9-23.9.0-0/etc/fish/conf.d/conda.fish" + . "/home/dlani/.asdf/installs/python/miniconda3-3.9-23.9.0-0/etc/fish/conf.d/conda.fish" + else + set -x PATH "/home/dlani/.asdf/installs/python/miniconda3-3.9-23.9.0-0/bin" $PATH + end +end +# <<< conda initialize <<< diff --git a/config/fish/fish_plugins b/config/fish/fish_plugins index 736d01d..2c349c2 100644 --- a/config/fish/fish_plugins +++ b/config/fish/fish_plugins @@ -1,15 +1,14 @@ +jethrokuan/z jorgebucaran/fisher +ilancosman/tide@v5 +wfxr/forgit oh-my-fish/plugin-await -oh-my-fish/plugin-aws oh-my-fish/plugin-brew danhper/fish-ssh-agent oh-my-fish/plugin-grc edc/bass nickeb96/puffer-fish -joseluisq/gitnow@2.10.0 jorgebucaran/autopair.fish +joseluisq/gitnow@2.10.0 halostatue/fish-direnv patrickf1/fzf.fish -wfxr/forgit -ilancosman/tide@v5 -jethrokuan/z diff --git a/config/fish/functions/__bass.py b/config/fish/functions/__bass.py index 3fe17fc..3f02bd4 100644 --- a/config/fish/functions/__bass.py +++ b/config/fish/functions/__bass.py @@ -36,6 +36,8 @@ def ignored(name): return True if name in IGNORED or name.startswith("BASH_FUNC"): return True + if name.startswith('%'): + return True return False def escape(string): diff --git a/config/fish/functions/__gi_update_completions.fish b/config/fish/functions/__gi_update_completions.fish deleted file mode 100644 index eb6fac3..0000000 --- a/config/fish/functions/__gi_update_completions.fish +++ /dev/null @@ -1,21 +0,0 @@ -function __gi_update_completions -d "Update completions for gitignore.io" - set compl_dir ~/.config/fish/completions - set compl_file "$compl_dir/gi.fish" - - # Download list of ignore types - set -l gi_list (gi list | tr ',' ' ') - if test -z "$gi_list" - echo "No result returned from gitignore.io" >&2 - return 1 - end - - # Backup existing completions - if test -e $compl_file - mv -f $compl_file {$compl_file}.bak - else if not test -d $compl_dir - mkdir -p $compl_dir - end - - # Output new completions - echo "complete -c gi -a \"update-completions $gi_list\"" >$compl_file -end diff --git a/config/fish/functions/_fzf_search_directory.fish b/config/fish/functions/_fzf_search_directory.fish index ad30a30..4541eec 100644 --- a/config/fish/functions/_fzf_search_directory.fish +++ b/config/fish/functions/_fzf_search_directory.fish @@ -5,8 +5,7 @@ function _fzf_search_directory --description "Search the current directory. Repl set -f fd_cmd (command -v fdfind || command -v fd || echo "fd") set -f --append fd_cmd --color=always $fzf_fd_opts - # $fzf_dir_opts is the deprecated version of $fzf_directory_opts - set -f fzf_arguments --multi --ansi $fzf_dir_opts $fzf_directory_opts + set -f fzf_arguments --multi --ansi $fzf_directory_opts set -f token (commandline --current-token) # expand any variables or leading tilde (~) in the token set -f expanded_token (eval echo -- $token) @@ -18,10 +17,10 @@ function _fzf_search_directory --description "Search the current directory. Repl if string match --quiet -- "*/" $unescaped_exp_token && test -d "$unescaped_exp_token" set --append fd_cmd --base-directory=$unescaped_exp_token # use the directory name as fzf's prompt to indicate the search is limited to that directory - set --prepend fzf_arguments --prompt="Search Directory $unescaped_exp_token> " --preview="_fzf_preview_file $expanded_token{}" + set --prepend fzf_arguments --prompt="Directory $unescaped_exp_token> " --preview="_fzf_preview_file $expanded_token{}" set -f file_paths_selected $unescaped_exp_token($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments) else - set --prepend fzf_arguments --prompt="Search Directory> " --query="$unescaped_exp_token" --preview='_fzf_preview_file {}' + set --prepend fzf_arguments --prompt="Directory> " --query="$unescaped_exp_token" --preview='_fzf_preview_file {}' set -f file_paths_selected ($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments) end diff --git a/config/fish/functions/_fzf_search_git_log.fish b/config/fish/functions/_fzf_search_git_log.fish index 2f0a521..aa54724 100644 --- a/config/fish/functions/_fzf_search_git_log.fish +++ b/config/fish/functions/_fzf_search_git_log.fish @@ -6,13 +6,19 @@ function _fzf_search_git_log --description "Search the output of git log and pre # %h gives you the abbreviated commit hash, which is useful for saving screen space, but we will have to expand it later below set -f fzf_git_log_format '%C(bold blue)%h%C(reset) - %C(cyan)%ad%C(reset) %C(yellow)%d%C(reset) %C(normal)%s%C(reset) %C(dim normal)[%an]%C(reset)' end + + set -f preview_cmd 'git show --color=always --stat --patch {1}' + if set --query fzf_diff_highlighter + set preview_cmd "$preview_cmd | $fzf_diff_highlighter" + end + set -f selected_log_lines ( git log --no-show-signature --color=always --format=format:$fzf_git_log_format --date=short | \ _fzf_wrapper --ansi \ --multi \ - --tiebreak=index \ - --prompt="Search Git Log> " \ - --preview='git show --color=always --stat --patch {1}' \ + --scheme=history \ + --prompt="Git Log> " \ + --preview=$preview_cmd \ --query=(commandline --current-token) \ $fzf_git_log_opts ) diff --git a/config/fish/functions/_fzf_search_git_status.fish b/config/fish/functions/_fzf_search_git_status.fish index f3138a0..358f88c 100644 --- a/config/fish/functions/_fzf_search_git_status.fish +++ b/config/fish/functions/_fzf_search_git_status.fish @@ -2,14 +2,19 @@ function _fzf_search_git_status --description "Search the output of git status. if not git rev-parse --git-dir >/dev/null 2>&1 echo '_fzf_search_git_status: Not in a git repository.' >&2 else + set -f preview_cmd '_fzf_preview_changed_file {}' + if set --query fzf_diff_highlighter + set preview_cmd "$preview_cmd | $fzf_diff_highlighter" + end + set -f 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_wrapper --ansi \ --multi \ - --prompt="Search Git Status> " \ + --prompt="Git Status> " \ --query=(commandline --current-token) \ - --preview='_fzf_preview_changed_file {}' \ + --preview=$preview_cmd \ --nth="2.." \ $fzf_git_status_opts ) diff --git a/config/fish/functions/_fzf_search_history.fish b/config/fish/functions/_fzf_search_history.fish index 4b8e3c8..cafbce9 100644 --- a/config/fish/functions/_fzf_search_history.fish +++ b/config/fish/functions/_fzf_search_history.fish @@ -10,21 +10,25 @@ function _fzf_search_history --description "Search command history. Replace the set -f fzf_history_time_format "%m-%d %H:%M:%S" end + # Delinate time from command in history entries using the vertical box drawing char (U+2502). + # Then, to get raw command from history entries, delete everything up to it. The ? on regex is + # necessary to make regex non-greedy so it won't match into commands containing the char. + set -f time_prefix_regex '^.*? │ ' # Delinate commands throughout pipeline using null rather than newlines because commands can be multi-line set -f commands_selected ( builtin history --null --show-time="$fzf_history_time_format │ " | _fzf_wrapper --read0 \ --print0 \ --multi \ - --tiebreak=index \ - --prompt="Search History> " \ + --scheme=history \ + --prompt="History> " \ --query=(commandline) \ - --preview="echo -- {} | string replace --regex '^.*? │ ' '' | fish_indent --ansi" \ + --preview="string replace --regex '$time_prefix_regex' '' -- {} | fish_indent --ansi" \ --preview-window="bottom:3:wrap" \ $fzf_history_opts | string split0 | # remove timestamps from commands selected - string replace --regex '^.*? │ ' '' + string replace --regex $time_prefix_regex '' ) if test $status -eq 0 diff --git a/config/fish/functions/_fzf_search_processes.fish b/config/fish/functions/_fzf_search_processes.fish index 4e8b288..133a880 100644 --- a/config/fish/functions/_fzf_search_processes.fish +++ b/config/fish/functions/_fzf_search_processes.fish @@ -8,7 +8,7 @@ function _fzf_search_processes --description "Search all running processes. Repl set -f processes_selected ( $ps_cmd -A -opid,command | \ _fzf_wrapper --multi \ - --prompt="Search Processes> " \ + --prompt="Processes> " \ --query (commandline --current-token) \ --ansi \ # first line outputted by ps is a header, so we need to mark it as so diff --git a/config/fish/functions/_fzf_search_variables.fish b/config/fish/functions/_fzf_search_variables.fish index bf82340..52a7c70 100644 --- a/config/fish/functions/_fzf_search_variables.fish +++ b/config/fish/functions/_fzf_search_variables.fish @@ -23,12 +23,11 @@ function _fzf_search_variables --argument-names set_show_output set_names_output set -f variable_names_selected ( printf '%s\n' $all_variable_names | _fzf_wrapper --preview "_fzf_extract_var_info {} $set_show_output" \ - --prompt="Search Variables> " \ + --prompt="Variables> " \ --preview-window="wrap" \ --multi \ --query=$cleaned_curr_token \ - # $fzf_shell_vars_opts is the deprecated version of $fzf_variables_opts - $fzf_shell_vars_opts $fzf_variables_opts + $fzf_variables_opts ) if test $status -eq 0 diff --git a/config/fish/functions/_fzf_wrapper.fish b/config/fish/functions/_fzf_wrapper.fish index 45556ce..486e36c 100644 --- a/config/fish/functions/_fzf_wrapper.fish +++ b/config/fish/functions/_fzf_wrapper.fish @@ -4,9 +4,10 @@ function _fzf_wrapper --description "Prepares some environment variables before # Use --function so that it doesn't clobber SHELL outside this function. set -f --export SHELL (command --search fish) - # If FZF_DEFAULT_OPTS is not set, then set some sane defaults. + # If neither FZF_DEFAULT_OPTS nor FZF_DEFAULT_OPTS_FILE are set, then set some sane defaults. # See https://github.com/junegunn/fzf#environment-variables - if not set --query FZF_DEFAULT_OPTS + set --query FZF_DEFAULT_OPTS FZF_DEFAULT_OPTS_FILE + if test $status -eq 2 # cycle allows jumping between the first and last results, making scrolling faster # layout=reverse lists results top to bottom, mimicking the familiar layouts of git log, history, and env # border shows where the fzf window begins and ends diff --git a/config/fish/functions/_puffer_fish_expand_bang.fish b/config/fish/functions/_puffer_fish_expand_bang.fish index abe0bcb..401d85e 100644 --- a/config/fish/functions/_puffer_fish_expand_bang.fish +++ b/config/fish/functions/_puffer_fish_expand_bang.fish @@ -2,7 +2,6 @@ function _puffer_fish_expand_bang switch (commandline -t) case '!' commandline -t $history[1] - commandline -f repaint case '*' commandline -i '!' end diff --git a/config/fish/functions/_puffer_fish_expand_dots.fish b/config/fish/functions/_puffer_fish_expand_dots.fish index 3c240b8..ff82af7 100644 --- a/config/fish/functions/_puffer_fish_expand_dots.fish +++ b/config/fish/functions/_puffer_fish_expand_dots.fish @@ -1,16 +1,9 @@ function _puffer_fish_expand_dots -d 'expand ... to ../.. etc' set -l cmd (commandline --cut-at-cursor) - set -l split (string split ' ' $cmd) - switch $split[-1] - case './*'; commandline --insert '.' - case '*..' - # Only expand if the string consists of dots and slashes. - # We don't want to expand strings like `bazel build target/...`. - if string match --quiet --regex '^[/.]*$' $split[-1] - commandline --insert '/..' - else - commandline --insert '.' - end - case '*'; commandline --insert '.' + set -l split (string split -- ' ' $cmd) + if string match --quiet --regex -- '^(\.\./)*\.\.$' $split[-1] + commandline --insert '/..' + else + commandline --insert '.' end end diff --git a/config/fish/functions/aws.fish b/config/fish/functions/aws.fish deleted file mode 100644 index b8788ed..0000000 --- a/config/fish/functions/aws.fish +++ /dev/null @@ -1,19 +0,0 @@ -function aws -a cmd -d 'Universal CLI for AWS' - switch "$cmd" - case profile - if set -q argv[2] - set -gx AWS_PROFILE "$argv[2]" - else if set -q FILTER - aws profiles | command env $FILTER | read -gx AWS_PROFILE - echo $AWS_PROFILE - else - echo $AWS_PROFILE - end - - case profiles - command sed -n -e 's/^\[\(.*\)\]/\1/p' "$HOME/.aws/credentials" - - case '*' - command aws $argv - end -end diff --git a/config/fish/functions/cdf.fish b/config/fish/functions/cdf.fish deleted file mode 100644 index ae6b1db..0000000 --- a/config/fish/functions/cdf.fish +++ /dev/null @@ -1,3 +0,0 @@ -function cdf -d "cd to the current Finder directory" - cd (pfd) -end diff --git a/config/fish/functions/fisher.fish b/config/fish/functions/fisher.fish index 833b9db..e915cb8 100644 --- a/config/fish/functions/fisher.fish +++ b/config/fish/functions/fisher.fish @@ -1,6 +1,6 @@ function fisher --argument-names cmd --description "A plugin manager for Fish" set --query fisher_path || set --local fisher_path $__fish_config_dir - set --local fisher_version 4.4.3 + set --local fisher_version 4.4.5 set --local fish_plugins $__fish_config_dir/fish_plugins switch "$cmd" @@ -29,7 +29,7 @@ function fisher --argument-names cmd --description "A plugin manager for Fish" set --local old_plugins $_fisher_plugins set --local new_plugins - test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins) + test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins | string replace -- \~ ~) if ! set --query argv[2] if test "$cmd" != update @@ -98,7 +98,7 @@ function fisher --argument-names cmd --description "A plugin manager for Fish" echo Fetching (set_color --underline)\$url(set_color normal) - if command curl --silent -L \$url | command tar -xzC \$temp -f - 2>/dev/null + if command curl -q --silent -L \$url | command tar -xzC \$temp -f - 2>/dev/null command cp -Rf \$temp/*/* $source else echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2 @@ -206,7 +206,7 @@ function fisher --argument-names cmd --description "A plugin manager for Fish" contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin end - printf "%s\n" $commit_plugins >$fish_plugins + string replace --regex -- $HOME \~ $commit_plugins >$fish_plugins else set --erase _fisher_plugins command rm -f $fish_plugins diff --git a/config/fish/functions/flushdns.fish b/config/fish/functions/flushdns.fish deleted file mode 100644 index c543e72..0000000 --- a/config/fish/functions/flushdns.fish +++ /dev/null @@ -1,3 +0,0 @@ -function flushdns -d "Flushes OS X DNS cache" - sudo killall -HUP mDNSResponder -end diff --git a/config/fish/functions/gi.fish b/config/fish/functions/gi.fish deleted file mode 100644 index d1312f1..0000000 --- a/config/fish/functions/gi.fish +++ /dev/null @@ -1,9 +0,0 @@ -function gi -d "gitignore.io cli for fish" - if test $argv[1] = 'update-completions' - __gi_update_completions - return $status - end - - set -l params (echo $argv|tr ' ' ',') - curl -s https://www.gitignore.io/api/$params -end diff --git a/config/fish/functions/git/vcs.branch.fish b/config/fish/functions/git/vcs.branch.fish deleted file mode 100644 index 9535fb1..0000000 --- a/config/fish/functions/git/vcs.branch.fish +++ /dev/null @@ -1,4 +0,0 @@ -function vcs.branch - command git symbolic-ref --short HEAD 2>/dev/null; - or command git show-ref --head -s --abbrev | head -n1 2>/dev/null -end diff --git a/config/fish/functions/git/vcs.conflict.fish b/config/fish/functions/git/vcs.conflict.fish deleted file mode 100644 index 1e16147..0000000 --- a/config/fish/functions/git/vcs.conflict.fish +++ /dev/null @@ -1,10 +0,0 @@ -function vcs.conflict - set -l dot_git_path (git rev-parse --git-dir) - if test -d $dot_git_path/rebase-apply - echo -n 'rebase' - return - # Another option is to list the unmerged files with: git ls-files -u - else if not command git merge HEAD >/dev/null 2>&1 - echo -n 'merge' - end -end diff --git a/config/fish/functions/git/vcs.dirty.fish b/config/fish/functions/git/vcs.dirty.fish deleted file mode 100644 index 9f80d63..0000000 --- a/config/fish/functions/git/vcs.dirty.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.dirty -d "Check if there are changes to tracked files" - not command git diff --no-ext-diff --quiet --exit-code 2>/dev/null -end diff --git a/config/fish/functions/git/vcs.git.present.fish b/config/fish/functions/git/vcs.git.present.fish deleted file mode 100644 index 76185b5..0000000 --- a/config/fish/functions/git/vcs.git.present.fish +++ /dev/null @@ -1,16 +0,0 @@ -function vcs.git.present - type -q git; or return 1 - test -d .git; and return 0 - set -l dir $PWD - - while test "$dir" != "/" - test -d $dir'/.git'; and return 0 - test -f $dir'/.git' - and grep -q gitdir $dir'/.git' - and return 0 - # Go up one directory - set dir (dirname $dir 2>/dev/null) - end - - return 1 -end diff --git a/config/fish/functions/git/vcs.root.fish b/config/fish/functions/git/vcs.root.fish deleted file mode 100644 index 6492857..0000000 --- a/config/fish/functions/git/vcs.root.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.root - command git rev-parse --show-toplevel 2>/dev/null -end diff --git a/config/fish/functions/git/vcs.staged.fish b/config/fish/functions/git/vcs.staged.fish deleted file mode 100644 index 8aae417..0000000 --- a/config/fish/functions/git/vcs.staged.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.staged - not command git diff --cached --no-ext-diff --quiet --exit-code -end diff --git a/config/fish/functions/git/vcs.stashed.fish b/config/fish/functions/git/vcs.stashed.fish deleted file mode 100644 index b4c7005..0000000 --- a/config/fish/functions/git/vcs.stashed.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.stashed - command git rev-parse --verify --quiet refs/stash 2>/dev/null -end diff --git a/config/fish/functions/git/vcs.status.fish b/config/fish/functions/git/vcs.status.fish deleted file mode 100644 index 2648ea9..0000000 --- a/config/fish/functions/git/vcs.status.fish +++ /dev/null @@ -1,33 +0,0 @@ -function vcs.status -a ahead behind diverged detached clean - test -z "$ahead"; and set ahead "ahead" - test -z "$behind"; and set behind "behind" - test -z "$diverged"; and set diverged "diverged" - test -z "$detached"; and set detached "detached" - test -z "$clean"; and set clean "clean" - - set revs (command git rev-list --count --left-right "@{upstream}...HEAD" 2>/dev/null) - - if test "$status" -ne 0 - if not command git symbolic-ref --short HEAD >/dev/null 2>&1 - echo "$detached" - return - end - end - - if test -z "$revs" - return - end - - set remote (echo $revs | cut -f1) - set local (echo $revs | cut -f2) - - if test "$remote" -gt 0 -a "$local" -gt 0 - echo -n "$diverged" - else if test "$remote" -gt 0 - echo -n "$behind" - else if test "$local" -gt 0 - echo -n "$ahead" - else - echo -n "$clean" - end -end diff --git a/config/fish/functions/git/vcs.touched.fish b/config/fish/functions/git/vcs.touched.fish deleted file mode 100644 index 6be1009..0000000 --- a/config/fish/functions/git/vcs.touched.fish +++ /dev/null @@ -1,4 +0,0 @@ -function vcs.touched - not command git diff-index --cached --quiet HEAD -- >/dev/null 2>&1 - or not command git diff --no-ext-diff --quiet --exit-code >/dev/null 2>&1 -end diff --git a/config/fish/functions/hg/vcs.branch.fish b/config/fish/functions/hg/vcs.branch.fish deleted file mode 100644 index 2981426..0000000 --- a/config/fish/functions/hg/vcs.branch.fish +++ /dev/null @@ -1,4 +0,0 @@ -function vcs.branch - cat (vcs.root)/.hg/branch 2>/dev/null; - or echo "default" -end diff --git a/config/fish/functions/hg/vcs.conflict.fish b/config/fish/functions/hg/vcs.conflict.fish deleted file mode 100644 index cd7bd5f..0000000 --- a/config/fish/functions/hg/vcs.conflict.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.conflict - contains 'U' (command hg resolve --list 2>/dev/null | cut -c1 | sort -u) -end diff --git a/config/fish/functions/hg/vcs.dirty.fish b/config/fish/functions/hg/vcs.dirty.fish deleted file mode 100644 index f39eed9..0000000 --- a/config/fish/functions/hg/vcs.dirty.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.dirty - command hg summary 2> /dev/null | command grep -q 'commit: (clean)' 2> /dev/null -end diff --git a/config/fish/functions/hg/vcs.hg.present.fish b/config/fish/functions/hg/vcs.hg.present.fish deleted file mode 100644 index c6e2aa5..0000000 --- a/config/fish/functions/hg/vcs.hg.present.fish +++ /dev/null @@ -1,13 +0,0 @@ -function vcs.hg.present - type -q hg; or return 1 - test -d .hg; and return 0 - set -l dir $PWD - - while test "$dir" != "/" - test -d $dir'/.hg'; and return 0 - # Go up one directory - set dir (dirname $dir 2>/dev/null) - end - - return 1 -end diff --git a/config/fish/functions/hg/vcs.root.fish b/config/fish/functions/hg/vcs.root.fish deleted file mode 100644 index a13bc3c..0000000 --- a/config/fish/functions/hg/vcs.root.fish +++ /dev/null @@ -1,15 +0,0 @@ -function vcs.root - set -l dir $PWD - - while test "$dir" != "/" - if test -d $dir'/.hg' - echo "$dir" - return 0 - end - - # Go up one directory - set dir (dirname $dir 2>/dev/null) - end - - return 1 -end diff --git a/config/fish/functions/hg/vcs.staged.fish b/config/fish/functions/hg/vcs.staged.fish deleted file mode 100644 index 1fd3d50..0000000 --- a/config/fish/functions/hg/vcs.staged.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.staged - contains 'M' (command hg status 2>/dev/null | cut -d' ' -f1 | sort -u) -end diff --git a/config/fish/functions/hg/vcs.stashed.fish b/config/fish/functions/hg/vcs.stashed.fish deleted file mode 100644 index 6ec9951..0000000 --- a/config/fish/functions/hg/vcs.stashed.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.stashed - count (command hg shelve --list 2>/dev/null) >/dev/null -end diff --git a/config/fish/functions/hg/vcs.status.fish b/config/fish/functions/hg/vcs.status.fish deleted file mode 100644 index 8311a73..0000000 --- a/config/fish/functions/hg/vcs.status.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.status - false -end diff --git a/config/fish/functions/hg/vcs.touched.fish b/config/fish/functions/hg/vcs.touched.fish deleted file mode 100644 index 57e0f65..0000000 --- a/config/fish/functions/hg/vcs.touched.fish +++ /dev/null @@ -1,3 +0,0 @@ -function vcs.touched - test -n (echo (command hg status 2>/dev/null)) -end diff --git a/config/fish/functions/itunes.fish b/config/fish/functions/itunes.fish deleted file mode 100644 index d308c4a..0000000 --- a/config/fish/functions/itunes.fish +++ /dev/null @@ -1,31 +0,0 @@ -function itunes -d "Control iTunes. Use -h or --help for a more detailed description." - if [ (count $argv) -gt 0 ] - set -l opt $argv[1] - switch $opt - case launch play pause stop rewind resume quit - case mute - set opt "set mute to true" - case unmute - set opt "set mute to false" - case next previous - set opt "$opt track" - case vol volume - set opt "set sound volume to $argv[2]" - case "" -h --help - echo "Usage: itunes