# Main file for fish command completions. This file contains various
# common helper functions for the command completions. All actual
# completions are located in the completions subdirectory.
#
# Set default field separators
#
set -g IFS \n\ \t
set -qg __fish_added_user_paths
or set -g __fish_added_user_paths

# For one-off upgrades of the fish version, see __fish_config_interactive.fish
if not set -q __fish_initialized
    set -U __fish_initialized 0
    if set -q __fish_init_2_39_8
        set __fish_initialized 2398
    else if set -q __fish_init_2_3_0
        set __fish_initialized 2300
    end
end

#
# Create the default command_not_found handler
#
function __fish_default_command_not_found_handler
    printf "fish: Unknown command: %s\n" (string escape -- $argv[1]) >&2
end

if status --is-interactive
    # Enable truecolor/24-bit support for select terminals
    # Ignore Screen and emacs' ansi-term as they swallow the sequences, rendering the text white.
    if not set -q STY
        and not string match -q -- 'eterm*' $TERM
        and begin
            set -q KONSOLE_PROFILE_NAME # KDE's konsole
            or string match -q -- "*:*" $ITERM_SESSION_ID # Supporting versions of iTerm2 will include a colon here
            or string match -q -- "st-*" $TERM # suckless' st
            or test -n "$VTE_VERSION" -a "$VTE_VERSION" -ge 3600 # Should be all gtk3-vte-based terms after version 3.6.0.0
            or test "$COLORTERM" = truecolor -o "$COLORTERM" = 24bit # slang expects this
        end
        # Only set it if it isn't to allow override by setting to 0
        set -q fish_term24bit
        or set -g fish_term24bit 1
    end
else
    # Hook up the default as the principal command_not_found handler
    # in case we are not interactive
    function __fish_command_not_found_handler --on-event fish_command_not_found
        __fish_default_command_not_found_handler $argv
    end
end

#
# Set default search paths for completions and shellscript functions
# unless they already exist
#

# __fish_data_dir, __fish_sysconf_dir, __fish_help_dir, __fish_bin_dir
# are expected to have been set up by read_init from fish.cpp

# Grab extra directories (as specified by the build process, usually for
# third-party packages to ship completions &c.
set -l __extra_completionsdir
set -l __extra_functionsdir
set -l __extra_confdir
if test -f $__fish_data_dir/__fish_build_paths.fish
    source $__fish_data_dir/__fish_build_paths.fish
end

# Compute the directories for vendor configuration.  We want to include
# all of XDG_DATA_DIRS, as well as the __extra_* dirs defined above.
set -l xdg_data_dirs
if set -q XDG_DATA_DIRS
    set --path xdg_data_dirs $XDG_DATA_DIRS
    set xdg_data_dirs (string replace -r '([^/])/$' '$1' -- $xdg_data_dirs)/fish
else
    set xdg_data_dirs $__fish_data_dir
end

set -l vendor_completionsdirs $xdg_data_dirs/vendor_completions.d
set -l vendor_functionsdirs $xdg_data_dirs/vendor_functions.d
set -l vendor_confdirs $xdg_data_dirs/vendor_conf.d

# Ensure that extra directories are always included.
if not contains -- $__extra_completionsdir $vendor_completionsdirs
    set -a vendor_completionsdirs $__extra_completionsdir
end
if not contains -- $__extra_functionsdir $vendor_functionsdirs
    set -a vendor_functionsdirs $__extra_functionsdir
end
if not contains -- $__extra_confdir $vendor_confdirs
    set -a vendor_confdirs $__extra_confdir
end

# Set up function and completion paths. Make sure that the fish
# default functions/completions are included in the respective path.

if not set -q fish_function_path
    set fish_function_path $__fish_config_dir/functions $__fish_sysconf_dir/functions $vendor_functionsdirs $__fish_data_dir/functions
else if not contains -- $__fish_data_dir/functions $fish_function_path
    set -a fish_function_path $__fish_data_dir/functions
end

if not set -q fish_complete_path
    set fish_complete_path $__fish_config_dir/completions $__fish_sysconf_dir/completions $vendor_completionsdirs $__fish_data_dir/completions $__fish_user_data_dir/generated_completions
else if not contains -- $__fish_data_dir/completions $fish_complete_path
    set -a fish_complete_path $__fish_data_dir/completions
end

