set PATH {$HOME}/.nix-profile/bin {$HOME}/.cargo/bin {$HOME}/.cabal/bin {$HOME}/.local/bin $PATH
set -gx TERM xterm-kitty
set -gx NIX_PATH {$HOME}/.nix-defexpr/channels

# https://github.com/fish-shell/fish-shell/issues/5593
bind \cd true

export MANPAGER='nvim +Man!'
export NIX_SSL_CERT_FILE='/etc/ssl/certs/ca-certificates.crt'

if [ -n "$NVIM_LISTEN_ADDRESS" ]
  export VISUAL="nvr"
  export EDITOR="nvr"
else
  export VISUAL="nvim"
  export EDITOR="nvim"
end

alias b="cd .."
alias c="clear"
alias v="nvim"
alias vc="nvim --clean"
alias vn="nvim -u NONE"
alias vnrc="nvim -u NORC"
alias vnp="nvim --noplugin"
alias tksa="tmux kill-session -a"
alias tks="tmux kill-server"
alias tat="tmux attach -t "
alias tls="tmux ls"
alias vf="v (fzf)"
alias cs="cscope -bqR"
alias cat="bat"
alias t="tokei ."
alias gst="gst-inspect-1.0"
alias gsl="gst-launch-1.0"
alias sds="systemctl status "
alias sde="systemctl enable "
alias sdd="systemctl disable "
alias sfc="source ~/.config/fish/config.fish"
alias icat="kitty +kitten icat (fzf)"
alias jb="journalctl -b"
alias jbl="journalctl --list-boots"
alias jf="journalctl -f"
alias jk="journalctl -r -k"
alias jr="journalctl -r"
alias ju="journalctl -u"
alias jx="journalctl -xe"

# emacs org
alias e="emacsclient"
alias ej="emacsclient ~/org/journal.org"
alias en="emacsclient ~/org/notes.org"
alias ep="emacsclient ~/org/projects.org"
alias et="emacsclient ~/org/todo.org"

# Git helpers
alias vg="vgrep"
alias vs="vgrep -s"

# Open fugitive with nvim directly
alias gn="nvim +Git +only"

# Branch (b)
alias gb='git branch'
alias gba='git branch --all --verbose'
alias gbc='git checkout -b'
alias gbd='git branch --delete'
alias gbD='git branch --delete --force'
alias gbl='git branch --verbose'
alias gbL='git branch --all --verbose'
alias gbm='git branch --move'
alias gbM='git branch --move --force'
alias gbr='git branch --move'
alias gbR='git branch --move --force'
alias gbs='git show-branch'
alias gbS='git show-branch --all'
alias gbv='git branch --verbose'
alias gbV='git branch --verbose --verbose'
alias gbx='git branch --delete'
alias gbX='git branch --delete --force'

# Commit (c)
alias gc='git commit --verbose'
alias gca='git commit --verbose --all'
alias gcm='git commit --message'
alias gcS='git commit -s --verbose'
alias gcSa='git commit -s --verbose --all'
alias gcSm='git commit -s --message'
alias gcam='git commit --all --message'
alias gco='git checkout'
alias gcO='git checkout --patch'
alias gcf='git commit --amend --reuse-message HEAD'
alias gcSf='git commit -S --amend --reuse-message HEAD'
alias gcF='git commit --verbose --amend'
alias gcSF='git commit -S --verbose --amend'
alias gcp='git cherry-pick --ff'
alias gcP='git cherry-pick --no-commit'
alias gcr='git revert'
alias gcR='git reset HEAD^'
alias gcs='git show'
alias gcsS='git show --pretty=short --show-signature'
alias gcl='git-commit-lost'
alias gcy='git cherry -v --abbrev'
alias gcY='git cherry -v'

# Conflict (C)
alias gCl='git --no-pager diff --name-only --diff-filter=U'
alias gCa='git add (gCl)'
alias gCe='git mergetool (gCl)'
alias gCo='git checkout --ours --'
alias gCO='gCo (gCl)'
alias gCt='git checkout --theirs --'
alias gCT='gCt (gCl)'

