#+PROPERTY: header-args :mkdirp yes #+title:Dotfiles Configuration * Configurations This file contains all configurations across all my machines. Well, most of them anyway. #+TOC: headlines 2 * Terminal ** Shell Environment #+begin_src sh :tangle ~/.profile alias k=kubectl alias lg=lazygit alias ld=lazydocker export EDITOR=vim export BROWSER=firefox export PAGER=bat export SHELL=fish export TERMINAL=wezterm export PATH="~/.dotfiles/scripts:$PATH" export PATH="/usr/local/bin:$PATH" #+end_src ** Git - TODO: re-evaluate merge conflictstyle #+begin_src ini :tangle ~/.gitconfig [user] name = Ian Keane email = ian@keane.sh [alias] find-file = "!for branch in `git for-each-ref --format=\"%(refname)\" refs/heads`; do echo \"${branch}:\"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep \"$1\"; done; :" [core] pager = delta [interactive] diffFilter = delta --color-only [delta] navigate = true side-by-side = true line-numbers-left-format = "" line-numbers-right-format = "│ " [merge] conflictstyle = diff3 [diff] colorMoved = default #+end_src ** Bat #+begin_src :tangle ~/.config/bat/config --style='changes,grid,header-filename' --color=always #+end_src ** TODO Autojump ** TODO Atuin ** Fish Fish shell configuration using starship prompt. *** Main Configuration #+begin_src fish :tangle ~/.config/fish/config.fish fish_vi_key_bindings # Initialize starship prompt starship init fish | source # Load aliases if they exist test -f ~/.config/fish/aliases.fish && source ~/.config/fish/aliases.fish #+end_src *** Mode Prompt Disable default mode indicator since starship handles it #+begin_src fish :tangle ~/.config/fish/functions/fish_mode_prompt.fish function fish_mode_prompt end #+end_src *** Starship Prompt Configure the starship prompt appearance and behavior #+begin_src toml :tangle ~/.config/starship.toml # Multi-line prompt with project context format = """ [╭─](bold blue) $directory\ $fill\ $git_branch$git_status$kubernetes$python$nodejs$rust$golang$docker_context [╰─](bold blue)$character""" # Add fill module for right alignment [fill] symbol = " " style = "bold blue" # Directory display with single-letter truncation [directory] style = "bold white" truncation_length = 1 truncate_to_repo = true fish_style_pwd_dir_length = 1 format = "[$path]($style)" # Command prompt character [character] success_symbol = "[❯](bold green)" error_symbol = "[❯](bold red)" vimcmd_symbol = "[❮](bold green)" # Git branch display [git_branch] format = "[$symbol$branch]($style)" style = "bold purple" symbol = " " # Git branch symbol # Git status indicators [git_status] format = '([\[$ahead_behind$staged$modified$deleted\]]($style) )' style = "bold cyan" # Repository status compared to remote ahead = "⇡${count}" # Local repo has ${count} commits not pushed to remote behind = "⇣${count}" # Remote has ${count} commits not in local repo diverged = "⇕⇡${ahead_count}⇣${behind_count}" # Local and remote have diverged # Working tree status staged = "+${count}" # Number of staged files modified = "!${count}" # Number of files with unstaged changes deleted = "✘${count}" # Number of deleted files untracked = "" # Hide untracked files indicator (was "?${count}") # Note: Other git status symbols available but hidden for cleaner display: # conflicted = "✖" # Merge conflicts # stashed = "≡" # Stashed changes # renamed = "»" # Renamed files # Kubernetes context [kubernetes] format = '[$symbol$context( \($namespace\))]($style) ' style = "bold blue" symbol = "☸ " disabled = true # Default to disabled detect_files = ["k8s", "kubernetes", "k3d.yaml", "kubeconfig.yaml"] # Only show in directories with these files # Python environment [python] format = '[$symbol$virtualenv]($style) ' style = "bold yellow" symbol = "🐍 " # Node.js [nodejs] format = '[$symbol($version )]($style)' style = "bold green" symbol = "⬢ " # Rust [rust] format = '[$symbol($version )]($style)' style = "bold red" symbol = "🦀 " # Docker [docker_context] format = '[$symbol$context]($style) ' style = "bold blue" symbol = "🐋 " # Golang [golang] format = '[$symbol($version )]($style)' style = "bold cyan" symbol = "Go " #+end_src error_symbol = "[❯](red)" vimcmd_symbol = "[❮](green)" # Git branch display [git_branch] format = "[$branch]($style)" style = "bright-black" # Git status indicators [git_status] format = "[[(*$conflicted$untracked$modified$staged$renamed$deleted)](218) ($ahead_behind$stashed)]($style)" style = "cyan" conflicted = "✖" untracked = "+" modified = "!" staged = "+" renamed = "»" deleted = "✘" stashed = "≡" # Command duration [cmd_duration] min_time = 500 format = "[$duration]($style) " # Username display [username] show_always = false style_user = "white bold" style_root = "red bold" # Hostname display [hostname] ssh_only = true format = "[$hostname]($style) " trim_at = "-" style = "bold dimmed green" #+end_src ** Tmux #+begin_src txt :tangle ~/.config/tmux/tmux.conf # Required for yazi set -g allow-passthrough on set -ga update-environment TERM set -ga update-environment TERM_PROGRAM # set-option -g default-shell /usr/bin/fish # set -g default-terminal "screen-256color" # # set-window-option -g mode-keys vi # set-window-option -g automatic-rename on set-window-option -g mode-keys vi # Blank space between status and bottom of window set -Fg 'status-format[1]' '#{status-format[0]}' set -g 'status-format[0]' '#[bg=black] ' set -g status 2 # Smart pane switching with awareness of Vim splits. # See: https://github.com/christoomey/vim-tmux-navigator # Adapted to avoid fzf conflicts is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'" multiple_panes="[ $(tmux list-panes | wc -l) -gt 1 ]" bind-key -n 'C-h' if-shell "$is_vim && $multiple_panes" 'send-keys C-h' 'select-pane -L' bind-key -n 'C-j' if-shell "$is_vim && $multiple_panes" 'send-keys C-j' 'select-pane -D' bind-key -n 'C-k' if-shell "$is_vim && $multiple_panes" 'send-keys C-k' 'select-pane -U' bind-key -n 'C-l' if-shell "$is_vim && $multiple_panes" 'send-keys C-l' 'select-pane -R' # bind-key -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l" bind a resize-pane -Z # Shift arrow to switch windows bind -n C-S-Space previous-window bind -n C-Space next-window # Remove escape delay set -g escape-time 0 # Enable mouse scroll set -g mouse on set-option -g status-right-length 140 set-option -g status-right "#(curl 'wttr.in/?format=%%c%%t%%20')|#[bg=default] %a %l:%M %p#[default]#(curl 'wttr.in/?format=%%20%%m%%20(%%M)%') |#(sugar --tmux)#[bg=default]" set-option -g status-left-length 140 set-option -g status-left " Session: #[bold,fg=green,bg=black] #S #[fg=black,bg=green] " set-option -g status-justify centre set-option -g window-status-current-format '#[bold,fg=green,bg=black] #{window_name} ' set-option -g window-status-format '#{window_name}' #+end_src ** TODO Tmuxinator * Wezterm #+begin_src lua :tangle ~/.config/wezterm/wezterm.lua local wezterm = require 'wezterm' local config = {} config.color_scheme = 'OceanicNext (base16)' config.font = wezterm.font 'FiraCode Nerd Font Mono' config.font_size = 20 config.enable_tab_bar = false return config #+end_src * Text Editors ** Helix *** TODO Things to remap - HML - gg G - next / previous / show hunk ghn ghp ghv - alias & to something easier - remap alt-s - remap ctrl-r to redo - remap gc to comment *** TODO Misc - Language server config - GPT config #+begin_src toml :tangle ~/.config/helix/config.toml theme = "base16_transparent" #+end_src #+begin_src toml :tangle ~/.config/helix/languages.toml [[language]] name = "lua" auto-format = true formatter = { command = "stylua", args = [ "-" ] } #+end_src ** Emacs Pinentry #+begin_src txt :tangle ~/.gnupg/gpg-agent.conf allow-emacs-pinentry #+end_src * Audio ** mpd #+begin_src ini :tangle ~/.config/mpd/mpd.conf db_file "~/.config/mpd/database" log_file "~/.config/mpd/log" music_directory "/mnt/media/music" playlist_directory "~/.config/mpd/playlists" pid_file "~/.config/mpd/pid" state_file "~/.config/mpd/state" sticker_file "~/.config/mpd/sticker.sql" auto_update "yes" bind_to_address "127.0.0.1" restore_paused "yes" max_output_buffer_size "16384" audio_output { type "alsa" name "alsa for audio soundcard" # mixer_type "software" } audio_output { type "fifo" name "toggle_visualizer" path "/tmp/mpd.fifo" format "44100:16:2" } audio_output { type "pulse" name "PulseAudio Output" #server "localhost" # optional #sink "alsa_output" # optional } audio_output { type "alsa" name "MPD" device "pulse" mixer_control "Master" } #+end_src ** Bluetooth - TODO: evaluate if this can be done differently in nixos #+begin_src lua :tangle /sudo::/etc/wireplumber/bluetooth.lua.d/51-bluez-config.lua bluez_monitor.properties = { ["bluez5.enable-sbc-xq"] = true, ["bluez5.enable-msbc"] = true, ["bluez5.enable-hw-volume"] = true, ["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]" } #+end_src * Xorg Config - Tangle to =/etc/X11/xorg.conf.d/00-keyboard.conf= for non-nixos #+begin_src txt :tangle no Section "InputClass" Identifier "keyboard-catchall" MatchIsKeyboard "on" Option "XkbLayout" "us,ru,ara" Option "XkbOptions" "grp:alt_shift_toggle,ctrl:nocaps,altwin:swap_alt_win" EndSection #+end_src ** Non-Nix Xorg *** Laptop Only - Avoid unintentional touchpad activation - TODO: Tangle to /etc/X11/xorg.conf.d/10-synaptics.conf for non-nix #+begin_src Section "InputClass" Identifier "touchpad catchall" Driver "synaptics" MatchIsTouchpad "on" MatchDevicePath "/dev/input/event*" Option "MaxTapTime" "0" EndSection #+end_src * Tasks ** Taskwarrior - TODO: evaluate if taskwarrior 3 has different settings - TODO: clean up categories - TODO: configure aws bucket for task warrior #+begin_src ini :tangle ~/.config/task/taskrc data.location=~/.local/share/task hooks.location=~/.config/task/hooks include dark-yellow-green.theme color.project.infra=yellow color.project.workflow=green color.project.home=color5 # purple color.project.other=blue color.project.blog=color6 # ??? report.list.columns=id,depends.indicator,priority,project,recur.indicator,description.count report.list.labels=ID,D,P,Project,R,Description #+end_src ** Vit - TODO: Compare to mac for custom keybindings #+begin_src ini :tangle ~/.config/vit/ [taskwarrior] taskrc = ~/.config/task/taskrc [vit] default_keybindings = vi theme = default confirmation = False [report] row_striping = False [color] enabled = True #+end_src * Dunst #+begin_src ini :tangle ~/.config/dunst/dunstrc [global] monitor = 0 follow = none width = 300 height = 300 origin = top-right offset = 10x50 scale = 0 notification_limit = 0 progress_bar = true progress_bar_height = 10 progress_bar_frame_width = 1 progress_bar_min_width = 150 progress_bar_max_width = 300 indicate_hidden = yes transparency = 0 separator_height = 2 padding = 8 horizontal_padding = 8 text_icon_padding = 0 frame_width = 3 gap_size = 0 sort = yes font = Monospace 12 line_height = 0 markup = full # The format of the message. Possible variables are: # %a appname # %s summary # %b body # %i iconname (including its path) # %I iconname (without its path) # %p progress value if set ([ 0%] to [100%]) or nothing # %n progress value if set without any extra characters # %% Literal % # Markup is allowed format = "%s\n%b" alignment = left vertical_alignment = center show_age_threshold = 60 ellipsize = middle ignore_newline = no stack_duplicates = true hide_duplicate_count = false show_indicators = yes sticky_history = yes history_length = 20 dmenu = /usr/bin/dmenu -p dunst: browser = /usr/bin/xdg-open always_run_script = true title = Dunst class = Dunst corner_radius = 0 ignore_dbusclose = false force_xinerama = false mouse_left_click = close_current mouse_middle_click = do_action, close_current mouse_right_click = close_all [experimental] per_monitor_dpi = false #+end_src * Databases #+begin_src ini :tangle ~/.config/pgcli/config [main] smart_completion = True wider_completion_menu = False multi_line = False multi_line_mode = psql destructive_warning = True expand = False auto_expand = False generate_aliases = False log_file = default keyword_casing = auto casing_file = default generate_casing_file = False case_column_headers = True history_file = default # "CRITICAL", "ERROR", "WARNING", "INFO" "DEBUG", "NONE" log_level = INFO # table_order and alphabetic asterisk_column_order = table_order qualify_columns = if_more_than_one_table search_path_filter = False timing = True show_bottom_toolbar = True # Recommended: psql, fancy_grid or grid. table_format = psql syntax_style = default vi = True on_error = STOP row_limit = 1000 less_chatty = False prompt = '\u@\h:\d> ' min_num_menu_lines = 4 multiline_continuation_char = '' null_string = '' enable_pager = True keyring = True #+end_src * Special Exceptions ** Tdrop - Must be installed from the repo, doesn't work from nix repos - Must be moved to /usr/local/bin and given same permissions that come from make install * Window Manager ** BSPWM BSPWM is a tiling window manager that represents windows as the leaves of a binary tree. *** Workspace and Monitor Configuration - Defines workspaces (desktops) - Sets window rules for specific applications - Configures border colors using Flavours theme integration - Sets core window manager behavior (gaps, border width, etc) #+begin_src sh :tangle ~/.config/bspwm/bspwmrc-new #! /bin/sh bspc monitor -d 1 2 3 4 bspc rule -a Gimp desktop='^8' state=floating follow=on bspc rule -a Chromium desktop='^2' bspc rule -a mplayer2 state=floating bspc rule -a Kupfer.py focus=on bspc rule -a Screenkey manage=off bspc rule -a Screenkey manage=off # start flavours @ bspc config normal_border_color "#343D46" @ bspc config active_border_color "#99C794" @ bspc config focused_border_color "#99C794" @ bspc config presel_feedback_color "#5FB3B3" # end flavours bspc config border_width 2 bspc config window_gap 12 bspc config split_ratio 0.52 bspc config borderless_monocle true bspc config gapless_monocle true export PATH = $PATH:~/scripts autorandr & polybar & sleep 3 && sxhkd & #+end_src ** SXHKD Simple X Hotkey Daemon (SXHKD) handles keyboard input and executes commands. Configuration is organized into sections for different types of functionality. *** Floating Windows and (t|n)drops Windows I want to be able to access at any time (usually fullscreen), often facilitated by tdrop or ndrop - TODO notes here about configuring tdrop to make this work - TODO calcurse window command - Right now these don't start the process necessarily that they list #+begin_src conf :tangle ~/.config/sxhkd/sxhkdrc # Persistent terminal window with tmux session super + Return tdrop -n 1 wezterm start --always-new-process -- tmux super + c tdrop -n 2 wezterm start --always-new-process -- tmux super + m tdrop -n 2 wezterm start --always-new-process -- ncmpcpp super + r tdrop -n secondmux wezterm --class secondmux && xdotool getwindowfocus getwindowclassname | grep -q secondmux && bspc node -t fullscreen super + e tdrop emacsclient -c super + shift + n {bspc rule -a \* -o state=floating && st -e nmtui} #+end_src *** Drop-down selectors (dmenu) #+begin_src conf :tangle ~/.config/sxhkd/sxhkdrc super + d dmenu_run super + @space dmenu_run -l 15 -i -nf $norm_fg -nb $norm_bg -sb $sel_bg -sf $sel_fg #+end_src *** DE management #+begin_src conf :tangle ~/.config/sxhkd/sxhkdrc # make sxhkd reload its configuration files: super + Escape pkill -USR1 -x sxhkd # quit/restart bspwm super + alt + {q,r} bspc {quit,wm -r} #+end_src *** Simple one-off keybinds #+begin_src conf :tangle ~/.config/sxhkd/sxhkdrc # close and kill super + q bspc node -c # screenshot super + s sleep .2 && scrot -s -e 'xclip -selection clipboard -t image/png -i $f' # change language (borked due to the key changing once in a different language) super + x languagecycle #+end_src *** Window Management #+begin_src conf :tangle ~/.config/sxhkd/sxhkdrc # set the window state super + {t,shift + t,shift + f,f} bspc node -t {tiled,floating,pseudo_tiled,~fullscreen} # focus the node in the given direction super + {_,shift + }{h,j,k,l} bspc node -{f,s} {west,south,north,east} # focus the next/previous desktop in the current monitor super + bracket{left,right} bspc desktop -f {prev,next}.local # focus the last node/desktop super + {grave,Tab} bspc {node,desktop} -f last # focus the older or newer node in the focus history super + {o,i} bspc wm -h off; \ bspc node {older,newer} -f; \ bspc wm -h on # focus or send to the given desktop super + {_,shift + }{1-9,0} bspc {desktop -f,node -d} '^{1-9,10}' # preselect the direction super + ctrl + {h,j,k,l} bspc node -p {west,south,north,east} # Resize windows super + alt + {h,j,k,l} {bspc node @parent/second -z left -20 0; \ bspc node @parent/first -z right -20 0, \ bspc node @parent/second -z top 0 +20; \ bspc node @parent/first -z bottom 0 +20, \ bspc node @parent/first -z bottom 0 -20; \ bspc node @parent/second -z top 0 -20, \ bspc node @parent/first -z right +20 0; \ bspc node @parent/second -z left +20 0} # move a floating window super + {Left,Down,Up,Right} bspc node -v {-20 0,0 20,0 -20,20 0} super + w gapcycle super + shift + w layoutcycle && sleep .1 #+end_src * Desktop Environment - .fehbg - polybar * TODO Media - mpv - video streaming - lf file selection - mpv plugins * TODO chat ** TODO weechat * TODO - Better polybar config - BSPWM / sxhkd / startup stuff / xinitrc - Consider configuring flavours - taskwarrior - vit - vimrc - tmuxinator setup - special popup for emacs, chat, gpt, etc - git / delta - firefox plugins settings - dunst alert once polybar battery widget shows low - mpd + radio? - sync calcurse and etar - polybar modules - brightness - bluetooth - polybar font colors - click battery to notify-send percentage - clock click to open calcurse - master chat notifications (click to open chat tdrop) - autorandr - dunstrc - ncmpcpp - scrobble - mpdscribble - internet radio - polybar - manage polybar w/ systemctl - make 'youtube' albums of songs I from there - explore mpd auto playlists