# This cannot be in an autoload-file because `:.fish` is an invalid filename on windows.
function : -d "no-op function"
    # for compatibility with sh, bash, and others.
    # Often used to insert a comment into a chain of commands without having
    # it eat up the remainder of the line, handy in Makefiles.
    # This command always succeeds
    true
end

#
# This is a Solaris-specific test to modify the PATH so that
# Posix-conformant tools are used by default. It is separate from the
# other PATH code because this directory needs to be prepended, not
# appended, since it contains POSIX-compliant replacements for various
# system utilities.
#

if begin; not set -q FISH_UNIT_TESTS_RUNNING; and test -d /usr/xpg4/bin; end
    not contains -- /usr/xpg4/bin $PATH
    and set PATH /usr/xpg4/bin $PATH
end

# Add a handler for when fish_user_path changes, so we can apply the same changes to PATH
function __fish_reconstruct_path -d "Update PATH when fish_user_paths changes" --on-variable fish_user_paths
    set -l local_path $PATH

    for x in $__fish_added_user_paths
        set -l idx (contains --index -- $x $local_path)
        and set -e local_path[$idx]
    end

    set -g __fish_added_user_paths
    if set -q fish_user_paths
        # Explicitly split on ":" because $fish_user_paths might not be a path variable,
        # but $PATH definitely is.
        for x in (string split ":" -- $fish_user_paths[-1..1])
            if set -l idx (contains --index -- $x $local_path)
                set -e local_path[$idx]
            else
                set -ga __fish_added_user_paths $x
            end
            set -p local_path $x
        end
    end

    set -xg PATH $local_path
end

#
# Launch debugger on SIGTRAP
#
function fish_sigtrap_handler --on-signal TRAP --no-scope-shadowing --description "Signal handler for the TRAP signal. Launches a debug prompt."
    breakpoint
end

#
# Whenever a prompt is displayed, make sure that interactive
# mode-specific initializations have been performed.
# This handler removes itself after it is first called.
#
function __fish_on_interactive --on-event fish_prompt
    __fish_config_interactive
    functions -e __fish_on_interactive
end

# Set the locale if it isn't explicitly set. Allowing the lack of locale env vars to imply the
# C/POSIX locale causes too many problems. Do this before reading the snippets because they might be
# in UTF-8 (with non-ASCII characters).
__fish_set_locale

# "." alias for source; deprecated
function . -d 'Evaluate a file (deprecated, use "source")' --no-scope-shadowing --wraps source
    if [ (count $argv) -eq 0 ] && isatty 0
        echo "source: using source via '.' is deprecated, and stdin doesn't work."\n"Did you mean 'source' or './'?" >&2
        return 1
    else
        source $argv
    end
end

# Upgrade pre-existing abbreviations from the old "key=value" to the new "key value" syntax.
# This needs to be in share/config.fish because __fish_config_interactive is called after sourcing
# config.fish, which might contain abbr calls.
if test $__fish_initialized -lt 2300
    if set -q fish_user_abbreviations
        set -l fab
        for abbr in $fish_user_abbreviations
            set -a fab (string replace -r '^([^ =]+)=(.*)$' '$1 $2' -- $abbr)
        end
        set fish_user_abbreviations $fab
    end
end