# Data (d)
alias gd='git ls-files'
alias gdc='git ls-files --cached'
alias gdx='git ls-files --deleted'
alias gdm='git ls-files --modified'
alias gdu='git ls-files --other --exclude-standard'
alias gdk='git ls-files --killed'

# Fetch (f)
alias gf='git fetch'
alias gfa='git fetch --all'
alias gfc='git clone'
alias gfcr='git clone --recurse-submodules'
alias gfm='git pull'
alias gfr='git pull --rebase'

# Grep (g)
alias gg='git grep'
alias ggi='git grep --ignore-case'
alias ggl='git grep --files-with-matches'
alias ggL='git grep --files-without-matches'
alias ggv='git grep --invert-match'
alias ggw='git grep --word-regexp'

# Index (i)
alias gia='git add'
alias giA='git add .'
alias gip='git add --patch'
alias giu='git add --update'
alias gid='git diff --no-ext-diff --cached'
alias giD='git diff --no-ext-diff --cached --word-diff'
alias gii='git update-index --assume-unchanged'
alias giI='git update-index --no-assume-unchanged'
alias gir='git reset'
alias giR='git reset --patch'
alias gix='git rm -r --cached'
alias giX='git rm -rf --cached'

# Log (l)
alias gl='git log --topo-order --pretty=medium'
alias glf='git log --topo-order --stat --pretty=fuller'
alias gls='git log --topo-order --stat --pretty=medium'
alias gld='git log --topo-order --stat --patch --full-diff --pretty=medium'
alias glo='git log --topo-order --pretty=oneline'
alias glg='git log --topo-order --all --graph --pretty=oneline'
alias glc='git shortlog --summary --numbered'
alias glS='git log --show-signature'

# Merge (m)
alias gm='git merge'
alias gmC='git merge --no-commit'
alias gmF='git merge --no-ff'
alias gma='git merge --abort'
alias gmt='git mergetool'

# Push (p)
alias gp='git push'
alias gpf='git push --force-with-lease'
alias gpF='git push --force'
alias gpa='git push --all'
alias gpA='git push --all && git push --tags'
alias gpt='git push --tags'
alias gpc='git push --set-upstream origin (git-branch-current 2> /dev/null)'
alias gpp='git pull origin (git-branch-current 2> /dev/null) && git push origin (git-branch-current 2> /dev/null)'

# Rebase (r)
alias gr='git rebase'
alias gra='git rebase --abort'
alias grc='git rebase --continue'
alias gri='git rebase --interactive'
alias grs='git rebase --skip'

# Remote (R)
alias gR='git remote'
alias gRl='git remote --verbose'
alias gRa='git remote add'
alias gRx='git remote rm'
alias gRm='git remote rename'
alias gRu='git remote update'
alias gRp='git remote prune'
alias gRs='git remote show'
alias gRb='git-hub-browse'

# Stash (s)
alias gs='git stash'
alias gsa='git stash apply'
alias gsx='git stash drop'
alias gsX='git-stash-clear-interactive'
alias gsl='git stash list'
alias gsL='git-stash-dropped'
alias gsd='git stash show --patch --stat'
alias gsp='git stash pop'
alias gsr='git-stash-recover'
alias gss='git stash save --include-untracked'
alias gsS='git stash save --patch --no-keep-index'
alias gsw='git stash save --include-untracked --keep-index'

# Submodule (S)
alias gS='git submodule'
alias gSa='git submodule add'
alias gSf='git submodule foreach'
alias gSi='git submodule init'
alias gSI='git submodule update --init --recursive'
alias gSl='git submodule status'
alias gSm='git-submodule-move'
alias gSs='git submodule sync'
alias gSu='git submodule foreach git pull origin master'
alias gSx='git-submodule-remove'

# Tag (t)
alias gt='git tag'
alias gtl='git tag -l'
alias gts='git tag -s'
alias gtv='git verify-tag'

