From c0f9ecf5e0b075db8e54ef1235ec80878e418398 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 2 Oct 2025 11:28:53 +0300 Subject: Update content for html --- gemfeed/examples/conf/dotfiles/README.md | 5 + gemfeed/examples/conf/dotfiles/Rexfile | 225 ++++++++++++++ gemfeed/examples/conf/dotfiles/bash/bash_profile | 3 + gemfeed/examples/conf/dotfiles/bash/bashrc | 15 + gemfeed/examples/conf/dotfiles/claude/CLAUDE.md | 2 + gemfeed/examples/conf/dotfiles/fish/conf.d/ai.fish | 39 +++ .../conf/dotfiles/fish/conf.d/alternatives.fish | 17 ++ .../examples/conf/dotfiles/fish/conf.d/config.fish | 31 ++ .../conf/dotfiles/fish/conf.d/dotfiles.fish | 48 +++ .../examples/conf/dotfiles/fish/conf.d/editor.fish | 44 +++ .../examples/conf/dotfiles/fish/conf.d/fuzzy.fish | 5 + .../examples/conf/dotfiles/fish/conf.d/games.fish | 15 + .../examples/conf/dotfiles/fish/conf.d/gos.fish | 6 + .../examples/conf/dotfiles/fish/conf.d/k8s.fish | 76 +++++ .../conf/dotfiles/fish/conf.d/quickedit.fish | 93 ++++++ .../conf/dotfiles/fish/conf.d/supersync.fish | 114 +++++++ .../conf/dotfiles/fish/conf.d/taskwarrior.fish | 121 ++++++++ .../examples/conf/dotfiles/fish/conf.d/timr.fish | 25 ++ .../conf/dotfiles/fish/conf.d/tmputils.fish | 54 ++++ .../examples/conf/dotfiles/fish/conf.d/tmux.fish | 94 ++++++ .../examples/conf/dotfiles/fish/conf.d/update.fish | 75 +++++ .../examples/conf/dotfiles/fish/conf.d/utils.fish | 142 +++++++++ .../conf/dotfiles/fish/conf.d/worktime.fish | 122 ++++++++ .../examples/conf/dotfiles/fish/conf.d/zoxide.fish | 6 + .../examples/conf/dotfiles/fish/conf.d/zsh.fish | 12 + gemfeed/examples/conf/dotfiles/ghostty/config | 17 ++ .../examples/conf/dotfiles/gitsyncer/config.json | 33 +++ gemfeed/examples/conf/dotfiles/helix/config.toml | 87 ++++++ .../examples/conf/dotfiles/helix/languages.toml | 203 +++++++++++++ gemfeed/examples/conf/dotfiles/nvim/init.lua | 70 +++++ .../examples/conf/dotfiles/pipewire/pipewire.conf | 257 ++++++++++++++++ gemfeed/examples/conf/dotfiles/scripts/README.md | 3 + gemfeed/examples/conf/dotfiles/scripts/ai | 7 + .../conf/dotfiles/scripts/brokenlinkfinder | 73 +++++ gemfeed/examples/conf/dotfiles/scripts/gvim | 7 + .../conf/dotfiles/scripts/hx.aichat-prompt | 9 + .../conf/dotfiles/scripts/hx.chatgpt-prompt | 3 + .../examples/conf/dotfiles/scripts/hx.goformatter | 3 + .../examples/conf/dotfiles/scripts/hx.hexai-prompt | 9 + .../conf/dotfiles/scripts/hx.nvim-copilot-prompt | 32 ++ gemfeed/examples/conf/dotfiles/scripts/hx.prompt | 14 + .../examples/conf/dotfiles/scripts/randomnote.rb | 30 ++ .../conf/dotfiles/scripts/taskwarriorfeeder.rb | 221 ++++++++++++++ gemfeed/examples/conf/dotfiles/signature | 2 + gemfeed/examples/conf/dotfiles/ssh/config | 21 ++ .../conf/dotfiles/sway/config.d/keyboard.conf | 6 + gemfeed/examples/conf/dotfiles/tmux/tmux.conf | 32 ++ .../examples/conf/dotfiles/tmux/tmux.local.conf | 2 + gemfeed/examples/conf/dotfiles/vale.ini | 6 + gemfeed/examples/conf/dotfiles/waybar/config.jsonc | 194 ++++++++++++ gemfeed/examples/conf/dotfiles/waybar/style.css | 326 +++++++++++++++++++++ 51 files changed, 3056 insertions(+) create mode 100644 gemfeed/examples/conf/dotfiles/README.md create mode 100644 gemfeed/examples/conf/dotfiles/Rexfile create mode 100644 gemfeed/examples/conf/dotfiles/bash/bash_profile create mode 100644 gemfeed/examples/conf/dotfiles/bash/bashrc create mode 100644 gemfeed/examples/conf/dotfiles/claude/CLAUDE.md create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/ai.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/alternatives.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/config.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/dotfiles.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/editor.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/fuzzy.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/games.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/gos.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/k8s.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/quickedit.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/supersync.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/taskwarrior.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/timr.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/tmputils.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/tmux.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/update.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/utils.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/worktime.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/zoxide.fish create mode 100644 gemfeed/examples/conf/dotfiles/fish/conf.d/zsh.fish create mode 100644 gemfeed/examples/conf/dotfiles/ghostty/config create mode 100644 gemfeed/examples/conf/dotfiles/gitsyncer/config.json create mode 100644 gemfeed/examples/conf/dotfiles/helix/config.toml create mode 100644 gemfeed/examples/conf/dotfiles/helix/languages.toml create mode 100644 gemfeed/examples/conf/dotfiles/nvim/init.lua create mode 100644 gemfeed/examples/conf/dotfiles/pipewire/pipewire.conf create mode 100644 gemfeed/examples/conf/dotfiles/scripts/README.md create mode 100755 gemfeed/examples/conf/dotfiles/scripts/ai create mode 100644 gemfeed/examples/conf/dotfiles/scripts/brokenlinkfinder create mode 100755 gemfeed/examples/conf/dotfiles/scripts/gvim create mode 100755 gemfeed/examples/conf/dotfiles/scripts/hx.aichat-prompt create mode 100755 gemfeed/examples/conf/dotfiles/scripts/hx.chatgpt-prompt create mode 100755 gemfeed/examples/conf/dotfiles/scripts/hx.goformatter create mode 100755 gemfeed/examples/conf/dotfiles/scripts/hx.hexai-prompt create mode 100755 gemfeed/examples/conf/dotfiles/scripts/hx.nvim-copilot-prompt create mode 100755 gemfeed/examples/conf/dotfiles/scripts/hx.prompt create mode 100644 gemfeed/examples/conf/dotfiles/scripts/randomnote.rb create mode 100644 gemfeed/examples/conf/dotfiles/scripts/taskwarriorfeeder.rb create mode 100644 gemfeed/examples/conf/dotfiles/signature create mode 100644 gemfeed/examples/conf/dotfiles/ssh/config create mode 100644 gemfeed/examples/conf/dotfiles/sway/config.d/keyboard.conf create mode 100644 gemfeed/examples/conf/dotfiles/tmux/tmux.conf create mode 100644 gemfeed/examples/conf/dotfiles/tmux/tmux.local.conf create mode 100644 gemfeed/examples/conf/dotfiles/vale.ini create mode 100644 gemfeed/examples/conf/dotfiles/waybar/config.jsonc create mode 100644 gemfeed/examples/conf/dotfiles/waybar/style.css (limited to 'gemfeed/examples/conf/dotfiles') diff --git a/gemfeed/examples/conf/dotfiles/README.md b/gemfeed/examples/conf/dotfiles/README.md new file mode 100644 index 00000000..6fdd2c25 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/README.md @@ -0,0 +1,5 @@ +# dotfiles + +These are all my dotfiles. I can install them locally on my laptop and/or workstation as well as remotely on any server. + +For local installation, also have a read through https://blog.ferki.it/2023/08/11/local-management-with-rex/ diff --git a/gemfeed/examples/conf/dotfiles/Rexfile b/gemfeed/examples/conf/dotfiles/Rexfile new file mode 100644 index 00000000..e0e002e5 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/Rexfile @@ -0,0 +1,225 @@ +use Rex -feature => [ '1.14', 'exec_autodie' ]; +use Rex::Logger; + +our $HOME = $ENV{HOME}; + +# In a public Git rapository. +our $DOT = "$HOME/git/conf/dotfiles"; + +# In a private Git repository. +our $DOT_PRIVATE = "$HOME/git/conf_private/dotfiles"; + +sub ensure_dir { + my ( $src_glob, $dst_dir, $file_mode ) = @_; + Rex::Logger::info("Ensure dir glob $src_glob"); + + file $dst_dir, + ensure => 'directory', + mode => '0700'; + + file "$dst_dir/" . basename($_), + ensure => 'present', + source => $_, + mode => $file_mode // '0640' + for glob $src_glob; +} + +sub ensure_file { + my ( $src_file, $dst_file, $file_mode ) = @_; + + file $dst_file, + ensure => 'present', + source => $src_file, + mode => $file_mode // '0640'; +} + +sub ensure { + my ( $src, $dst, $mode ) = @_; + ( $dst =~ /\/$/ ? \&ensure_dir : \&ensure_file )->( $src, $dst, $mode ); +} + +desc 'Install packages on Termux'; +task 'pkg_termux', sub { + my @pkgs = qw/ + ack-grep + ctags + fzf + golang + htop + make + nodejs + ripgrep + rsync + ruby + starship + tig + /; + + for my $pkg (@pkgs) { + Rex::Logger::info("Installing package $pkg"); + pkg $pkg, ensure => 'installed'; + } +}; + +desc 'Install packages on FreeBSD'; +task 'pkg_freebsd', sub { + my @pkgs = qw/ + bat + ctags + fzf + gmake + go + gron + htop + lynx + node + p5-ack + ripgrep + starship + tig + tmux + /; + + for my $pkg (@pkgs) { + Rex::Logger::info("Installing package $pkg"); + pkg $pkg, ensure => 'installed'; + } +}; + +desc 'Install packages on Fedora Linux'; +task 'pkg_fedora', sub { + my @pkgs = qw/ + opendoas + fd-find + nodejs-bash-language-server + fortune-mod + syncthing + ncdu + ack + fish + bat + ctags + fzf + golang + golang-x-tools-gopls + gpaste + gron + htop + java-latest-openjdk-devel + lynx + make + nodejs + perl-File-Slurp + procs + rakudo + Rex + ripgrep + ruby + strace + task2 + tig + tmux + dialect + chromium + strawberry + gnumeric + sway-config-fedora + sway + waybar + zathura + /; + + for my $pkg (@pkgs) { + Rex::Logger::info("Installing package $pkg"); + pkg $pkg, ensure => 'installed'; + } +}; + +desc 'Install ~/.config/helix'; +task 'home_helix', sub { ensure "$DOT/helix/*" => "$HOME/.config/helix/" }; + +desc 'Install ~/.config/ghostty'; +task 'home_ghostty', sub { ensure "$DOT/ghostty/*" => "$HOME/.config/ghostty/" }; + +desc 'Install ~/scripts'; +task 'home_scripts', sub { ensure "$DOT/scripts/*" => "$HOME/scripts/", '0750' }; + +desc 'Install ~/.ssh files'; +task 'home_ssh', sub { ensure "$DOT/ssh/config" => "$HOME/.ssh/config", '0600' }; + +desc 'Install BASH configuration'; +task 'home_bash', sub { + ensure "$DOT/bash/bash_profile" => "$HOME/.bash_profile"; + ensure "$DOT/bash/bashrc" => "$HOME/.bashrc"; +}; + +desc 'Install fish configuration'; +task 'home_fish', sub { + + # ensure "$DOT/fish/conf.d/*" => "$HOME/.config/fish/conf.d/"; + my $dest_dir = "$HOME/.config/fish/conf.d"; + if ( !-l $dest_dir ) { + if ( -d $dest_dir ) { + rename $dest_dir, "$dest_dir.old" or die "Could not rename $dest_dir: $!"; + } + symlink "$DOT/fish/conf.d" => $dest_dir or die "Could not create symlink: $!"; + } +}; + +desc 'Install gitsyncer configuration'; +task 'home_gitsyncer', sub { + my $dest_dir = "$HOME/.config/gitsyncer"; + symlink "$DOT/gitsyncer/" => $dest_dir or die "Could not create symlink: $!"; +}; + +sub isFileSymlink() { + my $file = shift; + return -l $file && -e $file; +} + +desc 'Vale and proselint'; +task 'home_vale', sub { + ensure "$DOT/vale.ini" => "$HOME/.vale.ini"; + say 'Now you can run "vale sync"'; +}; + +desc 'Install tmux configuration'; +task 'home_tmux', sub { + ensure "$DOT/tmux/*" => "$HOME/.config/tmux/"; +}; + +desc 'Install Sway configuration'; +task 'home_sway', sub { + ensure "$DOT/sway/config.d/*" => "$HOME/.config/sway/config.d/"; + ensure "$DOT/waybar/*" => "$HOME/.config/waybar/"; +}; + +desc 'Install my signature'; +task 'home_signature', sub { + ensure "$DOT/signature" => "$HOME/.signature"; +}; + +desc 'Install my calendar files'; +task 'home_calendar', sub { + unless ( -d $DOT_PRIVATE ) { + Rex::Logger::info( "$DOT_PRIVATE not there, skipping task", 'warn' ); + } + else { + ensure "$DOT_PRIVATE/calendar/*" => "$HOME/.calendar/"; + } +}; + +desc 'Install my Pipewire tuned for High-Res config'; +task 'home_pipewire', sub { + file "$HOME/.config/pipewire" => ensure => 'directory', + mode => '0750'; + ensure + "$DOT/pipewire/pipewire.conf" => "$HOME/.config/pipewire/pipewire.conf", + '0600'; +}; + +desc 'Install all my ~ files'; +task 'home', sub { + require Rex::TaskList; + run_task $_ for Rex::TaskList->create()->get_all_tasks('^home_'); +}; diff --git a/gemfeed/examples/conf/dotfiles/bash/bash_profile b/gemfeed/examples/conf/dotfiles/bash/bash_profile new file mode 100644 index 00000000..004a7b32 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/bash/bash_profile @@ -0,0 +1,3 @@ +if [ -f $HOME/.bashrc ]; then + source $HOME/.bashrc +fi diff --git a/gemfeed/examples/conf/dotfiles/bash/bashrc b/gemfeed/examples/conf/dotfiles/bash/bashrc new file mode 100644 index 00000000..ec2b10c3 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/bash/bashrc @@ -0,0 +1,15 @@ +# If shell is interactive +if [[ ! -z "$PS1" && ! -f $HOME/.nofish ]]; then + # Use fish if it's installed + if [ -e /opt/local/bin/fish ]; then + exec /opt/local/bin/fish + elif [ -e /bin/fish ]; then + exec /bin/fish + elif [ -e /usr/bin/fish ]; then + exec /usr/bin/fish + elif [ -e /data/data/com.termux/files/usr/bin/fish ]; then + exec /data/data/com.termux/files/usr/bin/fish + fi + + echo 'I might want to install fish on this host' +fi diff --git a/gemfeed/examples/conf/dotfiles/claude/CLAUDE.md b/gemfeed/examples/conf/dotfiles/claude/CLAUDE.md new file mode 100644 index 00000000..ffda0b71 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/claude/CLAUDE.md @@ -0,0 +1,2 @@ +- Whenever updating code, also update the comments in the code to reflect the reality and the reasoning. +- When a function reaches 50 lines of code or more, try to refactor it into several functions of about 30 lines each. In case of a go project, when main.go becomes too large, move code into the ./internal package. 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 diff --git a/gemfeed/examples/conf/dotfiles/ghostty/config b/gemfeed/examples/conf/dotfiles/ghostty/config new file mode 100644 index 00000000..e1095832 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/ghostty/config @@ -0,0 +1,17 @@ +window-decoration = true +copy-on-select = true +quick-terminal-position = bottom +quick-terminal-screen = mouse +shell-integration = zsh +bold-is-bright = true + +# Toggle window decorations only works on Linux! +keybind = ctrl+shift+d=toggle_window_decorations +keybind = ctrl+shift+f=toggle_fullscreen +keybind = ctrl+shift+g=reload_config +# Toggle quick terminal only supported for MacOS +keybind = global:ctrl+shift+t=toggle_quick_terminal +keybind = ctrl+shift+c=copy_to_clipboard +keybind = ctrl+shift+v=paste_from_clipboard +keybind = ctrl+shift+w=paste_from_selection + diff --git a/gemfeed/examples/conf/dotfiles/gitsyncer/config.json b/gemfeed/examples/conf/dotfiles/gitsyncer/config.json new file mode 100644 index 00000000..3ebb7780 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/gitsyncer/config.json @@ -0,0 +1,33 @@ +{ + "organizations": [ + { + "host": "git@codeberg.org", + "name": "snonux" + }, + { + "host": "git@github.com", + "name": "snonux" + }, + { + "host": "paul@t450:git", + "backupLocation": true + } + ], + "repositories": [], + "skip_releases": { + "fapi": [ + "0.0.1" + ] + }, + "exclude_from_showcase": [ + "bratwurstmitsenf", + "Adv360-Pro-ZMK", + "katana", + "playground", + "pages", + "nvim" + ], + "exclude_branches": [ + "^codex/" + ] +} \ No newline at end of file diff --git a/gemfeed/examples/conf/dotfiles/helix/config.toml b/gemfeed/examples/conf/dotfiles/helix/config.toml new file mode 100644 index 00000000..0d96c3ff --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/helix/config.toml @@ -0,0 +1,87 @@ +theme = "adwaita-dark" + +[editor] +bufferline = "always" +rulers = [80, 100, 120, 140] +line-number = "relative" +mouse = true +cursorline = true +cursorcolumn = true +continue-comments = false +completion-timeout = 2000 + +[editor.soft-wrap] +enable = true + +[editor.inline-diagnostics] +# cursor-line = "hint" + +[editor.auto-save] +focus-lost = true +after-delay.timeout = 3000 +after-delay.enable = true + +[editor.statusline] +left = ["version-control", "mode", "spinner", "file-name", "position" ] +center = ["diagnostics"] +right = ["selections", "file-encoding", "file-line-ending", "file-type"] + +[editor.lsp] +display-messages = true +display-inlay-hints = false + +[editor.cursor-shape] +normal = "block" +insert = "underline" +select = "bar" + +[editor.whitespace.render] +space = "none" +tab = "none" +newline = "none" + +[keys.normal] +D = ["ensure_selections_forward", "extend_to_line_end"] +S = ["ensure_selections_forward", "extend_to_line_start"] +0 = ["select_mode", "extend_to_file_start"] +G = ["ensure_selections_forward", "extend_to_file_end"] +"^" = ["move_prev_word_start", "move_next_word_end", "search_selection", "global_search"] +"ret" = "goto_word" + +C-c = "yank_main_selection_to_clipboard" +C-v = { b = "paste_clipboard_before", a = "paste_clipboard_after", r = ":clipboard-paste-replace" } +A-c = "toggle_comments" # Was originally C-c, so mapped to ALT now + +# Helix related helpers +C-h = { c = ":config-open", r = ":config-reload", C = ":run-shell-command cp -v ~/.config/helix/*.toml ~/git/conf/dotfiles/helix/", l = ":open ~/.config/helix/languages.toml", h = ":open ~/git/worktime/HelixCheat.md", L = ":log-open", d = ":theme default" } + +C-r = [ ":config-reload", ":reload-all" ] + +C-u = [ ":write", ":run-shell-command sh -c 'source ~/.hx.remote.source; scp $LOCAL_PATH $REMOTE_URI && echo Uploaded to $REMOTE_URI || echo Failed uploading to $REMOTE_URI'"] + +# Various helpers +C-s = { e = ":set-option soft-wrap.enable true", d = ":set-option soft-wrap.enable false", s = "save_selection" } + +# Buffer stuff +C-q = ":buffer-close" + +# AI commands are good here. +C-p = { c = ":pipe ai correct this sentence and only print out the corrected text", r = ":pipe ai restructure and reword the input and dont leave information out and only print out the new text", a = ":pipe ai rewrite this in a more casual style", n = ":pipe ai these are book notes of mine. correct the grammar and re-organize the notes. use bullet points for short information and whole paragraphs for longer one. the output must be in Gemini Gemtext format with the star * as the bullet point symbol and not the minus - . dont leave out any content.", p = ":pipe ai" } +# Will replace the above +C-a = ":pipe hexai-tmux-action" + +# Git commands +C-g = { d = ":run-shell-command git diff", p = ":run-shell-command git pull", u = ":run-shell-command git push", t = ":run-shell-command tmux new-window -n hx-git-tig tig", c = ":run-shell-command tmux split-window -v 'git commit -a'" } + +# Build commands +C-l = { m = ":run-shell-command make", d = ":run-shell-command go-task dev", r = ":run-shell-command tmux new-window -n hx-go-task-run 'go-task run'" } + +[keys.normal.space] +B = "file_picker_in_current_buffer_directory" +Q = [ ":cd ~/QuickEdit", "file_picker_in_current_directory" ] + +[keys.select] +"{" = "goto_prev_paragraph" +"}" = "goto_next_paragraph" +n = ["extend_search_next", "merge_selections"] +N = ["extend_search_prev", "merge_selections"] diff --git a/gemfeed/examples/conf/dotfiles/helix/languages.toml b/gemfeed/examples/conf/dotfiles/helix/languages.toml new file mode 100644 index 00000000..60e6a19c --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/helix/languages.toml @@ -0,0 +1,203 @@ +[[language]] +name = "hcl" +scope = "source.hcl" +injection-regex = "(hcl|tf|nomad)" +language-id = "terraform" +file-types = ["hcl", "tf", "nomad"] +comment-token = "#" +block-comment-tokens = { start = "/*", end = "*/" } +indent = { tab-width = 2, unit = " " } +language-servers = [ "terraform-ls", "hexai-lsp" ] +auto-format = true + +[[language]] +name = "go" +auto-format= true +diagnostic-severity = "hint" +formatter = { command = "hx.goformatter" } +language-servers = [ "gopls", "golangci-lint-lsp", "hexai-lsp" ] +[language-server.hexai-lsp] +command = "hexai-lsp" + +[language-server.gopls] +command = "gopls" + +[language-server.gopls.config.hints] +assignVariableTypes = true +compositeLiteralFields = true +constantValues = true +functionTypeParameters = true +parameterNames = true +rangeVariableTypes = true + +# go install github.com/nametake/golangci-lint-langserver@latest │ +[language-server.golangci-lint-lsp] +command = "golangci-lint-langserver" + +# golangci-lint-langserver depepds/calls golangci-lint +# go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest +[language-server.golangci-lint-lsp.config] +command = ["golangci-lint", "run", "--issues-exit-code=1"] +# command = ["golangci-lint", "run", "--out-format", "json", "--issues-exit-code=1"] + +[[language]] +name = "c" +scope = "source.c" +injection-regex = "c" +file-types = ["c", "h"] +comment-token = "//" +language-servers = [ "clangd", "hexai-lsp" ] +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "c" +source = { git = "https://github.com/tree-sitter/tree-sitter-c", rev = "7175a6dd5fc1cee660dce6fe23f6043d75af424a" } + +[language-server.clangd] +command = "clangd" + +[[language]] +name = "perl" +auto-format= true +formatter = { command = "perltidy", args = ["-l=120"] } +scope = "source.perl" +file-types = ["pl", "pm", "t", "psgi", "raku", "rakumod", "rakutest", "rakudoc", "nqp", "p6", "pl6", "pm6", { glob = "Rexfile" }] +shebangs = ["perl"] +comment-token = "#" +language-servers = [ "perlnavigator", "hexai-lsp" ] +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "perl" +source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "e99bb5283805db4cb86c964722d709df21b0ac16" } + +[[language]] +name = "pod" +scope = "source.pod" +injection-regex = "pod" +file-types = ["pod"] + +[[grammar]] +name = "pod" +source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "39da859947b94abdee43e431368e1ae975c0a424" } + +[[language]] +name = "ruby" +auto-format = true +scope = "source.ruby" +injection-regex = "ruby" +file-types = [ + "rb", + "rbs", + "rake", + "irb", + "gemspec", + { glob = "Gemfile" }, + { glob = "Rakefile" } +] +shebangs = ["ruby"] +comment-token = "#" +language-servers = [ "ruby-lsp", "solargraph", "rubocop", "hexai-lsp" ] +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "ruby" +source = { git = "https://github.com/tree-sitter/tree-sitter-ruby", rev = "206c7077164372c596ffa8eaadb9435c28941364" } + +[[language]] +name = "bash" +scope = "source.bash" +injection-regex = "(shell|bash|zsh|sh)" +file-types = [ + "sh", + "bash", + "zsh", + "zshenv", + "zlogin", + "zlogout", + "zprofile", + "zshrc", + "eclass", + "ebuild", + "bazelrc", + "Renviron", + "zsh-theme", + "ksh", + "cshrc", + "tcshrc", + "bashrc_Apple_Terminal", + "zshrc_Apple_Terminal", + { glob = "*zshrc*" }, +] +shebangs = ["sh", "bash", "dash", "zsh"] +comment-token = "#" +language-servers = [ "bash-language-server", "hexai-lsp" ] +indent = { tab-width = 2, unit = " " } + +[[language]] +name = "fish" +# scope = "source.fish" +# injection-regex = "(fish)" +# file-types = [ +# "fish", +# ] +# shebangs = ["fish" ] +# comment-token = "#" +language-servers = [ "fish-lsp", "hexai-lsp" ] +# indent =dth = 4, unit = " " } + +[[grammar]] +name = "bash" +source = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "275effdfc0edce774acf7d481f9ea195c6c403cd" } + +[language-server] +bash-language-server = { command = "bash-language-server", args = ["start"] } +vale-ls = { command = "vale-ls" } +ruby-lsp = { command = "ruby-lsp"} +rubocop = { command = "rubocop", args = ["--lsp"] } + +[[language]] +name = "markdown" +scope = "source.md" +injection-regex = "md|markdown" +file-types = ["md", "markdown", "mkd", "mdwn", "mdown", "markdn", "mdtxt", "mdtext", "workbook", "gmi", "tpl", "txt" ] +roots = [".marksman.toml"] +language-servers = [ "marksman", "markdown-oxide", "vale-ls", "hexai-lsp"] +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "markdown" +source = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "aaf76797aa8ecd9a5e78e0ec3681941de6c945ee", subpath = "tree-sitter-markdown" } + +[[language]] +name = "markdown.inline" +scope = "source.markdown.inline" +injection-regex = "markdown\\.inline" +file-types = [] +grammar = "markdown_inline" + +[[grammar]] +name = "markdown_inline" +source = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "aaf76797aa8ecd9a5e78e0ec3681941de6c945ee", subpath = "tree-sitter-markdown-inline" } + +[[language]] +name = "gemini" +scope = "source.gmi" +file-types = ["gmi", "tpl"] + +[[grammar]] +name = "gemini" +source = { git = "https://git.sr.ht/~nbsp/tree-sitter-gemini", rev = "3cc5e4bdf572d5df4277fc2e54d6299bd59a54b3" } + +[[language]] +name = "java" +scope = "source.java" +injection-regex = "java" +file-types = ["java", "jav", "pde"] +roots = ["pom.xml", "build.gradle", "build.gradle.kts"] +language-servers = [ "jdtls", "hexai-lsp" ] +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "java" +source = { git = "https://github.com/tree-sitter/tree-sitter-java", rev = "09d650def6cdf7f479f4b78f595e9ef5b58ce31e" } diff --git a/gemfeed/examples/conf/dotfiles/nvim/init.lua b/gemfeed/examples/conf/dotfiles/nvim/init.lua new file mode 100644 index 00000000..c3b8701d --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/nvim/init.lua @@ -0,0 +1,70 @@ + +require("CopilotChat").setup { + -- See Configuration section for options +} + +local timer = vim.loop.new_timer() -- Initialize the timer + +vim.api.nvim_create_autocmd("BufEnter", { + pattern = "*", + callback = function() + if vim.bo.filetype == "copilot-chat" then + local copilot_chat_buf = vim.api.nvim_get_current_buf() + vim.cmd("wincmd _") -- Maximize height + vim.cmd("wincmd |") -- Maximize width + local file_path = vim.fn.expand("~/.copilot_chat_output.txt") + + -- Start the timer with a 2-second interval + timer:start(1000, 1000, vim.schedule_wrap(function() + if copilot_chat_buf and vim.api.nvim_buf_is_valid(copilot_chat_buf) then + -- Get all lines in the buffer + local lines = vim.api.nvim_buf_get_lines(copilot_chat_buf, 0, -1, false) + + -- Check for the stopping condition + local user_line_count = 0 + for _, line in ipairs(lines) do + if line:find("^## User") then + user_line_count = user_line_count + 1 + if user_line_count >= 2 then + print("Stopping write process: Two '## User' lines detected.") + timer:stop() + -- Write the buffer content to the file + vim.api.nvim_buf_call(copilot_chat_buf, function() + vim.cmd("write! " .. file_path) + end) + vim.cmd("qa!") + return + end + end + end + + -- Write the buffer content to the file + vim.api.nvim_buf_call(copilot_chat_buf, function() + vim.cmd("write! " .. file_path) + end) + end + end)) + end + end, +}) + +vim.api.nvim_create_user_command('CopilotAsk', function(args) + local chat = require("CopilotChat") + local input + if args.args and args.args ~= "" then + input = args.args + else + local input_file = os.getenv("HOME") .. "/.copilot_chat_input.txt" + local file = io.open(input_file, "r") + if file then + input = file:read("*all") + file:close() + else + print("Error: Unable to open input file.") + return + end + end + chat.ask(input) +end, { force = true, range = true, nargs = "?" }) + + diff --git a/gemfeed/examples/conf/dotfiles/pipewire/pipewire.conf b/gemfeed/examples/conf/dotfiles/pipewire/pipewire.conf new file mode 100644 index 00000000..a97c99e7 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/pipewire/pipewire.conf @@ -0,0 +1,257 @@ +# Daemon config file for PipeWire version "0.3.51" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/pipewire.conf.d/ for system-wide changes or in +# ~/.config/pipewire/pipewire.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #library.name.system = support/libspa-support + #context.data-loop.library.name.system = support/libspa-support + #support.dbus = true + #link.max-buffers = 64 + link.max-buffers = 16 # version < 3 clients can't handle more + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + #clock.power-of-two-quantum = true + #log.level = 2 + #cpu.zero.denormals = false + + core.daemon = true # listening for socket connections + core.name = pipewire-0 # core name and socket name + + ## Properties for the DSP configuration. + default.clock.rate = 48000 + default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 352800 384000 ] + #default.clock.quantum = 1024 + default.clock.min-quantum = 16 + #default.clock.max-quantum = 2048 + #default.clock.quantum-limit = 8192 + #default.video.width = 640 + #default.video.height = 480 + #default.video.rate.num = 25 + #default.video.rate.denom = 1 + # + #settings.check-quantum = false + #settings.check-rate = false + # + # These overrides are only applied when running in a vm. + vm.overrides = { + default.clock.min-quantum = 1024 + } +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + api.alsa.* = alsa/libspa-alsa + api.v4l2.* = v4l2/libspa-v4l2 + api.libcamera.* = libcamera/libspa-libcamera + api.bluez5.* = bluez5/libspa-bluez5 + api.vulkan.* = vulkan/libspa-vulkan + api.jack.* = jack/libspa-jack + support.* = support/libspa-support + #videotestsrc = videotestsrc/libspa-videotestsrc + #audiotestsrc = audiotestsrc/libspa-audiotestsrc +} + +context.modules = [ + #{ name = + # [ args = { = ... } ] + # [ flags = [ [ ifexists ] [ nofail ] ] + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # + + # Uses realtime scheduling to boost the audio thread priorities. This uses + # RTKit if the user doesn't have permission to use regular realtime + # scheduling. + { name = libpipewire-module-rt + args = { + nice.level = -11 + #rt.prio = 88 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # The profile module. Allows application to access profiler + # and performance data. It provides an interface that is used + # by pw-top and pw-profiler. + { name = libpipewire-module-profiler } + + # Allows applications to create metadata objects. It creates + # a factory for Metadata objects. + { name = libpipewire-module-metadata } + + # Creates a factory for making devices that run in the + # context of the PipeWire server. + { name = libpipewire-module-spa-device-factory } + + # Creates a factory for making nodes that run in the + # context of the PipeWire server. + { name = libpipewire-module-spa-node-factory } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Allows creating devices that run in the context of the + # client. Is used by the session manager. + { name = libpipewire-module-client-device } + + # The portal module monitors the PID of the portal process + # and tags connections with the same PID as portal + # connections. + { name = libpipewire-module-portal + flags = [ ifexists nofail ] + } + + # The access module can perform access checks and block + # new clients. + { name = libpipewire-module-access + args = { + # access.allowed to list an array of paths of allowed + # apps. + #access.allowed = [ + # /usr/bin/pipewire-media-session + #] + + # An array of rejected paths. + #access.rejected = [ ] + + # An array of paths with restricted access. + #access.restricted = [ ] + + # Anything not in the above lists gets assigned the + # access.force permission. + #access.force = flatpak + } + } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } + + # Makes a factory for creating links between ports. + { name = libpipewire-module-link-factory } + + # Provides factories to make session manager objects. + { name = libpipewire-module-session-manager } + + # Use libcanberra to play X11 Bell + #{ name = libpipewire-module-x11-bell + # args = { + # #sink.name = "" + # #sample.name = "bell-window-system" + # #x11.display = null + # #x11.xauthority = null + # } + #} +] + +context.objects = [ + #{ factory = + # [ args = { = ... } ] + # [ flags = [ [ nofail ] ] + #} + # + # Creates an object from a PipeWire factory with the given parameters. + # If nofail is given, errors are ignored (and no object is created). + # + #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } } + #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] } + #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } } + #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } } + #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } } + #{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } } + + # A default dummy driver. This handles nodes marked with the "node.always-driver" + # property when no other driver is currently active. JACK clients need this. + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Dummy-Driver + node.group = pipewire.dummy + priority.driver = 20000 + } + } + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Freewheel-Driver + priority.driver = 19000 + node.group = pipewire.freewheel + node.freewheel = true + } + } + # This creates a new Source node. It will have input ports + # that you can link, to provide audio for this source. + #{ factory = adapter + # args = { + # factory.name = support.null-audio-sink + # node.name = "my-mic" + # node.description = "Microphone" + # media.class = "Audio/Source/Virtual" + # audio.position = "FL,FR" + # } + #} + + # This creates a single PCM source device for the given + # alsa device path hw:0. You can change source to sink + # to make a sink in the same way. + #{ factory = adapter + # args = { + # factory.name = api.alsa.pcm.source + # node.name = "alsa-source" + # node.description = "PCM Source" + # media.class = "Audio/Source" + # api.alsa.path = "hw:0" + # api.alsa.period-size = 1024 + # api.alsa.headroom = 0 + # api.alsa.disable-mmap = false + # api.alsa.disable-batch = false + # audio.format = "S16LE" + # audio.rate = 48000 + # audio.channels = 2 + # audio.position = "FL,FR" + # } + #} +] + +context.exec = [ + #{ path = [ args = "" ] } + # + # Execute the given program with arguments. + # + # You can optionally start the session manager here, + # but it is better to start it as a systemd service. + # Run the session manager with -h for options. + # + #{ path = "/usr/bin/pipewire-media-session" args = "" } + # + # You can optionally start the pulseaudio-server here as well + # but it is better to start it as a systemd service. + # It can be interesting to start another daemon here that listens + # on another address with the -a option (eg. -a tcp:4713). + # + #{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" } +] diff --git a/gemfeed/examples/conf/dotfiles/scripts/README.md b/gemfeed/examples/conf/dotfiles/scripts/README.md new file mode 100644 index 00000000..ecbc8ec0 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/README.md @@ -0,0 +1,3 @@ +# Scripts installed to my ~/scripts + +Mostly quick-n-dirty ones! diff --git a/gemfeed/examples/conf/dotfiles/scripts/ai b/gemfeed/examples/conf/dotfiles/scripts/ai new file mode 100755 index 00000000..abcf4909 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/ai @@ -0,0 +1,7 @@ +#!/usr/bin/env zsh + +if [ $(uname) = Darwin ]; then + exec hx.nvim-copilot-prompt "$@" +else + exec hx.hexai-prompt "$@" +fi diff --git a/gemfeed/examples/conf/dotfiles/scripts/brokenlinkfinder b/gemfeed/examples/conf/dotfiles/scripts/brokenlinkfinder new file mode 100644 index 00000000..7fe15765 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/brokenlinkfinder @@ -0,0 +1,73 @@ +#!/usr/bin/env ruby + +require 'net/http' +require 'uri' +require 'nokogiri' +require 'set' + +# Method to fetch and parse HTML from a URL +def fetch_html(url) + response = Net::HTTP.get_response(URI(url)) + response.body if response.is_a?(Net::HTTPSuccess) +rescue StandardError => e + puts "Error fetching #{url}: #{e.message}" + nil +end + +# Method to find and check links on a page +def check_links(url, domain) + html = fetch_html(url) + return unless html + + checked = Set.new + broken = Set.new + + document = Nokogiri::HTML(html) + links = document.css('a').map { |link| link['href'] }.compact + + internal_links = links.select do |link| + link.start_with?('/') || link.start_with?('./') || URI(link).host == domain + end + puts "Internal links: #{internal_links}" + + internal_links.uniq.each do |link| + full_url = link.start_with?('/') || link.start_with?('./') ? "#{url}#{link}" : link + full_url.sub!('./', '/') + next if checked.include?(full_url) + + broken << full_url unless check_link(full_url) + checked << full_url + end + + broken +end + +# Method to check if a link is broken +def check_link(url) + uri = URI(url) + response = Net::HTTP.get_response(uri) + + if response.is_a?(Net::HTTPSuccess) + puts "Working link: #{url}" + true + else + puts "Broken link: #{url} (HTTP #{response.code})" + false + end +rescue StandardError => e + puts "Error checking #{url}: #{e.message}" + false +end + +# Main program +if ARGV.length != 1 + puts 'Usage: ruby brokenlinkfinder.rb ' + exit +end + +start_url = ARGV.first +domain = URI(start_url).host + +check_links(start_url, domain).each do |broken| + puts "Broken: #{broken}" +end diff --git a/gemfeed/examples/conf/dotfiles/scripts/gvim b/gemfeed/examples/conf/dotfiles/scripts/gvim new file mode 100755 index 00000000..5777a7ce --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/gvim @@ -0,0 +1,7 @@ +#!/bin/bash +# Hack so qutebrowser starts an editor (Helix) in a new ghostty terminal. + +declare -r FILE_PATH="$2" +#echo "$@" > /tmp/params.txt + +ghostty -e "hx $FILE_PATH" diff --git a/gemfeed/examples/conf/dotfiles/scripts/hx.aichat-prompt b/gemfeed/examples/conf/dotfiles/scripts/hx.aichat-prompt new file mode 100755 index 00000000..4cafcf5d --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/hx.aichat-prompt @@ -0,0 +1,9 @@ +#!/usr/bin/env zsh + +declare -xr INSTRUCTIONS='Answer only. If it is code, code only without code-block at the beginning and the end.' + +if [[ $# -eq 0 ]]; then + aichat "$(hx.prompt). $INSTRUCTIONS" +else + aichat "$@. $INSTRUCTIONS" +fi diff --git a/gemfeed/examples/conf/dotfiles/scripts/hx.chatgpt-prompt b/gemfeed/examples/conf/dotfiles/scripts/hx.chatgpt-prompt new file mode 100755 index 00000000..e4b6047f --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/hx.chatgpt-prompt @@ -0,0 +1,3 @@ +#!/usr/bin/env zsh + +chatgpt "$(hx.prompt). Answer only. If it is code, code only without code-block at the beginning and the end." diff --git a/gemfeed/examples/conf/dotfiles/scripts/hx.goformatter b/gemfeed/examples/conf/dotfiles/scripts/hx.goformatter new file mode 100755 index 00000000..028fbb25 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/hx.goformatter @@ -0,0 +1,3 @@ +#!/bin/sh + +goimports | gofumpt diff --git a/gemfeed/examples/conf/dotfiles/scripts/hx.hexai-prompt b/gemfeed/examples/conf/dotfiles/scripts/hx.hexai-prompt new file mode 100755 index 00000000..ef413c0a --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/hx.hexai-prompt @@ -0,0 +1,9 @@ +#!/usr/bin/env zsh + +declare -xr INSTRUCTIONS='Answer only. If it is code, code only without code-block at the beginning and the end.' + +if [[ $# -eq 0 ]]; then + hexai "$(hx.prompt). $INSTRUCTIONS" 2>/dev/null +else + hexai "$@. $INSTRUCTIONS" 2>/dev/null +fi diff --git a/gemfeed/examples/conf/dotfiles/scripts/hx.nvim-copilot-prompt b/gemfeed/examples/conf/dotfiles/scripts/hx.nvim-copilot-prompt new file mode 100755 index 00000000..dcb28376 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/hx.nvim-copilot-prompt @@ -0,0 +1,32 @@ +#!/usr/bin/env zsh + +declare -r STDIN_FILE=~/.copilot_prompt_stdin.txt +declare -r INPUT_FILE=~/.copilot_chat_input.txt +declare -r OUTPUT_FILE=~/.copilot_chat_output.txt +declare INPUT_PROMPT + +if [ -f $OUTPUT_FILE.done ]; then + rm $OUTPUT_FILE.done +fi +cat > $STDIN_FILE &>/dev/null + +if [ $# -eq 0 ]; then + INPUT_PROMPT="$(hx.prompt)" +else + INPUT_PROMPT="$@" +fi + +cat < $INPUT_FILE +$INPUT_PROMPT for the following: + +$(cat $STDIN_FILE) + +If the result is code, print out the code only, don't print the \`\`\`-markers around the code block. +INPUT_FILE + +tmux split-window -v "nvim +':CopilotAsk'; mv $OUTPUT_FILE $OUTPUT_FILE.done" + +while [ ! -f "$OUTPUT_FILE.done" ]; do + sleep 0.2 +done +sed -n '/^## Copilot/,/^## User/ { /^## Copilot/d; /\[file:/d; /^## User/d; p; }' $OUTPUT_FILE.done diff --git a/gemfeed/examples/conf/dotfiles/scripts/hx.prompt b/gemfeed/examples/conf/dotfiles/scripts/hx.prompt new file mode 100755 index 00000000..8dd14dd3 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/hx.prompt @@ -0,0 +1,14 @@ +#!/usr/bin/env zsh + +declare -r REPLY_FILE=~/.hx-prompt-reply +if [ -f "$REPLY_FILE" ]; then + rm "$REPLY_FILE" +fi + +tmux split-window -v "touch $REPLY_FILE.tmp; hx $REPLY_FILE.tmp; mv $REPLY_FILE.tmp $REPLY_FILE" + +while [ ! -f "$REPLY_FILE" ]; do + sleep 0.2 +done + +cat "$REPLY_FILE" diff --git a/gemfeed/examples/conf/dotfiles/scripts/randomnote.rb b/gemfeed/examples/conf/dotfiles/scripts/randomnote.rb new file mode 100644 index 00000000..b0c1b490 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/randomnote.rb @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby + +NOTES_DIR = "#{ENV['HOME']}/git/foo.zone-content/gemtext/notes" +BOOK_PATH = "#{ENV['HOME']}/Buecher/Diverse/Search-Inside-Yourself.txt" +MIN_PERCENTAGE = 80 +MIN_LENGTH = 10 + +class String + CLEAN_PATTERN = [ + /\d\d\d-\d\d-\d\d/, /[^A-Za-z0-9!.;,?'" @]/, + /http.?:\/\/\S+/, /\S+\.gmi/, /^\./, /^\d/, + ] + def clean + CLEAN_PATTERN.each {|p| gsub! p, '' } + gsub(/\s+/, ' ').strip + end + def letter_percentage?(threshold) = threshold <= (100 * count("A-Za-z")) / length +end + +begin + srand Random.new_seed + puts File.read((Dir["#{NOTES_DIR}/*.gmi"] + [BOOK_PATH]).shuffle.sample) + .split("\n") + .map(&:clean) + .select{ |l| l.length >= MIN_LENGTH } + .reject{ |l| l.match?(/(Published at|EMail your comments)/) } + .reject{ |l| l.match?(/'|book notes/) } + .select{ |l| l.letter_percentage?(MIN_PERCENTAGE) } + .shuffle.sample +end diff --git a/gemfeed/examples/conf/dotfiles/scripts/taskwarriorfeeder.rb b/gemfeed/examples/conf/dotfiles/scripts/taskwarriorfeeder.rb new file mode 100644 index 00000000..8e3096ea --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/scripts/taskwarriorfeeder.rb @@ -0,0 +1,221 @@ +#!/usr/bin/env ruby + +require 'optparse' +require 'digest' +require 'json' +require 'set' + +PERSONAL_TIMESPAN_D = 30 +WORK_TIMESPAN_D = 14 +WORKTIME_DIR = "#{ENV['HOME']}/git/worktime".freeze +GOS_DIR = "#{ENV['HOME']}/.gosdir".freeze +MAX_PENDING_RANDOM_TASKS = 11 + +def maybe? + [true, false].sample +end + +def run_from_personal_device? + `uname`.chomp == 'Linux' +end + +def random_count + MAX_PENDING_RANDOM_TASKS - `task status:pending +random count`.to_i +end + +def notes(notes_dirs, prefix, dry) + notes_dirs.each do |notes_dir| + Dir["#{notes_dir}/#{prefix}-*"].each do |notes_file| + match = File.read(notes_file).strip.match(/(?\d+)? *(?[A-Z]?[a-z,-:]+) *(?.*)/m) + next unless match + + tags = match[:tag].split(',') + [prefix] + due = if match[:due].nil? + tags.include?('track') ? '1year' : "#{rand(0..PERSONAL_TIMESPAN_D)}d" + else + "#{match[:due]}d" + end + yield tags, match[:body], due + File.delete(notes_file) unless dry + end + end +end + +def random_quote(md_file) + tag = File.basename(md_file, '.md').downcase + lines = File.readlines(md_file) + + match = lines.first.match(/\((\d+)\)/) + timespan = run_from_personal_device? ? PERSONAL_TIMESPAN_D : WORK_TIMESPAN_D + timespan = match ? match[1].to_i : timespan + + quote = lines.select { |l| l.start_with? '*' }.map { |l| l.sub(/\* +/, '') }.sample + tags = [tag, 'random'] + tags << 'work' if maybe? and maybe? + yield tags, quote.chomp, "#{rand(0..timespan)}d" +end + +def run!(cmd, dry) + puts cmd + return if dry + + puts `#{cmd}` + raise "Command '#{cmd}' failed with #{$?.exitstatus}" if $?.exitstatus != 0 +rescue StandardError => e + puts "Error running command '#{cmd}': #{e.message}" + exit 1 +end + +def skill_add!(skills_str, dry) + skills_file = "#{WORKTIME_DIR}/skills.txt" + skills_str.split(',').map(&:strip).each { skills[_1.to_s.downcase] = _1 } + + File.foreach(skills_file) do |line| + line.chomp! + skills[line.downcase] = line + end + File.open("#{skills_file}.tmp", 'w') do |file| + skills.each_value { |skill| file.puts(skill) } + end + return if dry + + File.rename("#{skills_file}.tmp", skills_file) +end + +def worklog_add!(tag, quote, due, dry) + file = "#{WORKTIME_DIR}/wl-#{Time.now.to_i}n.txt" + content = "#{due.chomp 'd'} #{tag} #{quote}" + + puts "#{file}: #{content}" + File.write(file, content) unless dry +end + +# Queue to Gos https://codeberg.org/snonux/gos +def gos_queue!(tags, message, dry) + tags.delete('share') + platforms = [] + %w[linkedin li mastodon ma noop no].select { tags.include?(_1) }.each do |platform| + platforms << platform + tags.delete(platform) + end + unless platforms.empty? + platforms = %w[share] + platforms + tags = ["#{platforms.join(':')}"] + tags + end + tags = %w[share] + tags if tags.size == 1 && !tags.first.start_with?('share') + tags_str = tags.join(',') + + message = "#{tags_str.empty? ? '' : "#{tags_str} "}#{message}" + file = "#{GOS_DIR}/#{Digest::MD5.hexdigest(message)}.txt" + puts "Writing #{file} with #{message}" + File.write(file, message) unless dry +end + +def task_add!(tags, quote, due, dry) + if quote.empty? + puts 'Not adding task with empty quote' + return + end + if tags.include?('tr') + tags << 'track' + tags.delete('tr') + end + tags << 'work' if tags.include?('mentoring') || tags.include?('productivity') + tags.uniq! + + if tags.include?('task') + run! "task #{quote}", dry + else + project = tags.find { |t| t =~ /^[A-Z]/ } + project = if project.nil? + '' + else + tags.delete(project) + " project:#{project.downcase}" + end + priority = tags.include?('high') ? 'H' : '' + run! "task add due:#{due} priority:#{priority}#{project} +#{tags.join(' +')} '#{quote.gsub("'", '"')}'", dry + end +end + +def task_schedule!(id, due, dry) + run! "timeout 5s task modify #{id} due:#{due}", dry +end + +# Randomly schedule all unscheduled tasks but the ones with the +unsched tag +def unscheduled_tasks + lines = `task -lowhigh -unsched -nosched -notes -note -meeting -track due: 2>/dev/null`.split("\n").drop(1) + lines.pop + lines.map { |foo| foo.split.first }.each do |id| + yield id if id.to_i.positive? + end +end + +begin + opts = { + quotes_dir: "#{ENV['HOME']}/Notes/HabitsAndQuotes", + notes_dirs: "#{ENV['HOME']}/Notes,#{ENV['HOME']}/Notes/Quicklogger,#{ENV['HOME']}/git/worktime", + dry_run: false, + no_random: false + } + + opt_parser = OptionParser.new do |o| + o.banner = 'Usage: ruby taskwarriorfeeder.rb [options]' + o.on('-d', '--quotes-dir DIR', 'The quotes directory') { |v| opts[:quotes_dir] = v } + o.on('-n', '--notes-dirs DIR1,DIR2,...', 'The notes directories') { |v| opts[:notes_dirs] = v } + o.on('-D', '--dry-run', 'Dry run mode') { opts[:dry_run] = true } + o.on('-R', '--no-randoms', 'No random entries') { opts[:no_random] = true } + o.on_tail('-h', '--help', 'Show this help message and exit') { puts o and exit } + end + + opt_parser.parse!(ARGV) + core_habits_md_file = "#{opts[:quotes_dir]}/CoreHabits.md" + + (run_from_personal_device? ? %w[ql pl] : %w[wl]).each do |prefix| + notes(opts[:notes_dirs].split(','), prefix, opts[:dry_run]) do |tags, note, due| + if tags.include?('skill') || tags.include?('skills') + skill_add!(note, opts[:dry_run]) + elsif tags.include? 'work' + worklog_add!(:log, note, due, opts[:dry_run]) + elsif tags.any? { |tag| tag.start_with?('share') } + gos_queue!(tags, note, opts[:dry_run]) + else + task_add!(tags, note, due, opts[:dry_run]) + end + end + end + + unless opts[:no_random] + if File.exist?(core_habits_md_file) + random_quote(core_habits_md_file) do |tags, quote, due| + task_add!(tags, quote, due, opts[:dry_run]) + end + end + count = random_count + + Dir["#{opts[:quotes_dir]}/*.md"].shuffle.each do |md_file| + next unless maybe? + break if count <= 0 + + random_quote(md_file) do |tags, quote, due| + task_add!(tags, quote, due, opts[:dry_run]) + count -= 1 + end + end + end + + if Dir.exist?(GOS_DIR) && !opts[:dry_run] + Dir["#{WORKTIME_DIR}/tw-gos-*.json"].each do |tw_gos| + JSON.parse(File.read(tw_gos)).each do |entry| + gos_queue!(entry['tags'], entry['description'], opts[:dry_run]) + end + File.delete(tw_gos) + rescue StandardError => e + puts e + end + end + + unscheduled_tasks do |id| + task_schedule!(id, "#{rand(0..PERSONAL_TIMESPAN_D)}d", opts[:dry_run]) + end +end diff --git a/gemfeed/examples/conf/dotfiles/signature b/gemfeed/examples/conf/dotfiles/signature new file mode 100644 index 00000000..8031719e --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/signature @@ -0,0 +1,2 @@ +Paul Buetow +paul.buetow.org diff --git a/gemfeed/examples/conf/dotfiles/ssh/config b/gemfeed/examples/conf/dotfiles/ssh/config new file mode 100644 index 00000000..5b4b250e --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/ssh/config @@ -0,0 +1,21 @@ +ControlPath ~/.ssh/cp-%C +ControlMaster auto +#UseKeychain yes +AddKeysToAgent yes +ControlPersist 60m +#StrictHostKeyChecking no + +Host blowfish.buetow.org +User rex +Port 2 + +Host fishfinger.buetow.org +User rex +Port 2 + +Host *.aws.buetow.org +User ec2-user +Port 22 + +Host *.buetow.org +Port 2 diff --git a/gemfeed/examples/conf/dotfiles/sway/config.d/keyboard.conf b/gemfeed/examples/conf/dotfiles/sway/config.d/keyboard.conf new file mode 100644 index 00000000..6b10a788 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/sway/config.d/keyboard.conf @@ -0,0 +1,6 @@ +input "type:keyboard" { + xkb_layout us,gb,de + xkb_options grp:win_space_toggle +} + +input * xkb_options "caps:escape" diff --git a/gemfeed/examples/conf/dotfiles/tmux/tmux.conf b/gemfeed/examples/conf/dotfiles/tmux/tmux.conf new file mode 100644 index 00000000..42c53866 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/tmux/tmux.conf @@ -0,0 +1,32 @@ +source ~/.config/tmux/tmux.local.conf + +set-option -g allow-rename off +set-option -g history-limit 100000 +set-option -s escape-time 0 +set-option -g set-titles on + +set-window-option -g mode-keys vi + +bind-key h select-pane -L +bind-key j select-pane -D +bind-key k select-pane -U +bind-key l select-pane -R + +bind-key H resize-pane -L 5 +bind-key J resize-pane -D 5 +bind-key K resize-pane -U 5 +bind-key L resize-pane -R 5 + +bind-key b break-pane -d +bind-key c new-window -c '#{pane_current_path}' +bind-key F new-window -n "session-switcher" "tmux list-sessions | fzf | cut -d: -f1 | xargs tmux switch-client -t" +bind-key p setw synchronize-panes off +bind-key P setw synchronize-panes on +bind-key r source-file ~/.tmux.conf \; display-message "~/.tmux.conf reloaded" +bind-key T choose-tree + +set-option -g pane-active-border-style fg=magenta,bold + +set -g status-right '#{@hexai_status} #[fg=colour8]| %H:%M' +set -g status-right-length 120 +set-environment -g HEXAI_TMUX_STATUS_THEME white-on-purple diff --git a/gemfeed/examples/conf/dotfiles/tmux/tmux.local.conf b/gemfeed/examples/conf/dotfiles/tmux/tmux.local.conf new file mode 100644 index 00000000..adb6294b --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/tmux/tmux.local.conf @@ -0,0 +1,2 @@ +bind-key -T copy-mode-vi 'v' send -X begin-selection +bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel diff --git a/gemfeed/examples/conf/dotfiles/vale.ini b/gemfeed/examples/conf/dotfiles/vale.ini new file mode 100644 index 00000000..3b396788 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/vale.ini @@ -0,0 +1,6 @@ +StylesPath = styles +MinAlertLevel = suggestion +Packages = Microsoft, proselint + +[*] +BasedOnStyles = Vale, Microsoft, proselint diff --git a/gemfeed/examples/conf/dotfiles/waybar/config.jsonc b/gemfeed/examples/conf/dotfiles/waybar/config.jsonc new file mode 100644 index 00000000..db2aeea6 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/waybar/config.jsonc @@ -0,0 +1,194 @@ +// -*- mode: jsonc -*- +{ + // "layer": "top", // Waybar at top layer + // "position": "bottom", // Waybar position (top|bottom|left|right) + "height": 20, // Waybar height (to be removed for auto height) + // "width": 1280, // Waybar width + "spacing": 1, // Gaps between modules (4px) + // Choose the order of the modules + "modules-left": [ + "sway/workspaces", + "sway/mode", + "sway/scratchpad" + ], + "modules-center": [ + ], + "modules-right": [ + "idle_inhibitor", + "pulseaudio", + "network", + "power-profiles-daemon", + "temperature", + "sway/language", + "battery", + "clock", + "tray" + ], + // Modules configuration + // "sway/workspaces": { + // "disable-scroll": true, + // "all-outputs": true, + // "warp-on-scroll": false, + // "format": "{name}: {icon}", + // "format-icons": { + // "1": "", + // "2": "", + // "3": "", + // "4": "", + // "5": "", + // "urgent": "", + // "focused": "", + // "default": "" + // } + // }, + "keyboard-state": { + "numlock": true, + "capslock": true, + "format": "{name} {icon}", + "format-icons": { + "locked": "", + "unlocked": "" + } + }, + "sway/mode": { + "format": "{}" + }, + "sway/scratchpad": { + "format": "{icon} {count}", + "show-empty": false, + "format-icons": ["", ""], + "tooltip": true, + "tooltip-format": "{app}: {title}" + }, + "mpd": { + "format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ", + "format-disconnected": "Disconnected ", + "format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ", + "unknown-tag": "N/A", + "interval": 5, + "consume-icons": { + "on": " " + }, + "random-icons": { + "off": " ", + "on": " " + }, + "repeat-icons": { + "on": " " + }, + "single-icons": { + "on": "1 " + }, + "state-icons": { + "paused": "", + "playing": "" + }, + "tooltip-format": "MPD (connected)", + "tooltip-format-disconnected": "MPD (disconnected)" + }, + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "", + "deactivated": "" + } + }, + "tray": { + // "icon-size": 21, + "spacing": 10 + }, + "clock": { + // "timezone": "America/New_York", + "tooltip-format": "{:%Y %B}\n{calendar}", + "format-alt": "{:%Y-%m-%d}" + }, + "cpu": { + "format": "{usage}% ", + "tooltip": false + }, + "memory": { + "format": "{}% " + }, + "temperature": { + // "thermal-zone": 2, + // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", + "critical-threshold": 80, + // "format-critical": "{temperatureC}°C {icon}", + "format": "{temperatureC}°C {icon}", + "format-icons": ["", "", ""] + }, + "backlight": { + // "device": "acpi_video1", + "format": "{percent}% {icon}", + "format-icons": ["🌑", "🌘", "🌗", "🌖", "🌕"] + }, + "battery": { + "states": { + // "good": 95, + "warning": 30, + "critical": 15 + }, + "format": "{capacity}% {icon}", + "format-full": "{capacity}% {icon}", + "format-charging": "{capacity}% ", + "format-plugged": "{capacity}% ", + "format-alt": "{time} {icon}", + // "format-good": "", // An empty format will hide the module + // "format-full": "", + "format-icons": ["", "", "", "", ""] + }, + "battery#bat2": { + "bat": "BAT2" + }, + "power-profiles-daemon": { + "format": "{icon}", + "tooltip-format": "Power profile: {profile}\nDriver: {driver}", + "tooltip": true, + "format-icons": { + "default": "", + "performance": "", + "balanced": "", + "power-saver": "" + } + }, + "network": { + // "interface": "wlp2*", // (Optional) To force the use of this interface + "format-wifi": "{essid} ({signalStrength}%) ", + "format-ethernet": "{ipaddr}/{cidr} ", + "tooltip-format": "{ifname} via {gwaddr} ", + "format-linked": "{ifname} (No IP) ", + "format-disconnected": "Disconnected ⚠", + "format-alt": "{ifname}: {ipaddr}/{cidr}" + }, + "pulseaudio": { + // "scroll-step": 1, // %, can be a float + "format": "{volume}% {icon} {format_source}", + "format-bluetooth": "{volume}% {icon} {format_source}", + "format-bluetooth-muted": " {icon} {format_source}", + "format-muted": " {format_source}", + "format-source": "{volume}% ", + "format-source-muted": "", + "format-icons": { + "headphone": "", + "hands-free": "", + "headset": "", + "phone": "", + "portable": "", + "car": "", + "default": ["", "", ""] + }, + "on-click": "pavucontrol" + }, + "custom/media": { + "format": "{icon} {}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": "", + "default": "🎜" + }, + "escape": true, + "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder + // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name + } +} diff --git a/gemfeed/examples/conf/dotfiles/waybar/style.css b/gemfeed/examples/conf/dotfiles/waybar/style.css new file mode 100644 index 00000000..e0310372 --- /dev/null +++ b/gemfeed/examples/conf/dotfiles/waybar/style.css @@ -0,0 +1,326 @@ +* { + font-family: 'Noto Sans Mono', 'Font Awesome 6 Free', 'Font Awesome 6 Brands', monospace; + font-size: 13px; +} + +window#waybar { + background-color: rgba(43, 48, 59, 0.5); + border-bottom: 3px solid rgba(100, 114, 125, 0.5); + color: #ffffff; + transition-property: background-color; + transition-duration: .5s; +} + +window#waybar.hidden { + opacity: 0.2; +} + +/* +window#waybar.empty { + background-color: transparent; +} +window#waybar.solo { + background-color: #FFFFFF; +} +*/ + +window#waybar.termite { + background-color: #3F3F3F; +} + +window#waybar.chromium { + background-color: #000000; + border: none; +} + +button { + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: inset 0 -3px transparent; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; +} + +/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ +button:hover { + background: inherit; + box-shadow: inset 0 -3px #ffffff; +} + +/* you can set a style on hover for any module like this */ +#pulseaudio:hover { + background-color: #a37800; +} + +#workspaces button { + padding: 0 5px; + background-color: transparent; + color: #ffffff; +} + +#workspaces button:hover { + background: rgba(0, 0, 0, 0.2); +} + +#workspaces button.focused { + background-color: #64727D; + box-shadow: inset 0 -3px #ffffff; +} + +#workspaces button.urgent { + background-color: #eb4d4b; +} + +#mode { + background-color: #64727D; + box-shadow: inset 0 -3px #ffffff; +} + +#clock, +#battery, +#cpu, +#memory, +#disk, +#temperature, +#backlight, +#network, +#pulseaudio, +#wireplumber, +#custom-media, +#tray, +#mode, +#idle_inhibitor, +#scratchpad, +#power-profiles-daemon, +#mpd { + padding: 0 10px; + color: #ffffff; +} + +#window, +#workspaces { + margin: 0 4px; +} + +/* If workspaces is the leftmost module, omit left margin */ +.modules-left > widget:first-child > #workspaces { + margin-left: 0; +} + +/* If workspaces is the rightmost module, omit right margin */ +.modules-right > widget:last-child > #workspaces { + margin-right: 0; +} + +#clock { + background-color: #64727D; +} + +#battery { + background-color: #ffffff; + color: #000000; +} + +#battery.charging, #battery.plugged { + color: #ffffff; + background-color: #26A65B; +} + +@keyframes blink { + to { + background-color: #ffffff; + color: #000000; + } +} + +/* Using steps() instead of linear as a timing function to limit cpu usage */ +#battery.critical:not(.charging) { + background-color: #f53c3c; + color: #ffffff; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: steps(12); + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#power-profiles-daemon { + padding-right: 15px; +} + +#power-profiles-daemon.performance { + background-color: #f53c3c; + color: #ffffff; +} + +#power-profiles-daemon.balanced { + background-color: #2980b9; + color: #ffffff; +} + +#power-profiles-daemon.power-saver { + background-color: #2ecc71; + color: #000000; +} + +label:focus { + background-color: #000000; +} + +#cpu { + background-color: #2ecc71; + color: #000000; +} + +#memory { + background-color: #9b59b6; +} + +#disk { + background-color: #964B00; +} + +#backlight { + background-color: #90b1b1; +} + +#network { + background-color: #2980b9; +} + +#network.disconnected { + background-color: #f53c3c; +} + +#pulseaudio { + background-color: #f1c40f; + color: #000000; +} + +#pulseaudio.muted { + background-color: #90b1b1; + color: #2a5c45; +} + +#wireplumber { + background-color: #fff0f5; + color: #000000; +} + +#wireplumber.muted { + background-color: #f53c3c; +} + +#custom-media { + background-color: #66cc99; + color: #2a5c45; + min-width: 100px; +} + +#custom-media.custom-spotify { + background-color: #66cc99; +} + +#custom-media.custom-vlc { + background-color: #ffa000; +} + +#temperature { + background-color: #f0932b; +} + +#temperature.critical { + background-color: #eb4d4b; +} + +#tray { + background-color: #2980b9; +} + +#tray > .passive { + -gtk-icon-effect: dim; +} + +#tray > .needs-attention { + -gtk-icon-effect: highlight; + background-color: #eb4d4b; +} + +#idle_inhibitor { + background-color: #2d3436; +} + +#idle_inhibitor.activated { + background-color: #ecf0f1; + color: #2d3436; +} + +#mpd { + background-color: #66cc99; + color: #2a5c45; +} + +#mpd.disconnected { + background-color: #f53c3c; +} + +#mpd.stopped { + background-color: #90b1b1; +} + +#mpd.paused { + background-color: #51a37a; +} + +#language { + background: #00b093; + color: #740864; + padding: 0 5px; + margin: 0 5px; + min-width: 16px; +} + +#keyboard-state { + background: #97e1ad; + color: #000000; + padding: 0 0px; + margin: 0 5px; + min-width: 16px; +} + +#keyboard-state > label { + padding: 0 5px; +} + +#keyboard-state > label.locked { + background: rgba(0, 0, 0, 0.2); +} + +#scratchpad { + background: rgba(0, 0, 0, 0.2); +} + +#scratchpad.empty { + background-color: transparent; +} + +#privacy { + padding: 0; +} + +#privacy-item { + padding: 0 5px; + color: white; +} + +#privacy-item.screenshare { + background-color: #cf5700; +} + +#privacy-item.audio-in { + background-color: #1ca000; +} + +#privacy-item.audio-out { + background-color: #0069d4; +} -- cgit v1.2.3