#
# Some things should only be done for login terminals
# This used to be in etc/config.fish - keep it here to keep the semantics
#
if status --is-login
    if command -sq /usr/libexec/path_helper
        # Adapt construct_path from the macOS /usr/libexec/path_helper
        # executable for fish; see
        # https://opensource.apple.com/source/shell_cmds/shell_cmds-203/path_helper/path_helper.c.auto.html .
        function __fish_macos_set_env -d "set an environment variable like path_helper does (macOS only)"
            set -l result

            # Populate path according to config files
            for path_file in $argv[2] $argv[3]/*
                if [ -f $path_file ]
                    while read -l entry
                        if not contains -- $entry $result
                            test -n "$entry"
                            and set -a result $entry
                        end
                    end <$path_file
                end
            end

            # Merge in any existing path elements
            for existing_entry in $$argv[1]
                if not contains -- $existing_entry $result
                    set -a result $existing_entry
                end
            end

            set -xg $argv[1] $result
        end

        __fish_macos_set_env 'PATH' '/etc/paths' '/etc/paths.d'
        if [ -n "$MANPATH" ]
            __fish_macos_set_env 'MANPATH' '/etc/manpaths' '/etc/manpaths.d'
        end
        functions -e __fish_macos_set_env
    end

    #
    # Put linux consoles in unicode mode.
    #
    if test "$TERM" = linux
        and string match -qir '\.UTF' -- $LANG
        and command -sq unicode_start
        unicode_start
    end
end

# Invoke this here to apply the current value of fish_user_path after
# PATH is possibly set above.
__fish_reconstruct_path

# Allow %n job expansion to be used with fg/bg/wait
# `jobs` is the only one that natively supports job expansion
function __fish_expand_pid_args
    for arg in $argv
        if string match -qr '^%\d+$' -- $arg
            # set newargv $newargv (jobs -p $arg)
            jobs -p $arg
            if not test $status -eq 0
                return 1
            end
        else
            printf "%s\n" $arg
        end
    end
end

for jobbltn in bg fg wait disown
    function $jobbltn -V jobbltn
        builtin $jobbltn (__fish_expand_pid_args $argv)
    end
end

function kill
    command kill (__fish_expand_pid_args $argv)
end

# As last part of initialization, source the conf directories.
# Implement precedence (User > Admin > Extra (e.g. vendors) > Fish) by basically doing "basename".
set -l sourcelist
for file in $__fish_config_dir/conf.d/*.fish $__fish_sysconf_dir/conf.d/*.fish $vendor_confdirs/*.fish
    set -l basename (string replace -r '^.*/' '' -- $file)
    contains -- $basename $sourcelist
    and continue
    set sourcelist $sourcelist $basename
    # Also skip non-files or unreadable files.
    # This allows one to use e.g. symlinks to /dev/null to "mask" something (like in systemd).
    [ -f $file -a -r $file ]
    and source $file
end

# zero

set fish_greeting

set fish_color_normal foreground
set fish_color_command white
set fish_color_keyword brblack
set fish_color_quote foreground
set fish_color_redirection foreground
set fish_color_end brblack
set fish_color_error yellow
set fish_color_param foreground
set fish_color_valid_path white
set fish_color_option white
set fish_color_comment brblue
set fish_color_selection -b brblack  # only sets the background
set fish_color_operator brblack
set fish_color_escape brblack
set fish_color_autosuggestion brcyan
set fish_color_cwd brblack
set fish_color_cwd_root brblack
set fish_color_user cyan
set fish_color_host brblack
set fish_color_host_remote cyan
set fish_color_status red
set fish_color_cancel brred
set fish_color_search_match brcyan -b cyan

# git

# set -g __fish_git_prompt_color_dirty yellow
# set -g __fish_git_prompt_color_untracked green
# set -g __fish_git_prompt_color_unstagedchanges cyan
# set -g __fish_git_prompt_color_stashstate blue
# set -g __fish_git_prompt_color_upstream_ahead red
# set -g __fish_git_prompt_color_upstream_behind brwhite
# set -g __fish_git_prompt_color yellow
# set -g __fish_git_prompt_color_prefix black
# set -g __fish_git_prompt_color_suffix black

set -g __fish_git_prompt_showunstagedchanges yes
# set -g __fish_git_prompt_show_informative_status yes
# set -g __fish_git_prompt_use_informative_chars yes
set -g __fish_git_prompt_char_stateseparator ' '
set -g __fish_git_prompt_showdirtystate yes
set -g __fish_git_prompt_showuntrackedfiles yes
set -g __fish_git_prompt_showupstream informative
set -g __fish_git_prompt_showstashstate yes
# set -g __fish_git_prompt_showcolorhints yes

# prompt

set -g fish_prompt_pwd_dir_length 1
set -g fish_prompt_pwd_full_dirs 1

function fish_prompt

   set -l s $status

   if test $s -ne 0
      set_color $fish_color_status
      echo -n $s" "
   end

   if set -q SSH_CLIENT
      if test $USER != "zero"
         set_color $fish_color_user
         echo -n $USER
         echo -n "@"
      end
      set_color $fish_color_host_remote
      echo -n $hostname
      echo -n " "
   else
      if test $USER != "zero"
         set_color $fish_color_host
         echo -n $USER
         echo -n " "
      end
   end

   set_color $fish_color_cwd
   echo -n (prompt_pwd)
   echo -n " "

   # darcs
   set -l dp (fish_darcs_prompt)
   if string length --visible -q $dp
      set_color green
      echo -n $dp
      echo -n " "
   end

   # pijul
   set -l pp (fish_pijul_prompt)
   if string length --visible -q $pp
      set_color blue
      echo -n $pp
      echo -n " "
   end

   # git
   set -l gp (fish_git_prompt)
   set -l gp (string replace --regex '\(' '' $gp)
   set -l gp (string replace --regex '\)' '' $gp)
   set -l gp (string replace --regex '\s' '' $gp)
   if string length --visible -q $gp
      set_color bryellow
      echo -n $gp
      echo -n " "
   end

