summaryrefslogtreecommitdiff
path: root/gemfeed/examples/conf/dotfiles/fish/conf.d
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-10-02 11:28:55 +0300
committerPaul Buetow <paul@buetow.org>2025-10-02 11:28:55 +0300
commit2b034797107660d4d83f8a7acdc55d32db785b82 (patch)
tree522fb586193c8a65ca6aee42df64eecc3555f644 /gemfeed/examples/conf/dotfiles/fish/conf.d
parent4d7d90638186ac71067232007607f6637d560a4d (diff)
Update content for md
Diffstat (limited to 'gemfeed/examples/conf/dotfiles/fish/conf.d')
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/ai.fish39
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/alternatives.fish17
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/config.fish31
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/dotfiles.fish48
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/editor.fish44
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/fuzzy.fish5
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/games.fish15
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/gos.fish6
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/k8s.fish76
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/quickedit.fish93
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/supersync.fish114
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/taskwarrior.fish121
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/timr.fish25
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/tmputils.fish54
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/tmux.fish94
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/update.fish75
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/utils.fish142
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/worktime.fish122
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/zoxide.fish6
-rw-r--r--gemfeed/examples/conf/dotfiles/fish/conf.d/zsh.fish12
20 files changed, 1139 insertions, 0 deletions
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/ai.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/ai.fish
new file mode 100644
index 00000000..23ce2b20
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/ai.fish
@@ -0,0 +1,39 @@
+abbr -a gpt chatgpt
+abbr -a gpti "chatgpt --interactive"
+abbr -a suggest hexai
+abbr -a explain 'hexai explain'
+abbr -a aic 'aichat -e'
+
+# helix-gpt env vars used
+# set -gx COPILOT_MODEL gpt-4.1 # can be changed with aimodels function
+set -gx COPILOT_MODEL gpt-4o # can be changed with aimodels function
+set -gx HANDLER copilot
+
+# TODO: also reconfigure aichat tool using this function
+function aimodels
+ # nvim for the ai tool wrapper so i can use Copilot Chat from the command line.
+ set -l NVIM_DIR "$HOME/.config/nvim/"
+ set -l COPILOT_CHAT_DIR "$NVIM_DIR/pack/copilotchat/start/CopilotChat.nvim/lua/CopilotChat"
+
+ printf "gpt-4o
+gpt-5
+gpt-o3
+gpt-4.1
+claude-3.7-sonnet
+claude-3.7-sonnet-thought
+claude-4.0-sonnet
+gemini-2.5-pro" >~/.aimodels
+
+ set -gx COPILOT_MODEL (cat ~/.aimodels | fzf)
+ set -gx OPENAI_MODEL $COPILOT_MODEL
+
+ if test -d $COPILOT_CHAT_DIR
+ set -l model_config "$COPILOT_CHAT_DIR/config-$COPILOT_MODEL.lua"
+ if test -f "$model_config"
+ echo "Using CopilotChat config from $model_config"
+ cp -v $model_config "$COPILOT_CHAT_DIR/config.lua"
+ else
+ echo "No config found at $model_config"
+ end
+ end
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/alternatives.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/alternatives.fish
new file mode 100644
index 00000000..491cf1fe
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/alternatives.fish
@@ -0,0 +1,17 @@
+if type -q bat
+ alias Cat=/usr/bin/cat
+ alias cat=bat
+end
+if type -q see
+ alias ca=see
+end
+if type -q bit
+ alias Git=/usr/bin/git
+ alias git=bit
+end
+if type -q procs
+ alias p='procs'
+end
+if type -q carl
+ alias cal='carl'
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/config.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/config.fish
new file mode 100644
index 00000000..670ca861
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/config.fish
@@ -0,0 +1,31 @@
+fish_vi_key_bindings
+
+# Add paths to PATH
+set -U fish_user_paths ~/bin ~/scripts ~/go/bin ~/.cargo/bin $fish_user_paths
+
+if command -q -v doas >/dev/null
+ abbr -a s doas
+else
+ abbr -a s sudo
+end
+
+abbr -a g 'grep -E -i'
+abbr -a no 'grep -E -i -v'
+abbr -a not 'grep -E -i -v'
+abbr -a gl 'git log --pretty=oneline --graph --decorate --all'
+abbr -a gp 'begin; git commit -a; and git pull; and git push; end'
+
+for dir in ~/.config/fish/conf.d.work ~/.config/fish/conf.d.local
+ if test -d $dir
+ for file in $dir/*.fish
+ source $file
+ end
+ end
+end
+
+if test -d /home/linuxbrew/.linuxbrew
+ if status is-interactive
+ # Commands to run in interactive sessions can go here
+ end
+ eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/dotfiles.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/dotfiles.fish
new file mode 100644
index 00000000..6304d321
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/dotfiles.fish
@@ -0,0 +1,48 @@
+set -gx DOTFILES_DIR ~/git/rexfiles/dotfiles
+
+function dotfiles::update
+ set -l prev_pwd (pwd)
+ cd $DOTFILES_DIR
+ rex home
+ cd "$prev_pwd"
+end
+
+function dotfiles::update::git
+ set -l prev_pwd (pwd)
+ cd $DOTFILES_DIR
+ git pull
+ git commit -a
+ git push
+ rex home
+ cd "$prev_pwd"
+end
+
+function dotfiles::fuzzy::edit
+ set -l prev_pwd (pwd)
+ cd $DOTFILES_DIR
+ set -l dotfile (find . -type f -not -path '*/.git/*' | fzf)
+ $EDITOR "$dotfile"
+ if echo "$dotfile" | grep -F -q .fish
+ echo "Sourcing $dotfile"
+ source "$dotfile"
+ end
+ cd "$prev_pwd"
+end
+
+function dotfiles::rexify
+ cd $DOTFILES_DIR
+ rex home
+ cd -
+end
+
+function dotfiles::random::edit
+ $EDITOR (find $DOTFILES_DIR -type f -not -path '*/.git/*' | shuf -n 1)
+end
+
+abbr -a .u 'dotfiles::update'
+abbr -a .ug 'dotfiles::update::git'
+abbr -a .e 'dotfiles::fuzzy::edit'
+abbr -a .rex 'dotfiles::rexify'
+abbr -a .re 'dotfiles::random::edit'
+abbr -a cdconf "cd $HOME/git/conf"
+abbr -a cdotfiles "cd $HOME/git/conf/dotfiles"
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/editor.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/editor.fish
new file mode 100644
index 00000000..bda46448
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/editor.fish
@@ -0,0 +1,44 @@
+set -gx EDITOR hx
+set -gx VISUAL $EDITOR
+set -gx GIT_EDITOR $EDITOR
+set -gx HELIX_CONFIG_DIR $HOME/.config/helix
+
+function editor::helix::open_with_lock
+ set -l file $argv[1]
+ set -l lock "$file.lock"
+ if test -f "$lock"
+ echo "File lock $lock exists! Another instance is editing it?"
+ return 2
+ end
+ touch $lock
+ hx $file $argv[2..-1]
+ rm $lock
+end
+
+function editor::helix::open_with_lock::force
+ set -l file $argv[1]
+ set -l lock "$file.lock"
+ if test -f "$lock"
+ echo "File lock $lock exists! Force deleting it and terminating all $EDITOR instances?"
+ rm -f $lock
+ pkill -f $EDITOR
+ end
+ touch $lock
+ hx $file $argv[2..-1]
+ rm $lock
+end
+
+function editor::helix::edit::remote
+ set -l local_path $argv[1]
+ set -l remote_uri $argv[2]
+ scp $local_path $remote_uri; or return 1
+ echo "LOCAL_PATH=$local_path; REMOTE_URI=$remote_uri" >~/.hx.remote.source
+ hx $local_path
+end
+
+abbr -a lhx 'editor::helix::open_with_lock'
+abbr -a hxl 'editor::helix::open_with_lock'
+abbr -a hxlf 'editor::helix::open_with_lock::force'
+abbr -a lhxf 'editor::helix::open_with_lock::force'
+abbr -a rhx 'editor::helix::edit::remote'
+abbr -a x hx
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/fuzzy.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/fuzzy.fish
new file mode 100644
index 00000000..7683a0e7
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/fuzzy.fish
@@ -0,0 +1,5 @@
+function __tv_git
+ tv git-repos
+end
+
+bind \cg __tv_git
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/games.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/games.fish
new file mode 100644
index 00000000..291a798f
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/games.fish
@@ -0,0 +1,15 @@
+function games::colorscript
+ if test -e ~/git/shell-color-scripts
+ cd ~/git/shell-color-scripts
+ set -x DEV 1
+ ./colorscript.sh --random
+ cd -
+ else
+ echo 'No colorscripts installed. Go to:'
+ echo ' https://gitlab.com/dwt1/shell-color-scripts'
+ end
+end
+
+if not test -f ~/.colorscript.disable
+ games::colorscript
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/gos.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/gos.fish
new file mode 100644
index 00000000..a23d7a7b
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/gos.fish
@@ -0,0 +1,6 @@
+set -x GOS_BIN ~/go/bin/gos
+set -x GOS_DIR ~/.gosdir
+
+if test -f $GOS_BIN
+ alias cdgos "cd $GOS_DIR"
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/k8s.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/k8s.fish
new file mode 100644
index 00000000..ee1584bf
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/k8s.fish
@@ -0,0 +1,76 @@
+function kcompletions
+ if command -q -v kubectl >/dev/null
+ kubectl completion fish | source
+ end
+end
+
+# Check if the directory $HOME/.krew exists and update PATH
+if test -d $HOME/.krew
+ set -x PATH (set -q KREW_ROOT; and echo $KREW_ROOT; or echo $HOME/.krew)/bin $PATH
+end
+
+function kpod
+ set pattern "."
+ if test -n "$argv[1]"
+ set pattern "$argv[1]"
+ end
+ set -gx POD (kubectl get pods | grep "$pattern" | sort -R | head -n 1 | cut -d' ' -f1)
+ echo "Pod is $POD"
+end
+
+function klogsf
+ if test -z "$POD" -o -n "$argv[1]"
+ kpod $argv
+ end
+ kubectl logs -f $POD
+end
+
+function klogs
+ if test -z "$POD" -o -n "$argv[1]"
+ kpod $argv
+ end
+ kubectl logs $POD
+end
+
+function kbash
+ if test -z "$POD" -o -n "$argv[1]"
+ kpod $argv
+ end
+ kubectl exec -it $POD -- /bin/bash
+end
+
+function kshell
+ if test -z "$POD" -o -n "$argv[1]"
+ kpod $argv
+ end
+ kubectl exec -it $POD -- /bin/sh
+end
+
+function kdesc
+ if test -z "$POD" -o -n "$argv[1]"
+ kpod $argv
+ end
+ kubectl describe pod $POD
+end
+
+function kedit
+ if test -z "$POD" -o -n "$argv[1]"
+ kpod $argv
+ end
+ kubectl edit pod $POD
+end
+
+function k8s::kubectl::config::contexts
+ kubectl config get-contexts | sed '1d; /\*/d' | awk '{ print $1 }' | sort
+end
+alias kcontexts="k8s::kubectl::config::contexts"
+
+function k8s::kubectl::config::use_context
+ kubectl config use-context (kubectl config get-contexts | sed '1d; /\*/d' | awk '{ print $1 }' | sort | fzf)
+end
+alias kcontext="k8s::kubectl::config::use_context"
+
+function k8s::kubectl::config::set_namespace
+ kubectl config set-context --current --namespace=(kubectl get ns | sed 1d | awk '{ print $1 }' | sort | fzf)
+end
+alias knamespace="k8s::kubectl::config::set_namespace"
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/quickedit.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/quickedit.fish
new file mode 100644
index 00000000..c722acc6
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/quickedit.fish
@@ -0,0 +1,93 @@
+set -gx QUICKEDIT_DIR ~/QuickEdit
+
+function quickedit::postaction
+ set -l file_path $argv[1]
+ set -l make_run 0
+
+ if test -f Makefile
+ make
+ set make_run 1
+ end
+
+ # Go to git toplevel dir (if exists)
+ cd (dirname $file_path)
+ set -l git_dir (git rev-parse --show-toplevel 2>/dev/null)
+ if test $status -eq 0
+ cd $git_dir
+ end
+ if not test $make_run -eq 1
+ if test -f Makefile
+ make
+ end
+ end
+ if test -d .git
+ git commit -a -m Update
+ git pull
+ git push
+ end
+end
+
+function quickedit
+ set -l prev_dir (pwd)
+ set -l grep_pattern .
+
+ if test (count $argv) -gt 0
+ set grep_pattern $argv[1]
+ end
+
+ cd $QUICKEDIT_DIR
+ set files (find -L . -type f -not -path '*/.*' | grep -E "$grep_pattern")
+
+ switch (count $files)
+ case 0
+ echo No result found
+ return
+ case 1
+ set file_path $files[1]
+ case '*'
+ set file_path (printf '%s\n' $files | fzf)
+ end
+
+ if editor::helix::open_with_lock $file_path
+ quickedit::postaction $file_path
+ end
+
+ cd $prev_dir
+end
+
+function quickedit::direct
+ set -l dir $argv[1]
+ set -l file $argv[2]
+ cd $dir
+
+ if editor::helix::open_with_lock $file
+ quickedit::postaction $file
+ end
+
+ cd -
+end
+
+function quickedit::scratchpad
+ quickedit::direct ~/Notes Scratchpad.md
+end
+
+function quickedit::quicknote
+ quickedit::direct ~/Notes QuickNote.md
+end
+
+function quickedit::performance
+ quickedit::direct ~/Notes Performance.md
+end
+
+abbr -a e quickedit
+abbr -a scratch quickedit::scratchpad
+abbr -a S quickedit::scratchpad
+abbr -a quicknote quickedit::quicknote
+abbr -a performance quickedit::performance
+abbr -a goals quickedit::performance
+abbr -a er "ranger $QUICKEDIT_DIR"
+abbr -a cdquickedit "cd $QUICKEDIT_DIR"
+abbr -a cdnotes 'cd ~/Notes'
+abbr -a cdfish 'cd ~/.config/fish/conf.d'
+abbr -a cddocs 'cd ~/Documents'
+abbr -a cdocs 'cd ~/Documents'
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/supersync.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/supersync.fish
new file mode 100644
index 00000000..356f773f
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/supersync.fish
@@ -0,0 +1,114 @@
+set -x SUPERSYNC_STAMP_FILE ~/.supersync.last
+
+# Only sync the HabitsAndQuotes when it's asked for via function parameter
+function supersync::worktime
+ set -l worktime_dir ~/git/worktime
+
+ if not test -d $worktime_dir
+ echo "Warning: Directory $worktime_dir does not exist"
+ return 1
+ end
+ cd $worktime_dir
+
+ if test (count $argv) -gt 0 -a $argv[1] = sync_quotes
+ if test -d ~/Notes/HabitsAndQuotes
+ echo "" >work-wisdoms.md.tmp
+ for notes in ~/Notes/HabitsAndQuotes/{Productivity,Mentoring}.md
+ grep '^\* ' $notes >>work-wisdoms.md.tmp
+ end
+ sort -u work-wisdoms.md.tmp >work-wisdoms.md
+ rm work-wisdoms.md.tmp
+ git add work-wisdoms.md
+ grep '^\* ' ~/Notes/HabitsAndQuotes/Exercise.md >exercises.md
+ git add exercises.md
+ end
+ end
+
+ find . -name '*.txt' -exec git add {} \;
+ find . -name '*.json' -exec git add {} \;
+ git commit -a -m sync
+
+ git pull origin master
+ git push origin master
+
+ cd -
+end
+
+function supersync::uprecords
+ set -l uprecords_dir ~/git/uprecords
+ set -l uprecords_repo git@codeberg.org:snonux/uprecords.git
+
+ if not test -d $uprecords_dir
+ git clone $uprecords_repo $uprecords_dir
+ cd $uprecords_dir
+ else
+ cd $uprecords_dir
+ git pull
+ end
+
+ make update
+ git commit -a -m Update
+ git push
+ cd -
+end
+
+function supersync::taskwarrior
+ if test -f ~/scripts/taskwarriorfeeder.rb
+ ruby ~/scripts/taskwarriorfeeder.rb
+ else
+ echo "No taskwarrior feeder script, skipping"
+ end
+
+ taskwarrior::export
+ taskwarrior::export::gos
+ taskwarrior::import
+end
+
+function supersync::gitsyncer
+ set enable_file ~/.gitsyncer_enable
+ set now (date +%s)
+ set weekly_interval (math 7 \* 24 \* 60 \* 60)
+
+ if not test -f $enable_file
+ echo $now >$enable_file
+ else
+ set last_run (cat $enable_file)
+ if test (math $now - $last_run) -lt $weekly_interval
+ return
+ end
+ end
+
+ if test -f ~/go/bin/gitsyncer
+ ~/go/bin/gitsyncer sync bidirectional && ~/go/bin/gitsyncer showcase
+ end
+ if test $status -eq 0
+ date +%s >$enable_file
+ end
+end
+
+function supersync
+ supersync::worktime sync_quotes
+ supersync::taskwarrior
+ supersync::worktime no_sync_quotes
+ supersync::uprecords
+ supersync::gitsyncer
+
+ if test -f ~/.gos_enable
+ gos
+ end
+
+ date +%s >$SUPERSYNC_STAMP_FILE.tmp
+ mv $SUPERSYNC_STAMP_FILE.tmp $SUPERSYNC_STAMP_FILE
+end
+
+function supersync::is_it_time_to_sync
+ set -l max_age 86400
+ set -l now (date +%s)
+ if test -f $SUPERSYNC_STAMP_FILE
+ set -l diff (math $now - (cat $SUPERSYNC_STAMP_FILE))
+ if test $diff -lt $max_age
+ return 0
+ end
+ end
+ read -P "It's time to run supersync! Run it? (y/n) " answer; and test "$answer" = y; and supersync
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/taskwarrior.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/taskwarrior.fish
new file mode 100644
index 00000000..d3192bcd
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/taskwarrior.fish
@@ -0,0 +1,121 @@
+function taskwarrior::fuzzy::_select
+ sed -n '/^[0-9]/p' | sort -rn | fzf | cut -d' ' -f1
+end
+
+function taskwarrior::fuzzy::find
+ set -g TASK_ID (task ready | taskwarrior::fuzzy::_select)
+end
+
+function taskwarrior::select
+ set -l task_id "$argv[1]"
+ if test -n "$task_id"
+ set -g TASK_ID "$task_id"
+ end
+ if test "$TASK_ID" = - -o -z "$TASK_ID"
+ taskwarrior::fuzzy::find
+ end
+end
+
+function taskwarrior::due::count
+ set -l due_count (task status:pending due.before:now count)
+
+ if test $due_count -gt 0
+ echo "There are $due_count tasks due!"
+ end
+end
+
+function taskwarrior::add::track
+ if test (count $argv) -gt 0
+ task add priority:L +personal +track $argv
+ else
+ tasksamurai +track
+ end
+end
+
+function taskwarrior::add::standup
+ if test (count $argv) -gt 0
+ task add priority:L +work +standup +sre +nosched $argv
+ task add priority:L +work +standup +storage +nosched $argv
+
+ if test -f ~/git/helpers/jira/jira.rb
+ echo "Do you want to raise a Jira ticket? (y/n)"
+ read -l user_input
+ if test "$user_input" = y
+ ruby ~/git/helpers/jira/jira.rb --raise "$argv"
+ end
+ end
+
+ else
+ tasksamurai +standup
+ end
+end
+
+function taskwarrior::add::standup::editor
+ set -l tmpfile (mktemp /tmp/standup.XXXXXX.txt)
+ $EDITOR $tmpfile
+ taskwarrior::add::standup (cat $tmpfile)
+end
+
+function _taskwarrior::set_import_export_tags
+ if test (uname) = Darwin
+ set -gx TASK_IMPORT_TAG work
+ set -gx TASK_EXPORT_TAG personal
+ else
+ set -gx TASK_IMPORT_TAG personal
+ set -gx TASK_EXPORT_TAG work
+ end
+end
+
+function taskwarrior::export::gos
+ task +share status:pending export >"$WORKTIME_DIR/tw-gos-export-$(date +%s).json"
+ yes | task +share status:pending delete
+end
+
+function taskwarrior::export
+ _taskwarrior::set_import_export_tags
+ set -l count (task +$TASK_EXPORT_TAG status:pending count)
+
+ if test $count -eq 0
+ return
+ end
+
+ echo "Exporting $count tasks to $TASK_EXPORT_TAG"
+ task +$TASK_EXPORT_TAG status:pending export >"$WORKTIME_DIR/tw-$TASK_EXPORT_TAG-export-$(date +%s).json"
+ yes | task +$TASK_EXPORT_TAG status:pending delete
+end
+
+function taskwarrior::import
+ _taskwarrior::set_import_export_tags
+
+ find $WORKTIME_DIR -name "tw-$TASK_IMPORT_TAG-export-*.json" | while read -l import
+ task import $import
+ rm $import
+ end
+
+ find $WORKTIME_DIR -name "tw-(hostname)-export-*.json" | while read -l import
+ task import $import
+ rm $import
+ end
+end
+
+abbr -a t task
+abbr -a L 'task add +log'
+abbr -a tlog 'task add +log'
+abbr -a log 'task add +log'
+abbr -a tdue 'tasksamurai status:pending due.before:now'
+abbr -a thome 'tasksamurai +home'
+abbr -a tasks 'tasksamurai -track'
+abbr -a tread 'tasksamurai +read'
+abbr -a track 'taskwarrior::add::track'
+abbr -a tra 'taskwarrior::add::track'
+abbr -a trat 'timr track'
+abbr -a tfind 'taskwarrior::fuzzy::find'
+abbr -a ts tasksamurai
+
+# Virtual standup abbrs
+abbr -a V 'taskwarrior::add::standup'
+abbr -a Vstorage 'tasksamurai +standup +storage'
+abbr -a Vsre 'tasksamurai +standup +sre'
+abbr -a Ved 'taskwarrior::add::standup::editor'
+
+taskwarrior::due::count
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/timr.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/timr.fish
new file mode 100644
index 00000000..4f084454
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/timr.fish
@@ -0,0 +1,25 @@
+function timr_prompt -d "Display timr timr_status in the prompt"
+ if command -v timr >/dev/null
+ set -l timr_status (timr prompt)
+ if test -n "$timr_status"
+ set -l icon (string sub -l 1 -- "$timr_status")
+ set -l time (string sub -s 2 -- "$timr_status")
+ if test "$icon" = "▶"
+ set_color green
+ else
+ set_color yellow
+ end
+ printf '%s' "$icon"
+ set_color normal
+ printf ' %s' "$time"
+ end
+ end
+end
+
+complete -c timr -n __fish_use_subcommand -a start -d "Start the timer"
+complete -c timr -n __fish_use_subcommand -a stop -d "Stop the timer"
+complete -c timr -n __fish_use_subcommand -a pause -d "Pause the timer"
+complete -c timr -n __fish_use_subcommand -a status -d "Show the timer status"
+complete -c timr -n __fish_use_subcommand -a reset -d "Reset the timer"
+complete -c timr -n __fish_use_subcommand -a live -d "Show the live timer"
+complete -c timr -n __fish_use_subcommand -a prompt -d "Show the prompt status"
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/tmputils.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/tmputils.fish
new file mode 100644
index 00000000..20a122ad
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/tmputils.fish
@@ -0,0 +1,54 @@
+set -gx TMPUTILS_DIR ~/data/tmp
+set -gx TMPUTILS_TMPFILE ~/.tmpfile
+
+function tmpls
+ if not test -d $TMPUTILS_DIR
+ return
+ end
+ ls $TMPUTILS_DIR
+end
+
+function tmptee
+ set -l name $argv[1]
+ if test -z "$name"
+ set name (date +%s)
+ else
+ set -e argv[1]
+ end
+ set -l file "$TMPUTILS_DIR/$name"
+ if not test -d $TMPUTILS_DIR
+ mkdir -p $TMPUTILS_DIR
+ end
+ tee $argv $file
+ echo $file >$TMPUTILS_TMPFILE
+end
+
+function tmpcat
+ set -l name $argv[1]
+ if test -z "$name"
+ cat (tmpfile)
+ return
+ end
+ cat "$TMPUTILS_DIR/$name"
+end
+
+function tmpedit
+ set -l name $argv[1]
+ if test -z "$name"
+ $EDITOR (tmpfile)
+ return
+ end
+ $EDITOR "$TMPUTILS_DIR/$name"
+end
+
+function tmpgrep
+ set -l name $argv[1]
+ set -e argv[1]
+ tmcpat $name | grep $argv
+end
+
+function tmpfile
+ cat $TMPUTILS_TMPFILE
+end
+
+abbr -a cdtmp "cd $TMPUTILS_DIR"
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/tmux.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/tmux.fish
new file mode 100644
index 00000000..e65960e0
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/tmux.fish
@@ -0,0 +1,94 @@
+function _tmux::cleanup_default
+ tmux list-sessions | string match -r '^T.*: ' | string match -v -r attached | string split ':' | while read -l s
+ echo "Killing $s"
+ tmux kill-session -t "$s"
+ end
+end
+
+function _tmux::connect_command
+ set -l server_or_pod $argv[1]
+ if test -z "$TMUX_KEXEC"
+ echo "ssh -A -t $server_or_pod"
+ else
+ echo "kubectl exec -it $server_or_pod -- /bin/bash"
+ end
+end
+
+function tmux::new
+ set -l session $argv[1]
+ _tmux::cleanup_default
+ if test -z "$session"
+ tmux::new (string join "" T (date +%s))
+ else
+ tmux new-session -d -s $session
+ tmux -2 attach-session -t $session || tmux -2 switch-client -t $session
+ end
+end
+
+function tmux::attach
+ set -l session $argv[1]
+ if test -z "$session"
+ tmux attach-session || tmux::new
+ else
+ tmux attach-session -t $session || tmux::new $session
+ end
+end
+
+function tmux::remote
+ set -l server $argv[1]
+ tmux new -s $server "ssh -A -t $server 'tmux attach-session || tmux'" || tmux attach-session -d -t $server
+end
+
+function tmux::search
+ set -l session (tmux list-sessions | fzf | cut -d: -f1)
+ if test -z "$TMUX"
+ tmux attach-session -t $session
+ else
+ tmux switch -t $session
+ end
+end
+
+function tmux::cluster_ssh
+ if test -f "$argv[1]"
+ tmux::tssh_from_file $argv[1]
+ return
+ end
+ tmux::tssh_from_argument $argv
+end
+
+function tmux::tssh_from_argument
+ set -l session $argv[1]
+ set first_server_or_container $argv[2]
+ set remaining_servers $argv[3..-1]
+ if test -z "$first_server_or_container"
+ set first_server_or_container $session
+ end
+
+ tmux new-session -d -s $session (_tmux::connect_command "$first_server_or_container")
+ if not tmux list-session | grep "^$session:"
+ echo "Could not create session $session"
+ return 2
+ end
+ for server_or_container in $remaining_servers
+ tmux split-window -t $session "tmux select-layout tiled; $(_tmux::connect_command "$server_or_container")"
+ end
+ tmux setw -t $session synchronize-panes on
+ tmux -2 attach-session -t $session || tmux -2 switch-client -t $session
+end
+
+function tmux::tssh_from_file
+ set -l serverlist $argv[1]
+ set -l session (basename $serverlist | cut -d. -f1)
+ tmux::tssh_from_argument $session (awk '{ print $1 }' $serverlist | sed 's/.lan./.lan/g')
+end
+
+alias tn 'tmux::new'
+alias ta 'tmux::attach'
+alias tx 'tmux::remote'
+alias ts 'tmux::search'
+alias tssh 'tmux::cluster_ssh'
+alias tm tmux
+alias tl 'tmux list-sessions'
+alias foo 'tmux::new foo'
+alias bar 'tmux::new bar'
+alias baz 'tmux::new baz'
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/update.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/update.fish
new file mode 100644
index 00000000..935b6302
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/update.fish
@@ -0,0 +1,75 @@
+function update::tools
+ set pids
+
+ echo "Installing/updating gofumpt"
+ go install mvdan.cc/gofumpt@latest &
+ set -a pids $last_pid
+
+ echo "Installing/updating mage"
+ go install github.com/magefile/mage@latest &
+ set -a pids $last_pid
+
+ echo "Installing/updating golangci-lint"
+ go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest &
+ set -a pids $last_pid
+
+ echo "Installing/updating goimports"
+ go install golang.org/x/tools/cmd/goimports@latest &
+ set -a pids $last_pid
+
+ for prog in hexai hexai-lsp hexai-tmux-action
+ echo "Installing/updating $prog from codeberg.org/snonux/hexai/cmd/$prog@latest"
+ go install codeberg.org/snonux/hexai/cmd/$prog@latest &
+ set -a pids $last_pid
+ end
+
+ for prog in tasksamurai timr
+ echo "Installing/updating $prog from codeberg.org/snonux/$prog/cmd/$prog@latest"
+ go install codeberg.org/snonux/$prog/cmd/$prog@latest &
+ set -a pids $last_pid
+ end
+
+ if test (uname) = Darwin
+ echo 'Updating cursor-agent on macOS'
+ cursor-agent update
+ end
+ set -a pids $last_pid
+
+ if test (uname) = Linux
+ echo "Installing/updating tgpt"
+ go install github.com/aandrew-me/tgpt/v2@latest &
+ set -a pids $last_pid
+
+ for prog in gos gitsyncer
+ echo "Installing/updating $prog from codeberg.org/snonux/$prog/cmd/$prog@latest"
+ go install codeberg.org/snonux/$prog/cmd/$prog@latest
+ end
+
+ echo "Installing/updating @anthropic-ai/claude-code globally via npm"
+ doas npm uninstall -g @anthropic-ai/claude-code
+ doas npm install -g @anthropic-ai/claude-code
+
+ # doas npm uninstall -g @qwen-code/qwen-code@latest
+ # doas npm install -g @qwen-code/qwen-code@latest
+
+ echo "Installing/updating @openai/codex globally via npm"
+ doas npm uninstall -g @openai/codex
+ doas npm install -g @openai/codex
+
+ echo "Installing/updating @google/gemini-cli globally via npm"
+ doas npm uninstall -g @google/gemini-cli
+ doas npm install -g @google/gemini-cli
+
+ # echo "Installing/updating @sourcegraph/amp globally via npm"
+ # doas npm uninstall -g @sourcegraph/amp
+ # doas npm install -g @sourcegraph/amp
+
+ echo "Installing/updating opencode-ai globally via npm"
+ doas npm uninstall -g opencode-ai
+ doas npm install -g opencode-ai
+ end
+
+ for pid in $pids
+ wait $pid
+ end
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/utils.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/utils.fish
new file mode 100644
index 00000000..0f112177
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/utils.fish
@@ -0,0 +1,142 @@
+function fullest_h
+ df -h | sort -n -k 5
+end
+
+function fullest_i
+ df -i | sort -n -k 5
+end
+
+function usortn
+ sort | uniq -c | sort -n
+end
+
+function asum
+ awk '{ sum += $1 } END { print sum }'
+end
+
+function stop
+ set -l service $argv[1]
+ sudo service $service stop $argv
+end
+
+function start
+ set -l service $argv[1]
+ sudo service $service start $argv
+end
+
+function restart
+ set -l service $argv[1]
+ sudo service $service restart $argv
+end
+
+function statuss
+ set -l service $argv[1]
+ sudo service $service status $argv
+end
+
+function loop
+ set -l sleep 10
+ if set -q SLEEP
+ set sleep $SLEEP
+ end
+ echo "sleep is $sleep" 1>&2
+ while true
+ $argv
+ sleep $sleep
+ end
+end
+
+function f
+ find . -iname "*$argv*"
+end
+
+function random
+ set -l upto $argv[1]
+ set -l random (math $RANDOM % $upto)
+ echo "Sleeping $random seconds"
+ sleep $random
+end
+
+function dedup
+ set -l file $argv[1]
+ if test -z $file
+ awk '{ if (line[$0] != 42) { print $0 }; line[$0] = 42; }'
+ else
+ awk '{ if (line[$0] != 42) { print $0 }; line[$0] = 42; }' $file | sudo tee $file.dedup >/dev/null
+ if test ! -f $file.dedupbak
+ sudo mv $file $file.dedupbak
+ end
+ sudo mv $file.dedup $file
+ wc -l $file $file.dedupbak
+ sudo gzip --best $file.dedupbak &
+ end
+end
+
+function dedup_no_bak
+ set -l file $argv[1]
+ if test -z $file
+ awk '{ if (line[$0] != 42) { print $0 }; line[$0] = 42; }'
+ else
+ awk '{ if (line[$0] != 42) { print $0 }; line[$0] = 42; }' $file | sudo tee $file.dedup >/dev/null
+ if test ! -f $file.dedupbak
+ sudo mv $file $file.dedupbak
+ end
+ sudo mv $file.dedup $file
+ wc -l $file $file.dedupbak
+ sudo rm -v $file.dedupbak &
+ end
+end
+
+function drop_caches
+ echo 3 | sudo tee /proc/sys/vm/drop_caches
+end
+
+function ssl_connect
+ set -l address $argv[1]
+ openssl s_client -connect $address
+end
+
+function ssl_dates
+ ssl_connect $argv | openssl x509 -noout -dates
+end
+
+function lastu
+ last | grep -E -v '(root|cron|nagios)'
+end
+
+function lastl
+ lastu | less
+end
+
+abbr wetter 'curl http://wttr.in'
+
+abbr tf terraform
+
+function touchtype
+ tt --noskip --noreport --showwpm --bold --theme (tt -list themes | sort -R | head -n1) $argv
+end
+
+function touchtype::quote
+ while true
+ touchtype -quotes en
+ sleep 0.2
+ end
+end
+
+abbr typing 'touchtype::quote'
+
+function sway_config_view
+ less /etc/sway/config
+end
+
+function ssh::force
+ set -l server $argv[1]
+ ssh-keygen -R $server
+ ssh -A $server
+end
+
+if test -f ~/git/geheim/geheim.rb
+ function geheim
+ ruby ~/git/geheim/geheim.rb $argv
+ end
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/worktime.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/worktime.fish
new file mode 100644
index 00000000..f2f7f5d6
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/worktime.fish
@@ -0,0 +1,122 @@
+set -gx WORKTIME_DIR ~/git/worktime
+
+if test (uname) = Darwin -a ! -f ~/.wtloggedin
+ echo "Warn: Not logged in, run wtlogin"
+end
+
+function worktime
+ ruby $WORKTIME_DIR/worktime.rb $argv
+end
+
+function worktime::sync
+ cd $WORKTIME_DIR
+ git commit -a -m sync
+ git pull
+ git push
+ cd -
+end
+
+function worktime::wisdom_reminder
+ if test -f $WORKTIME_DIR/work-wisdoms.md
+ sed -n '/^\* / { s/\* //; p; }' $WORKTIME_DIR/work-wisdoms.md | sort -R | head -n 1
+ end
+end
+
+function worktime::report
+ if test -f ~/.wtloggedin
+ if test -f ~/.wtmaster
+ worktime --report | tee $WORKTIME_DIR/report.txt
+ else
+ worktime --report
+ end
+ worktime::wisdom_reminder
+ end
+end
+
+function worktime::add
+ set -l seconds $argv[1]
+ set -l what $argv[2]
+ set -l descr $argv[3]
+ set -l epoch (date +%s)
+
+ if test -z "$what"
+ set what work
+ end
+
+ if test -z "$descr"
+ worktime --add $seconds --epoch $epoch --what $what
+ else
+ worktime --add $seconds --epoch $epoch --what $what --descr "$descr"
+ end
+
+ worktime::report
+end
+
+function worktime::log
+ set -l seconds $argv[1]
+ set -l what $argv[2]
+ set -l epoch (date +%s)
+
+ if test -z "$what"
+ set what work
+ end
+
+ worktime --log --epoch $epoch --what $what
+ worktime::report
+end
+
+function worktime::login
+ set -l what $argv[1]
+ if test -z "$what"
+ set what work
+ end
+ touch ~/.wtloggedin
+ worktime --login --what $what
+ worktime::wisdom_reminder
+end
+
+function worktime::logout
+ set -l what $argv[1]
+
+ if test -z "$what"
+ set what work
+ end
+
+ if test -f ~/.wtloggedin
+ rm ~/.wtloggedin
+ end
+
+ worktime --logout --what $what
+ worktime::report
+end
+
+function worktime::status
+ worktime::report
+
+ if test -f ~/.wtloggedin
+ echo "You are logged in"
+ set -l num_worklog (ls $WORKTIME_DIR | grep wl- | wc -l)
+ if test $num_worklog -gt 0
+ echo "$num_worklog entries in the worklog"
+ end
+ else
+ echo "You are not logged in"
+ end
+end
+
+abbr -a cdworktime "cd $WORKTIME_DIR"
+abbr -a wt worktime
+abbr -a wtedit 'worktime --edit'
+abbr -a wtreport 'worktime --report'
+abbr -a wtadd 'worktime::add'
+abbr -a wtlog 'worktime::log'
+abbr -a wtlogin 'worktime::login'
+abbr -a wtlogout 'worktime::logout'
+abbr -a wtstatus 'worktime::status'
+abbr -a wtsync 'worktime::sync'
+abbr -a wtf 'worktime --report'
+abbr -a random_exercise "sort -R $WORKTIME_DIR/exercises.md | head -n 1"
+abbr -a random_exercises "sort -R $WORKTIME_DIR/exercises.md | head -n 10"
+abbr -a wl 'task add +work'
+abbr -a ql 'task add +personal'
+abbr -a pl 'task add +personal'
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/zoxide.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/zoxide.fish
new file mode 100644
index 00000000..8fbd5d61
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/zoxide.fish
@@ -0,0 +1,6 @@
+if type -q zoxide
+ echo Sourcing zoxide for fish shell...
+ zoxide init fish | source
+else
+ echo "zoxide not installed?"
+end
diff --git a/gemfeed/examples/conf/dotfiles/fish/conf.d/zsh.fish b/gemfeed/examples/conf/dotfiles/fish/conf.d/zsh.fish
new file mode 100644
index 00000000..06174d84
--- /dev/null
+++ b/gemfeed/examples/conf/dotfiles/fish/conf.d/zsh.fish
@@ -0,0 +1,12 @@
+# To run a ZSH function in fish, you can use the following function.
+function Z
+ touch ~/.nofish
+ zsh -i -c "$argv"
+ rm ~/.nofish
+end
+
+function B
+ touch ~/.nofish
+ bash -i -c "$argv"
+ rm ~/.nofish
+end