diff --git a/.gitignore b/.gitignore index 6b22fc3..a7ab916 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ bin/misc -fish/fish_history -fish/fish_read_history -fish/fishd* configstore +fish/fish.xdg.symlink/conf.d/secret.fish + vim/vim.xdg.symlink/.netrwhist vim/vim.xdg.symlink/plugged vim/vim.xdg.symlink/plugged-update diff --git a/fish/fish.xdg.symlink/conf.d/fzf.fish b/fish/fish.xdg.symlink/conf.d/fzf.fish new file mode 100644 index 0000000..bd491df --- /dev/null +++ b/fish/fish.xdg.symlink/conf.d/fzf.fish @@ -0,0 +1,200 @@ +### key-bindings.fish ### +# ____ ____ +# / __/___ / __/ +# / /_/_ / / /_ +# / __/ / /_/ __/ +# /_/ /___/_/ key-bindings.fish +# +# - $FZF_TMUX_OPTS +# - $FZF_CTRL_T_COMMAND +# - $FZF_CTRL_T_OPTS +# - $FZF_CTRL_R_OPTS +# - $FZF_ALT_C_COMMAND +# - $FZF_ALT_C_OPTS + +status is-interactive; or exit 0 + + +# Key bindings +# ------------ +function fzf_key_bindings + + function __fzf_defaults + # $1: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS + # $2: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + echo "--height $FZF_TMUX_HEIGHT --bind=ctrl-z:ignore" $argv[1] + command cat "$FZF_DEFAULT_OPTS_FILE" 2> /dev/null + echo $FZF_DEFAULT_OPTS $argv[2] + end + + # Store current token in $dir as root for the 'find' command + function fzf-file-widget -d "List files and folders" + set -l commandline (__fzf_parse_commandline) + set -lx dir $commandline[1] + set -l fzf_query $commandline[2] + set -l prefix $commandline[3] + + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + begin + set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path --walker-root='$dir'" "$FZF_CTRL_T_OPTS") + set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND" + set -lx FZF_DEFAULT_OPTS_FILE '' + eval (__fzfcmd)' -m --query "'$fzf_query'"' | while read -l r; set result $result $r; end + end + if [ -z "$result" ] + commandline -f repaint + return + else + # Remove last token from commandline. + commandline -t "" + end + for i in $result + commandline -it -- $prefix + commandline -it -- (string escape $i) + commandline -it -- ' ' + end + commandline -f repaint + end + + function fzf-history-widget -d "Show command history" + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + begin + set -l FISH_MAJOR (echo $version | cut -f1 -d.) + set -l FISH_MINOR (echo $version | cut -f2 -d.) + + # merge history from other sessions before searching + if test -z "$fish_private_mode" + builtin history merge + end + + # history's -z flag is needed for multi-line support. + # history's -z flag was added in fish 2.4.0, so don't use it for versions + # before 2.4.0. + if [ "$FISH_MAJOR" -gt 2 -o \( "$FISH_MAJOR" -eq 2 -a "$FISH_MINOR" -ge 4 \) ]; + if type -P perl > /dev/null 2>&1 + set -lx FZF_DEFAULT_OPTS (__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '"\t"↳ ' --highlight-line $FZF_CTRL_R_OPTS +m") + set -lx FZF_DEFAULT_OPTS_FILE '' + builtin history -z --reverse | command perl -0 -pe 's/^/$.\t/g; s/\n/\n\t/gm' | eval (__fzfcmd) --tac --read0 --print0 -q '(commandline)' | command perl -pe 's/^\d*\t//' | read -lz result + and commandline -- $result + else + set -lx FZF_DEFAULT_OPTS (__fzf_defaults "" "--scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '"\t"↳ ' --highlight-line $FZF_CTRL_R_OPTS +m") + set -lx FZF_DEFAULT_OPTS_FILE '' + builtin history -z | eval (__fzfcmd) --read0 --print0 -q '(commandline)' | read -lz result + and commandline -- $result + end + else + builtin history | eval (__fzfcmd) -q '(commandline)' | read -l result + and commandline -- $result + end + end + commandline -f repaint + end + + function fzf-cd-widget -d "Change directory" + set -l commandline (__fzf_parse_commandline) + set -lx dir $commandline[1] + set -l fzf_query $commandline[2] + set -l prefix $commandline[3] + + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + begin + set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path --walker-root='$dir'" "$FZF_ALT_C_OPTS") + set -lx FZF_DEFAULT_OPTS_FILE '' + set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND" + eval (__fzfcmd)' +m --query "'$fzf_query'"' | read -l result + + if [ -n "$result" ] + cd -- $result + + # Remove last token from commandline. + commandline -t "" + commandline -it -- $prefix + end + end + + commandline -f repaint + end + + function __fzfcmd + test -n "$FZF_TMUX"; or set FZF_TMUX 0 + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + if [ -n "$FZF_TMUX_OPTS" ] + echo "fzf-tmux $FZF_TMUX_OPTS -- " + else if [ $FZF_TMUX -eq 1 ] + echo "fzf-tmux -d$FZF_TMUX_HEIGHT -- " + else + echo "fzf" + end + end + + bind \cr fzf-history-widget + if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND" + bind \ct fzf-file-widget + end + if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND" + bind \ec fzf-cd-widget + end + + if bind -M insert > /dev/null 2>&1 + bind -M insert \cr fzf-history-widget + if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND" + bind -M insert \ct fzf-file-widget + end + if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND" + bind -M insert \ec fzf-cd-widget + end + end + + function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix' + set -l commandline (commandline -t) + + # strip -option= from token if present + set -l prefix (string match -r -- '^-[^\s=]+=' $commandline) + set commandline (string replace -- "$prefix" '' $commandline) + + # eval is used to do shell expansion on paths + eval set commandline $commandline + + if [ -z $commandline ] + # Default to current directory with no --query + set dir '.' + set fzf_query '' + else + set dir (__fzf_get_dir $commandline) + + if [ "$dir" = "." -a (string sub -l 1 -- $commandline) != '.' ] + # if $dir is "." but commandline is not a relative path, this means no file path found + set fzf_query $commandline + else + # Also remove trailing slash after dir, to "split" input properly + set fzf_query (string replace -r "^$dir/?" -- '' "$commandline") + end + end + + echo $dir + echo $fzf_query + echo $prefix + end + + function __fzf_get_dir -d 'Find the longest existing filepath from input string' + set dir $argv + + # Strip all trailing slashes. Ignore if $dir is root dir (/) + if [ (string length -- $dir) -gt 1 ] + set dir (string replace -r '/*$' -- '' $dir) + end + + # Iteratively check if dir exists and strip tail end of path + while [ ! -d "$dir" ] + # If path is absolute, this can keep going until ends up at / + # If path is relative, this can keep going until entire input is consumed, dirname returns "." + set dir (dirname -- "$dir") + end + + echo $dir + end + +end +### end: key-bindings.fish ### +fzf_key_bindings diff --git a/fish/fish.xdg.symlink/conf.d/secret.fish.dist b/fish/fish.xdg.symlink/conf.d/secret.fish.dist new file mode 100644 index 0000000..3b42444 --- /dev/null +++ b/fish/fish.xdg.symlink/conf.d/secret.fish.dist @@ -0,0 +1,3 @@ +export GIT_AUTHOR_NAME="Max Bucknell" +export GIT_AUTHOR_EMAIL="me@maxbucknell.com" + diff --git a/fish/fish.xdg.symlink/config.fish b/fish/fish.xdg.symlink/config.fish new file mode 100644 index 0000000..81ff8e7 --- /dev/null +++ b/fish/fish.xdg.symlink/config.fish @@ -0,0 +1,95 @@ +# Base Path +set PATH "/usr/local/bin" "/usr/bin" "/bin" "/usr/sbin" "/sbin" + +# Homebrew (generated by `brew shellenv fish`, reformatted) +set -gx HOMEBREW_PREFIX "/opt/homebrew"; +set -gx HOMEBREW_CELLAR "/opt/homebrew/Cellar"; +set -gx HOMEBREW_REPOSITORY "/opt/homebrew"; + +fish_add_path --global --move --path "/opt/homebrew/bin" "/opt/homebrew/sbin"; + +if test -n "$MANPATH[1]" + set -gx MANPATH '' $MANPATH +end + +if not contains "/opt/homebrew/share/info" $INFOPATH + set -gx INFOPATH "/opt/homebrew/share/info" $INFOPATH +end + +# Rust +fish_add_path --global "$HOME/.cargo/bin" + +# Ruby +fish_add_path --global "$HOMEBREW_PREFIX/ruby/bin" + +# Go +set -gx GOPATH "$HOME/go" +set -gx GOBIN "$GOPATH/bin" +fish_add_path --global "$GOBIN" + +# Node.js +set -gx NODEPATH "$HOMEBREW_PREFIX/node@20" +fish_add_path --global "$NODEPATH/bin" + +# pnpm +set -gx PNPM_HOME "$HOME/Library/pnpm" +fish_add_path --global "$PNPM_HOME" + +# Java +set -gx JAVAPATH "$HOMEBREW_PREFIX/openjdk@21" +fish_add_path --global "$JAVAPATH/bin" + +# Android +set -gx ANDROID_HOME "$HOME/Library/Android/sdk" +fish_add_path --global "$ANDROID_HOME/emulator" "$ANDROID_HOME/platform-tools" + +# Local path +fish_add_path --global "$DOTFILES_PATH/bin" "$DOTFILES_PATH/bin/misc" + +# Git + +set -gx GIT_COMMITTER_NAME "$GIT_AUTHOR_NAME" +set -gx GIT_COMMITTER_EMAIL "$GIT_AUTHOR_EMAIL" + +set -g __fish_git_prompt_show_informative_status true +set -g __fish_git_prompt_showdirtystate true + +# Vim aliases +set -gx EDITOR "vim" +alias vi vim +alias v vim + +# Bazel +alias bazel bazelisk + +# Bat +alias cat "bat --paging=never" +set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'" + +# Eza +alias ls "eza --git --color=never" + +# Vi bindings + +# fish_vi_key_bindings + +# bind -M insert -m default jk cancel repaint-mode +# set -g fish_sequence_key_delay_ms 200 + +# Syntax highlighting + +fish_config theme choose none + +set -g fish_color_user normal +set -g fish_color_cwd normal +set -g fish_color_mode --bold magenta +set -g fish_color_comment green +set -g fish_color_error red +set -g fish_color_history_current magenta +set -g fish_color_quote blue +set -g fish_color_valid_path --bold +set -g fish_color_command --bold +set -g fish_color_time magenta + +# Greeting +set -g fish_greeting "You look nice today :-)" diff --git a/fish/fish.xdg.symlink/fish_variables b/fish/fish.xdg.symlink/fish_variables new file mode 100644 index 0000000..52cd691 --- /dev/null +++ b/fish/fish.xdg.symlink/fish_variables @@ -0,0 +1,31 @@ +# This file contains fish universal variable definitions. +# VERSION: 3.0 +SETUVAR __fish_initialized:3400 +SETUVAR fish_color_autosuggestion:brblack +SETUVAR fish_color_cancel:\x2dr +SETUVAR fish_color_command:blue +SETUVAR fish_color_comment:red +SETUVAR fish_color_cwd:green +SETUVAR fish_color_cwd_root:red +SETUVAR fish_color_end:green +SETUVAR fish_color_error:brred +SETUVAR fish_color_escape:brcyan +SETUVAR fish_color_history_current:\x2d\x2dbold +SETUVAR fish_color_host:normal +SETUVAR fish_color_host_remote:yellow +SETUVAR fish_color_normal:normal +SETUVAR fish_color_operator:brcyan +SETUVAR fish_color_param:cyan +SETUVAR fish_color_quote:yellow +SETUVAR fish_color_redirection:cyan\x1e\x2d\x2dbold +SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack +SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack +SETUVAR fish_color_status:red +SETUVAR fish_color_user:brgreen +SETUVAR fish_color_valid_path:\x2d\x2dunderline +SETUVAR fish_key_bindings:fish_default_key_bindings +SETUVAR fish_pager_color_completion:normal +SETUVAR fish_pager_color_description:yellow\x1e\x2di +SETUVAR fish_pager_color_prefix:normal\x1e\x2d\x2dbold\x1e\x2d\x2dunderline +SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan +SETUVAR fish_pager_color_selected_background:\x2dr diff --git a/fish/fish.xdg.symlink/functions/fish_mode_prompt.fish b/fish/fish.xdg.symlink/functions/fish_mode_prompt.fish new file mode 100644 index 0000000..827367a --- /dev/null +++ b/fish/fish.xdg.symlink/functions/fish_mode_prompt.fish @@ -0,0 +1,21 @@ +function fish_mode_prompt --description 'Displays the current mode' + # Do nothing if not in vi mode + if test "$fish_key_bindings" = fish_vi_key_bindings + or test "$fish_key_bindings" = fish_hybrid_key_bindings + set_color $fish_color_mode + switch $fish_bind_mode + case default + echo '[N]' + case insert + echo '[I]' + case replace_one + echo '[R]' + case replace + echo '[R]' + case visual + echo '[V]' + end + set_color normal + echo -n ' ' + end +end diff --git a/fish/fish.xdg.symlink/functions/fish_prompt.fish b/fish/fish.xdg.symlink/functions/fish_prompt.fish new file mode 100644 index 0000000..db53fa4 --- /dev/null +++ b/fish/fish.xdg.symlink/functions/fish_prompt.fish @@ -0,0 +1,31 @@ +function fish_prompt --description 'Write out the prompt' + set -l last_pipestatus $pipestatus + set -lx __fish_last_status $status # Export for __fish_print_pipestatus. + set -l normal (set_color normal) + set -q fish_color_status + or set -g fish_color_status red + + # Color the prompt differently when we're root + set -l color_cwd $fish_color_cwd + set -l suffix '$' + if functions -q fish_is_root_user; and fish_is_root_user + if set -q fish_color_cwd_root + set color_cwd $fish_color_cwd_root + end + set suffix '#' + end + + # Write pipestatus + # If the status was carried over (if no command is issued or if `set` leaves the status untouched), don't bold it. + set -l bold_flag --bold + set -q __fish_prompt_status_generation; or set -g __fish_prompt_status_generation $status_generation + if test $__fish_prompt_status_generation = $status_generation + set bold_flag + end + set __fish_prompt_status_generation $status_generation + set -l status_color (set_color $fish_color_status) + set -l statusb_color (set_color $bold_flag $fish_color_status) + set -l prompt_status (__fish_print_pipestatus "[" "]" "|" "$status_color" "$statusb_color" $last_pipestatus) + + echo -n -s (prompt_login)' ' (set_color $color_cwd) (prompt_pwd) $normal (fish_vcs_prompt) $normal " "$prompt_status " "$suffix " " +end diff --git a/fish/fish.xdg.symlink/functions/fish_prompt_right.fish b/fish/fish.xdg.symlink/functions/fish_prompt_right.fish new file mode 100644 index 0000000..059b743 --- /dev/null +++ b/fish/fish.xdg.symlink/functions/fish_prompt_right.fish @@ -0,0 +1,5 @@ +function fish_prompt_right + set_color $fish_color_time + date "+[%H:%M:%S]" + set_color normal +end diff --git a/fish/fish.xdg.symlink/functions/fish_right_prompt.fish b/fish/fish.xdg.symlink/functions/fish_right_prompt.fish new file mode 100644 index 0000000..13533f0 --- /dev/null +++ b/fish/fish.xdg.symlink/functions/fish_right_prompt.fish @@ -0,0 +1,5 @@ +function fish_right_prompt + set_color $fish_color_time + date "+[%H:%M:%S]" + set_color normal +end diff --git a/fish/fish.xdg.symlink/functions/prompt_login.fish b/fish/fish.xdg.symlink/functions/prompt_login.fish new file mode 100644 index 0000000..0a00d7a --- /dev/null +++ b/fish/fish.xdg.symlink/functions/prompt_login.fish @@ -0,0 +1,28 @@ +function prompt_login --description 'display user name for the prompt' + if not set -q __fish_machine + set -g __fish_machine + set -l debian_chroot $debian_chroot + + if test -r /etc/debian_chroot + set debian_chroot (cat /etc/debian_chroot) + end + + if set -q debian_chroot[1] + and test -n "$debian_chroot" + set -g __fish_machine "(chroot:$debian_chroot)" + end + end + + # Prepend the chroot environment if present + if set -q __fish_machine[1] + echo -n -s (set_color yellow) "$__fish_machine" (set_color normal) ' ' + end + + # If we're running via SSH, change the host color. + set -l color_host $fish_color_host + if set -q SSH_TTY; and set -q fish_color_host_remote + set color_host $fish_color_host_remote + end + + echo -n -s (set_color $fish_color_user) "$USER" (set_color normal) +end diff --git a/git/git.xdg.symlink/config b/git/git.xdg.symlink/config index 0d091a1..dbc9b58 100644 --- a/git/git.xdg.symlink/config +++ b/git/git.xdg.symlink/config @@ -78,3 +78,6 @@ [commit] gpgsign = true +[bash] + showInformativeStatus = 1 + showDirtyState = 1