end

function fish_pijul_prompt
   if not command -q pijul
      return
   end
   if not pijul list &>/dev/null
      return
   end
   # get channel
   echo -n (pijul channel | rg '^\* (.+)' -r '$1')
   echo -n " "
   # get status
   set -l pijul_status (pijul diff -su)
   if test -z "$pijul_status"
      echo -n "."
      return
   end
   if echo "$pijul_status" | rg -q '^.C '
      echo -n "!"
   end
   if echo "$pijul_status" | rg -q '^U '
      echo -n ":"
   end
   if echo "$pijul_status" | rg -q '^D '
      echo -n "-"
   end
   if echo "$pijul_status" | rg -q '^A '
      echo -n "+"
   end
   if echo "$pijul_status" | rg -q '^M |^MV |^R |^UD '
      echo -n "*"
   end
   if echo "$pijul_status" | rg -q '^RZ'
      echo -n "z"
   end
end

function fish_darcs_prompt
   if not command -q darcs
      return
   end
   if not darcs show repo &>/dev/null
      return
   end
   # get status
   set -l darcs_status (darcs whatsnew -lsq)
   if test $status -ne 0
      echo -n "."
      return
   end
   if echo "$darcs_status" | rg -q '^.! '
      echo -n "!"
   end
   if echo "$darcs_status" | rg -q '^a '
      echo -n ":"
   end
   if echo "$darcs_status" | rg -q '^R '
      echo -n "-"
   end
   if echo "$darcs_status" | rg -q '^A '
      echo -n "+"
   end
   if echo "$darcs_status" | rg -q '^M | -> '
      echo -n "*"
   end
end

function fish_right_prompt
  switch $fish_bind_mode
    case default
    case insert
    case replace_one
    case replace
      set_color -o cyan
      echo 'R'
    case visual
      set_color -o cyan
      echo 'v'
    case '*'
      set_color black -o -b red
      echo '?'
  end
  set_color normal
end

function fish_mode_prompt
end

# vi mode

set -g fish_key_bindings fish_vi_key_bindings

# fish

bind U redo
bind -M insert tab forward-word
bind -M insert shift-tab accept-autosuggestion

set fish_cursor_default block blink
set fish_cursor_insert line blink
set fish_cursor_replace underscore blink
set fish_cursor_replace_one underscore blink
set fish_cursor_external underscore blink
set fish_cursor_visual block blink

set -g fish_vi_force_cursor 1

bind \cg 'clear; git diff; commandline -f repaint'

set -gx PAGER less -R
set -gx VISUAL vim
set -gx EDITOR vim

set -gx LS_COLORS 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'

set -gx DARCS_ALWAYS_COLOR 1

#set -gx FZF_DEFAULT_COMMAND 'fd --type file --hidden --no-ignore'  # fzf now has a built-in walker
set -gx FZF_DEFAULT_OPTS '--no-height'

set -gx FZF_CTRL_T_COMMAND ''
set -gx FZF_CTRL_T_OPTS '--preview \'cat {}\''

set -gx FZF_ALT_C_COMMAND ''
set -gx FZF_ALT_C_OPTS '--preview \'tree -L 1 -C {}\''

# fzf shell integration
fzf --fish | source

set -gx id ~/.ssh/jrvieira_rsa

# aliases

# provide alias expansion
alias sudo='sudo '

alias vi='vim'

function bang
 echo (string split --max 1 " " $history[1])[2]
end

function bangbang
 echo $history[1]
end

abbr -a !! --position anywhere --function bangbang
abbr -a ! --position anywhere --function bang

abbr -a -g tunnelout autossh -f -nNT -R 9700:localhost:22
abbr -a -g untunnelout killall autossh
abbr -a -g tunnelin ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 9700 localhost

abbr -a -g r trash put
abbr -a -g mv mv -vi
abbr -a -g cp cp -vipr
abbr -a -g e $EDITOR
abbr -a -g p $PAGER
abbr -a -g yt ytfzf --detach --ytdl-path=/usr/bin/yt-dlp
abbr -a -g m sshfs -o allow_other
# abbr -a -g hi killall xflux; redshift -x
# abbr -a -g lo killall xflux; redshift -O 2000
abbr -a -g hi redshift -x
abbr -a -g lo redshift -O 2000
abbr -a -g g googler
abbr -a -g www w3m -N duckduckgo.com read.jrvieira.com/quote
if test -n "$WAYLAND_DISPLAY"
  abbr -a -g v swayimg