# Working Copy (w)
alias gwS='git status --ignore-submodules=none --short'
alias gws='git status --ignore-submodules=none'
alias gwd='git diff --no-ext-diff'
alias gwD='git diff --no-ext-diff --word-diff'
alias gwr='git reset --soft'
alias gwR='git reset --hard'
alias gwc='git clean -n'
alias gwC='git clean -f'
alias gwx='git rm -r'
alias gwX='git rm -rf'

# Open modified files
# ACMRU = Added || Copied || Modified || Renamed || Unmerged
# Edit all uncommitted files that have changes since the last commit (be they staged or unstaged)
alias vd="nvim (git diff HEAD --name-only --diff-filter=ACMR)"
# Edit all staged files that have changes since the last commit
alias vds="nvim (git diff --staged --name-only --diff-filter=ACMR)"
# Edit all files that were altered in the last commit
alias vdc="nvim (git diff HEAD^ --name-only --diff-filter=ACMR)"
# Edit files changed since master
alias vdm="nvim (git diff master --name-only --diff-filter=ACMR)"
# Edit files unmerged
alias vdu="nvim (git diff --name-only --diff-filter=U | uniq)"
# Add unmerged files
alias vdua="git add (git diff --name-only --diff-filter=U)"

# Cargo aliases
alias cba='cargo update && cargo build --all && cargo doc'
alias cbb='cargo build --all'
alias cbc='cargo clean'
alias cbd='cargo doc'
alias cbD='cargo doc --open'
alias cbu='cargo update'

# Git fzf helper functions
# https://github.com/junegunn/fzf/wiki/Examples-(fish)
function fco -d "Checkout a branch using fzf"
  git branch --all | grep -v HEAD | string trim | fzf | read -l result; and git checkout "$result"
end

function fcoc -d "Checkout a commit using fzf"
  git log --pretty=oneline --abbrev-commit --reverse | fzf --tac +s -e | awk '{print $1;}' | read -l result; and git checkout "$result"
end

# https://gist.github.com/gabesoft/b6e5e959c4cb11ed257d41edb07d47cb
# Modify to use --exact flag for fzf and delta as pager
function fbr --description "Git browse commits"
  set -l log_line_to_hash "echo {} | grep -o '[a-f0-9]\{7\}' | head -1"
  set -l view_commit "$log_line_to_hash | xargs -I % sh -c 'git show --color=always % | delta | less -R'"
  set -l copy_commit_hash "$log_line_to_hash | xclip"
  set -l git_checkout "$log_line_to_hash | xargs -I % sh -c 'git checkout %'"
  set -l open_cmd "open"

  if test (uname) = Linux
    set open_cmd "xdg-open"
  end

  set github_open "$log_line_to_hash | xargs -I % sh -c '$open_cmd https://github.\$(git config remote.origin.url | cut -f2 -d. | tr \':\' /)/commit/%'"

  git log --color=always --format='%C(auto)%h%d %s %C(green)%C(bold)%cr% C(blue)%an' | \
      fzf --exact --no-sort --reverse --tiebreak=index --no-multi --ansi \
          --preview="$view_commit" \
          --header="ENTER to view, CTRL-Y to copy hash, CTRL-O to open on GitHub, CTRL-X to checkout, CTRL-C to exit" \
          --bind "enter:execute:$view_commit" \
          --bind "ctrl-y:execute:$copy_commit_hash" \
          --bind "ctrl-x:execute:$git_checkout" \
          --bind "ctrl-o:execute:$github_open"
end

function fcf --description "Git commit fixup using fzf"
  git commit --fixup (git log --pretty=oneline --abbrev-commit --color=always | fzf --ansi | cut -d ' ' -f1)
end

function fcr --description "Git reset to a selected commit using fzf"
  git reset $argv (git log --pretty=oneline --abbrev-commit --color=always | fzf --ansi +s | awk '{print $1}')
end

function fcR --description "Git revert a selected commit using fzf"
  git revert (git log --pretty=oneline --abbrev-commit --color=always | fzf --ansi +s | awk '{print $1}')
end

function frbi --description "Git interactive rebase using fzf"
  git rebase -i (git log --pretty=oneline --abbrev-commit --color=always | fzf --ansi | cut -d ' ' -f1)