else
# abbr -a -g v feh -xdN -B black -R 1 --keep-zoom-vp --force-aliasing -e 'yudit/8'
  abbr -a -g v nsxiv -tb
end
abbr -a -g ascii ascii-image-converter -Cc
abbr -a -g za fzf --preview '"ascii-image-converter -Cc -W 119 {}"'
abbr -a -g watch watch --color --interval=0.1

abbr -a -g gl git log --stat
abbr -a -g gh git log -c
abbr -a -g gg git log --graph --all --oneline --decorate
abbr -a -g gs git status -sb
abbr -a -g gd git diff --histogram -U1 --ignore-space-at-eol
abbr -a -g gc --set-cursor "git commit -m \"%\""
abbr -a -g gb git branch
abbr -a -g go git checkout
abbr -a -g ga --set-cursor "git pull && git add -A && git commit -a -m \"%\" && git push"
abbr -a -g gu --set-cursor "git pull && git add -u && git commit -a -m \"%\" && git push"

abbr -a -g f --set-cursor "rg -uu --no-messages -C3 --color=always % &| less -R"
# abbr -a -g d vim -d
abbr -a -g o watch -ctd -n 0.1
abbr -a -g oi watch -ctd -n
# abbr -a -g con (basename -z "$(command -s kitten)") ssh -i '$id'
abbr -a -g otp --set-cursor "cloak view % | wl-copy"

function d
   difft --color always --display side-by-side-show-both $argv &| less -R
end

function vs -a path
   set -l error 0
   set -l repo_git
   set -l repo_pijul
   set -l repo_darcs
   if test -n "$path"
      set repo_git -C "$path"
      set repo_pijul --repository="$path"
      set repo_darcs --repodir="$path"
   end
   #git sync
   if git $repo_git rev-parse --git-dir &>/dev/null
      echo (set_color bryellow)"vs git"(set_color normal)
      git $repo_git pull
      and git $repo_git add -u
      and begin
         if not git $repo_git diff --cached --quiet
            git $repo_git commit -m "vs"
         end
      end
      and git $repo_git push
      or set error 1
   end
   # pijul sync
   if pijul list $repo_pijul &>/dev/null
      echo (set_color blue)"vs pijul"(set_color normal)
      pijul pull -a $repo_pijul
      and pijul record -a -m "vs" $repo_pijul
      and pijul push -a $repo_pijul
      or set error 1
   end
   # darcs sync
   if darcs show repo $repo_darcs &>/dev/null
      echo (set_color green)"vs darcs"(set_color normal)
      darcs pull -av $repo_darcs
      and begin
         if darcs whatsnew $repo_darcs &>/dev/null
            darcs record -av -m "vs" $repo_darcs
         end
      end
      and darcs push -av $repo_darcs
      or set error 1
   end
   # exit
   return $error
end

function dot
 # sync when run with no arguments
 if test (count $argv) -eq 0
    vs $HOME/dot
 end
 # link
 for link in $argv
  if not string match -q '/*' $link
   echo "error: '$link' must be an absolute path" >&2
   return 1
  end
  if test -e $link
   echo "error: destination '$link' already exists" >&2
   return 1
  end
  if not test -e $HOME/dot$link
   echo "error: source '$HOME/dot$link' does not exist" >&2
   return 1
  end
 end
 for link in $argv
  ln -sf (realpath $HOME/dot$link) $link
  or return 1
  echo "dot $link"
 end
end

function con
 if test -z "$SSH_TTY"; and test "$TERM" = "xterm-kitty"
  kitten ssh -t -i $id $USER@$argv[1] $argv[2..]
 else
  ssh -t -i $id $USER@$argv[1] $argv[2..]
 end
end

function lnetp
 ip route | rg -o 'proto kernel scope link src ((\d+\.){3})' -r '$1'
end

abbr -a -g lan --set-cursor con (lnetp)%

# bittorrent
abbr -a -g tt transmission-tui
abbr -a -g bt --set-cursor 'transmission-remote -a \'%\' && transmission-tui'
abbr -a -g lbt --set-cursor ssh -t -i '$id' zero@(lnetp)100 '"transmission-remote -a \'%\' -w /media/share && transmission-tui"'
abbr -a -g sbt --set-cursor ssh -t -i '$id' zero@ssh.jrvieira.com '"transmission-remote -a \'%\' -w /media/share && transmission-tui"'

# package management

if command -q nala
 abbr -a -g i 'sudo nala install'
 abbr -a -g s 'nala search'
 function up
  sudo nala upgrade
  up_containers
 end
else if command -q apt
 abbr -a -g i 'sudo apt install'
 abbr -a -g s 'apt search'
 function up
  sudo apt update && sudo apt full-upgrade
  up_containers
 end
else if command -q xbps-install
 abbr -a -g i 'sudo xbps-install -S'
 abbr -a -g s 'xbps-query -Rs'
 function up
  sudo xbps-install -Su xbps && sudo xbps-install -u
  up_containers
 end
else if command -q pacman
 abbr -a -g i 'sudo pacman -S'
 abbr -a -g s 'pacman -Ss'
 function up
  sudo pacman -Syu
  set orphans (pacman -Qtdq)
  if test -n "$orphans"
   sudo pacman -Rs $orphans
  end
  up_containers
 end
end

function up_containers
 if command -q flatpak
  echo "flatpak update"
  sudo flatpak update
  sudo flatpak uninstall --unused
 end
 if command -q snap
  echo "snap update"
  sudo snap refresh
 end
end

function sn -a name
 if set -q DTACH; and test -e /tmp/dtach/"$DTACH"
  echo "session nesting not allowed"
  return 1
 end
 if test -z "$argv"
  echo "no session name"
  return 1
 else
  set -l cmd $argv[2..]
  if test -z "$cmd"
   set cmd $SHELL
  end
  mkdir /tmp/dtach
  dtach -c /tmp/dtach/"$name" env DTACH="$name" $cmd
 end
end

function sl
 ls /tmp/dtach | while read -l sess
  if string match -q "$DTACH" "$sess"
   echo "* $sess"
  else
   echo "  $sess"
  end
 end
end

function sa
 if set -q DTACH
  echo "session nesting not allowed"
  return 1
 end
 if test -z "$argv"
  echo "no session name"
  return 1
 else
  dtach -a /tmp/dtach/"$argv" -r winch
 end
end

function sr
 rm /tmp/dtach/$argv
end

function zs
 if set -q DTACH
  echo "session nesting not allowed"
 else if test -z (ls /tmp/dtach)
  echo "no sessions"
 else
  dtach -a /tmp/dtach/(ls /tmp/dtach | fzf) -r winch
 end
end

function l -a path
 clear
#exa -F -x -s type --color-scale $path
 ls -FhXv --color=auto --group-directories-first $argv
end

function la -a path
 clear
#exa -a -F -x -s type --color-scale $path
 ls -FhXvA --color=auto --group-directories-first $argv
end

function ll -a path
#exa -l -F -s type --color-scale $path
 ls -lFhXv --color=auto --group-directories-first $argv
end

function lla -a path
#exa -l -F -s type --color-scale $path
 ls -lFhXvA --color=auto --group-directories-first $argv
end

function x
 if test -n "$argv"
  cd $argv
 end
 set -l dir (vifm --choose-dir - . .)
 clear
 cd $dir
end

function h -a regex
 clear
 if test -z "$regex"
  history --show-time="%Y-%m-%d %H:%M "
 else
  history --show-time="%Y-%m-%d %H:%M " | rg "$regex"
 end
end

# find whatever
function Z
 fd -u | fzf | string split : -f1
end

# find file
function ZF
 #find . -type f -print -o -type l -print 2> /dev/null | sed s/^..// | fzf --multi --preview 'cat {}'
 fd -u -t f -t l -t b -t c -t s -t p | fzf --multi --preview 'cat {}'
end

# find directory
function ZD
 fd -u -t d | fzf --preview 'tree -L 1 -C {}'
end

# find file by content
function ZV
 rg -uu --no-messages -S --hidden -q . | fzf | string split : -f1
end

# fzf whatever
function z -a cmd
 if test -n "$cmd"
  $cmd (Z)
 else
  open (Z)
 end
 clear
end

# fzf file
function zf -a cmd
 if test -n "$cmd"
  $cmd (ZF)
 else
  open (ZF)
 end
 clear
end

# fzf directory
function zd -a cmd
 if test -n "$cmd"
  $cmd (ZD)
 else
  cd (ZD)
 end