end

function ffa --description "Git add files using fzf"
  git add -- (git ls-files --modified --others --exclude-standard | fzf -m --preview 'bat --color=always {}')
end

function ffco --description "Git checkout a file using fzf"
  git checkout $argv -- (git ls-files --modified --exclude-standard | fzf -m)
end

function ffrs --description "Git restore a staged file using fzf"
  git restore --staged $argv -- (git diff --name-only --staged | fzf -m)
end

function ffr --description "Git restore a file using fzf"
  git restore $argv -- (git ls-files --modified --exclude-standard | fzf -m)
end

function grf --description "Search within a file with grep with context"
  grep --color=always -C 10 --group-separator="---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" $argv | less -R
end

function rgf --description "Search within a file with ripgrep"
  rg --color always $argv | nvim -R +AnsiEsc
end

function rgc --description "Search within a file with ripgrep with context"
  rg --color always -C 10 --context-separator="---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" $argv | nvim -R +AnsiEsc
end

function vo --description "Pipe a command output to neovim"
  $argv | nvim -R
end

function dotp --description "Generate Pipewire dot graph for linked nodes"
  pw-dot -L -s -o /tmp/pw.dot
  dot -Tsvg /tmp/pw.dot > ~/Pictures/pipewire/pw-dot-(date +%T).svg
  rm /tmp/pw.dot
end

function dotP --description "Generate Pipewire dot graph for all nodes"
  pw-dot -L -a -o /tmp/pw.dot
  dot -Tsvg /tmp/pw.dot > ~/Pictures/pipewire/pw-dot-(date +%T).svg
  rm /tmp/pw.dot
end

function dotg --description "Generate gstreamer dot graph for selected file"
  find $argv -maxdepth 1 -regextype posix-extended -regex ".*\.(dot)" | fzf | read -l result; and dot -Tsvg "$result" -O
  mv "$result".svg ~/Pictures/gstreamer
end

function gdba --description "Attach to a process"
  gdb attach -p (ps -ef | fzf | awk '{print $2}' | head -1)
end

function gdbp --description "Attach to a python process"
  gdb python3 (ps -ef | fzf | awk '{print $2}' | head -1)
end

function gdbr --description "Start a command/process with rust-gdb"
  rust-gdb --args $argv
end

function pst --description "Show process tree of a process"
  set proc (ps -ef | fzf | awk '{print $2}' | head -1)
  pstree -H $proc $proc
end

function cdi --description "Select a coredump to run coredumpctl info"
  coredumpctl list --reverse | awk -F" " '$9 == "present"' | fzf | read -l result
  coredumpctl info (echo $result | awk -F" " '{print $5}')
end

function cdg --description "coredumpctl gdb on last crashed process"
  coredumpctl gdb
end

function cdG --description "Select a coredump to run coredumpctl gdb"
  coredumpctl list --reverse | awk -F" " '$9 == "present"' | fzf | read -l result
  coredumpctl gdb (echo $result | awk -F" " '{print $5}')
end

function pft --description "Select a process to run perf top"
  set proc (ps -ef | fzf | awk '{print $2}')
  perf top -p $proc
end

function pfr --description "Select a process to record performance data in given file name"
  set proc (ps -ef | fzf | awk '{print $2}')
  perf record -F 99 -o $argv -p $proc
end

fzf_key_bindings

starship init fish | source
fnm env | source

# https://github.com/fish-shell/fish-shell/issues/7485#issuecomment-728984689
# https://wiki.archlinux.org/title/Flatpak#Adding_Flatpak_.desktop_files_to_your_menu
set -l xdg_data_home $XDG_DATA_HOME ~/.local/share
set -gx --path XDG_DATA_DIRS $xdg_data_home[1]/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share

for flatpakdir in ~/.local/share/flatpak/exports/bin /var/lib/flatpak/exports/bin
  if test -d $flatpakdir
    contains $flatpakdir $PATH; or set -a PATH $flatpakdir
  end
end