end

# fzf firectory > x
abbr -a -g zx zd x

# fzf file by content
function zv -a cmd
 set -l file (ZV)
 if test -n "$file"
  if test -n "$cmd"
   $cmd "$file"
  else
   open "$file"
  end
 else
 end
end

# same but argument is root path instead of command

# fzf whatever
function q -a path
 if test -n "$path"
  cd $path
 else
  cd /
 end
 x (dirname (Z))
end

# fzf file
function qf -a path
 if test -n "$path"
  cd $path
 else
  cd /
 end
 x (dirname (ZF))
end

# fzf directory
function qd -a path
 if test -n "$path"
  cd $path
 else
  cd /
 end
 x (ZD)
end

# fzf file by content
function qv -a path
 if test -n "$path"
  cd $path
 else
  cd /
 end
 set -l file (ZV)
 if test -n "$file"
   x (dirname $file)
 end
end

# tree level
function t -a level
 clear
 set -l dir $argv[2..]
 if test -n "$level"; and test -n "$dir"
  tree -L $level $dir
 else if test -n "$level"
  tree -L $level .
 else
  tree .
 end
end

function extract
 if test -z "$argv[1]"
  # display usage if no parameters given
  echo 'Usage: extract <path/file_name>.<zip|rar|bz2|gz|tar|tbz2|tgz|Z|7z|xz|ex|tar.bz2|tar.gz|tar.xz>'
 else
  if test -e "$argv[1]"
   switch "$argv[1]"
    case '*.tar.bz2'
     tar xvjf ./$argv[1]
    case '*.tar.gz'
     tar xvzf ./$argv[1]
    case '*.tar.xz'
     tar xvJf ./$argv[1]
    case '*.lzma'
     unlzma ./$argv[1]
    case '*.bz2'
     bunzip2 ./$argv[1]
    case '*.rar'
     unrar x -ad ./$argv[1]
    case '*.gz'
     gunzip ./$argv[1]
    case '*.tar'
     tar xvf ./$argv[1]
    case '*.tbz2'
     tar xvjf ./$argv[1]
    case '*.tgz'
     tar xvzf ./$argv[1]
    case '*.zip'
     unzip ./$argv[1]
    case '*.Z'
     uncompress ./$argv[1]
    case '*.7z'
     7z x ./$argv[1]
    case '*.xz'
     unxz ./$argv[1]
    case '*.exe'
     cabextract ./$argv[1]
    case '*'
     echo "extract: $argv[1] - unknown archive method"
    end
  else
   echo "$argv[1] - file does not exist"
  end
 end
end

function xtr
 extract $argv && rm -f $argv
end

function paste
 function write
  if test -n "$WAYLAND_DISPLAY"
   echo -n $argv[1] | wl-copy ; echo $argv[1]
  else
   echo -n $argv[1] | xclip -sel clip ; echo $argv[1]
  end
 end
 write (curl -s -X POST -H 'Content-Type: text/plain' --data-binary "@$argv" https://paste.jrvieira.com/paste)
end

function shot
 if test -n "$WAYLAND_DISPLAY"
  grim -g "$(slurp -w 0)" - | curl -s -F "image=@-;filename=$(date +%s).png" https://shot.jrvieira.com/shot
 else
  function write
   echo -n $argv[1] | xclip -sel clip && echo $argv[1]
  end
  set -l file "$HOME/$(date +%s).png"
  maim -s -u --quality=10 "$file" && write (curl -s -F "image=@$file" https://shot.jrvieira.com/shot) && rm $file
 end
end

function grab
 if test -n "$WAYLAND_DISPLAY"
  grim -g "$(slurp -w 0)" - | wl-copy
 else
  maim -s -u --quality=10 | xclip -selection clipboard -t image/png
 end
end

function reco
 if test -n "$WAYLAND_DISPLAY"
  wf-recorder --audio=@DEFAULT_SINK@.monitor -g "$(slurp)" -f "$HOME/shot/reco $(date +'%Y-%m-%d %H-%M-%S').mp4"
 else
  set sel (slop -f '%x %y %w %h')
  set -l X (echo $sel | cut -d' ' -f1)
  set -l Y (echo $sel | cut -d' ' -f2)
  set -l W (echo $sel | cut -d' ' -f3)
  set -l H (echo $sel | cut -d' ' -f4)
  set -l file "$HOME/shot/reco $(date +'%Y-%m-%d %H-%M-%S').mp4"
  ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+"$X,$Y" -f pulse -i @DEFAULT_SINK@.monitor "$file"
 end
end

function mail
   echo ''
   read -l -P 'from: (@jrvieira.com) ' from_address
   read -l -P 'to: ' to_address
   read -l -P 'subject: ' subject
   echo ''
   read -l lines
   echo ''
   read -l -P 'send? (y/N) ' y
   if test "$y" = 'y'

      set temp_file (mktemp)
      echo "$lines" > "$temp_file"
      curl --request POST \
         --url https://api.mailgun.net/v3/jrvieira.com/messages \
         --header "Authorization: Basic $(cat ~/secret/mailgun-api.txt)" \
         --header "content-type: multipart/form-data" \
         --form from="jrvieira <$from_address@jrvieira.com>" \
         --form to="$to_address" \
         --form subject="$subject" \
         --form text="<$temp_file"
      rm "$temp_file"

   else
      echo 'cancelled'
   end

end

# coda

function scm -a file
 if test -d "$PWD/.akku"
  .akku/env -f | source
 end
 if test -z "$file"
  set file (ls | rg -u -e "$(basename $PWD)\.\(sls\|scm\|sps\|sld\|ss\|sc\|sch\|sps7\|.*\)\$" | head -n 1)
  echo "\nfound $file"
 end
 if test -n "$file"
  fd -u | entr -cr scheme -q --optimize-level 2 --program $file
 else
  echo "no source"
 end
end

function hs
 ghcid --color=always --warnings --no-status --run --test-message="
" --clear --no-height-limit $argv
end

function haskell -a file
 ghc $file -O2 -threaded -Wall -fforce-recomp -fdiagnostics-color=always -j -no-keep-hi-files -no-keep-o-files && echo "compiled (O2, threaded)" && echo "running..." && ./$file
end

function idr
 fd -u $argv | entr -cr idris2 -x main $argv
end

# detached sessions

# auto create a "main" session if inexistent
if not set -q DTACH; and not status --is-login; and status --is-interactive; and not test -e /tmp/dtach/main
   mkdir -p /tmp/dtach
   dtach -c /tmp/dtach/main env DTACH=main fish
end

# # start wm
#
# function wm
#
#    # disable on non login shells and remote
#    if not status --is-login; or set -q SSH_CLIENT SSH_TTY
#       echo "can't run here" >&2
#       return 1
#    end
#
#    # populate list
#    set -l sessions
#    for f in /usr/share/{wayland-,x}sessions/*.desktop
#       rg -q "^NoDisplay=true" $f; and continue
#       set bin (grep -m1 "^Exec=" $f | cut -d= -f2- | string split " ")[1]
#       command -q $bin; or continue
#       set -a sessions (string join \t (grep -m1 "^Name=" $f | cut -d= -f2-) $f)
#    end
#
#    # last first
#    if not set -q sessions[1]
#       echo "no wm found"
#       return
#    end
#    set -l ordered
#    for s in $sessions
#       if test (string split \t $s)[1] = "$wm_last"
#          set -p ordered $s
#       else
#          set -a ordered $s
#       end
#    end
#
#    # run
#    set sel (string join \n $ordered | fzf --with-nth=1 --delimiter=\t --inline-info)
#    if test -z "$sel"
#       echo "no wm selected"
#       return
#    else
#       set -U wm_last (string split \t $sel)[1]
#    end
#    set -l cmd (grep -m1 "^Exec=" (string split \t $sel)[2] | cut -d= -f2- | string split -n " ")
#    exec $cmd
#
# end
#
# if status --is-login; and not set -q SSH_CLIENT SSH_TTY
#
#    # display v
#    cat ~/.jrvieira/v.txt
#
#    # check dependencies
#    set -l missing
#    for dep in fzf rg
#       command -q $dep
#       or set -a missing $dep
#    end
#    if set -q missing[1]
#       echo "missing: $missing!" >&2
#       return 1
#    end
#
#    # greet
#    wm
#
# end

# user env

# remote clipboard
set -x CLIPBOARD_NOGUI 1

# runit user services dir
set -gx SVDIR $HOME/.config/service

# local bin
set -gx PATH $HOME/.local/bin $PATH

# hledger
set -gx LEDGER_FILE $HOME/finance/main.journal

# ghcup
set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX $HOME ; set -gx PATH $HOME/.cabal/bin $PATH /home/zero/.ghcup/bin # ghcup-env