├── .config ├── alacritty │ └── alacritty.toml ├── autorandr │ ├── docked │ │ ├── config │ │ └── setup │ ├── mobile │ │ ├── config │ │ └── setup │ └── settings.ini ├── dunst │ └── dunstrc ├── fontconfig │ ├── conf.d │ │ ├── 10-powerline-symbols.conf │ │ ├── 30-dingbats.conf │ │ └── 70-cjk-fallback.conf │ └── fonts │ │ └── powerline-symbols.otf ├── git │ └── ignore ├── i3 │ └── config ├── i3status │ └── config ├── keepassxc │ └── keepassxc.ini ├── mpv │ ├── input.conf │ ├── mpv.conf │ └── script-opts │ │ ├── subs2srs.conf │ │ └── ytdl_hook.conf ├── nvim │ ├── after │ │ └── ftplugin │ │ │ ├── lua.vim │ │ │ └── python.vim │ ├── autoload │ │ └── pathogen.vim │ ├── colors │ │ ├── railscasts.vim │ │ └── solarizeddark.vim │ ├── ftdetect │ │ ├── dockerfile.vim │ │ └── markdown.vim │ ├── init.vim │ └── syntax │ │ ├── dockerfile.vim │ │ └── mail.vim └── redshift.conf ├── .gitconfig ├── .gitignore ├── .gitmodules ├── .local └── bin │ ├── battery-level │ ├── configure-keyboards │ ├── git-lh │ ├── kboot │ ├── keepassxc-helper │ ├── kernel-git-send-email-helper │ ├── lockmyi3 │ ├── mail-generate-msgid │ ├── mbsync-helper │ ├── redshiftd │ ├── wg-enroll │ ├── wyt │ └── zsh-raw ├── .mbsyncrc-personal ├── .mbsyncrc-suse ├── .mutt ├── mailcap ├── muttrc ├── muttrc-colours ├── muttrc-fix-msgid ├── muttrc-personal ├── muttrc-suse └── signature ├── .notmuch-config ├── .profile ├── .pythonrc.py ├── .ssh └── config ├── .tmux.conf ├── .wgetrc ├── .zsh ├── alias ├── banner ├── input └── prompt ├── .zshenv ├── .zshrc ├── COPYING ├── README.md ├── dist ├── install.sh ├── opensuse-tumbleweed └── opensuse │ ├── 00-osrelease.sh │ ├── 50-packages.sh │ ├── 51-user.sh │ ├── 52-graphics.sh │ ├── 53-wireguard.sh │ ├── 54-timedate.sh │ ├── 55-autorandr.sh │ ├── 56-dns.sh │ ├── 57-fonts.sh │ └── 60-sshkey.sh ├── hooks └── after │ ├── fonts │ └── mpv ├── install.py └── yomitan-settings.json /.config/alacritty/alacritty.toml: -------------------------------------------------------------------------------- 1 | [colors] 2 | draw_bold_text_with_bright_colors = true 3 | 4 | [colors.bright] 5 | black = "0x565656" 6 | blue = "0x49a4f8" 7 | cyan = "0x99faf2" 8 | green = "0xc0e17d" 9 | magenta = "0xa47de9" 10 | red = "0xec5357" 11 | white = "0xffffff" 12 | yellow = "0xf9da6a" 13 | 14 | [colors.normal] 15 | black = "0x2e2e2e" 16 | blue = "0x47a0f3" 17 | cyan = "0x64dbed" 18 | green = "0xabe047" 19 | magenta = "0x7b5cb0" 20 | red = "0xeb4129" 21 | white = "0xe5e9f0" 22 | yellow = "0xf6c744" 23 | 24 | [colors.primary] 25 | background = "0x000000" 26 | foreground = "0xfffbf6" 27 | 28 | [colors.selection] 29 | background = "CellForeground" 30 | text = "CellBackground" 31 | 32 | [cursor.style] 33 | blinking = "Off" 34 | shape = "Block" 35 | 36 | [font] 37 | size = 8 38 | 39 | [font.bold] 40 | family = "Japanese Cozette" 41 | style = "Bold" 42 | 43 | [font.normal] 44 | family = "Japanese Cozette" 45 | style = "Regular" 46 | 47 | [window] 48 | decorations_theme_variant = "Dark" 49 | dynamic_title = true 50 | opacity = 0.85 51 | startup_mode = "Maximized" 52 | title = "alacritty" 53 | -------------------------------------------------------------------------------- /.config/autorandr/docked/config: -------------------------------------------------------------------------------- 1 | output eDP-1 2 | off 3 | output DP-1 4 | off 5 | output DP-2 6 | off 7 | output DP-3 8 | off 9 | output DP-4 10 | off 11 | output DP-5 12 | off 13 | output DP-6 14 | off 15 | output DP-7 16 | off 17 | output DP-8 18 | off 19 | output DP-9 20 | off 21 | output DP-10 22 | off 23 | output DP-11 24 | off 25 | output DP-12 26 | crtc 1 27 | mode 1920x1080 28 | pos 0x0 29 | rate 60.00 30 | x-prop-max_bpc 8 31 | x-prop-non_desktop 0 32 | x-prop-scaling_mode None 33 | x-prop-underscan off 34 | x-prop-underscan_hborder 0 35 | x-prop-underscan_vborder 0 36 | output DP-13 37 | crtc 2 38 | mode 1920x1080 39 | pos 1920x0 40 | rate 60.00 41 | rotate right 42 | x-prop-max_bpc 8 43 | x-prop-non_desktop 0 44 | x-prop-scaling_mode None 45 | x-prop-underscan off 46 | x-prop-underscan_hborder 0 47 | x-prop-underscan_vborder 0 48 | -------------------------------------------------------------------------------- /.config/autorandr/docked/setup: -------------------------------------------------------------------------------- 1 | DP-12 00ffffffffffff0030aef66100000000181e0104a5331d783bee95a3544c99260f5054afef00d1c08180818a9500a9c0a9cfb300714f023a801871382d40582c4500fd1e1100001e000000fc004c454e20543233692d32300a20000000fd00324b0f5311000a202020202020000000ff00564e4134575454330a202020200133020318f14b901f0514010203041112132309070783010000023a80d072382d40102c4580fd1e1100001e011d80d0721c1620102c2500fd1e1100009e011d00bc52d01e20b8285540fd1e1100001e8c0ad090204031200c405500fd1e11000018662156aa51001e30468f3300fd1e1100001e0000000000000000000000000099 2 | DP-13 00ffffffffffff0030aeab61010101012b1d0104a5331d783e27b5a4574c9f260f5054bdcf00714f8180818c9500b300d1c001010101023a801871382d40582c4500fd1e1100001e000000ff00563330344e4847540a20202020000000fd00324b1e5311000a202020202020000000fc004c454e20543233692d31300a20010e020318f14b010203040514111213901f2309070783010000011d007251d01e206e285500fd1e1100001e8c0ad08a20e02d10103e9600fd1e110000188c0ad090204031200c405500fd1e1100001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc 3 | -------------------------------------------------------------------------------- /.config/autorandr/mobile/config: -------------------------------------------------------------------------------- 1 | output DP-1 2 | off 3 | output DP-2 4 | off 5 | output DP-3 6 | off 7 | output DP-4 8 | off 9 | output DP-5 10 | off 11 | output DP-6 12 | off 13 | output DP-7 14 | off 15 | output DP-8 16 | off 17 | output DP-9 18 | off 19 | output DP-10 20 | off 21 | output DP-11 22 | off 23 | output eDP-1 24 | crtc 0 25 | mode 2256x1504 26 | pos 0x0 27 | primary 28 | rate 60.00 29 | x-prop-colorspace Default 30 | x-prop-max_bpc 16 31 | x-prop-non_desktop 0 32 | x-prop-scaling_mode None 33 | x-prop-underscan off 34 | x-prop-underscan_hborder 0 35 | x-prop-underscan_vborder 0 36 | -------------------------------------------------------------------------------- /.config/autorandr/mobile/setup: -------------------------------------------------------------------------------- 1 | eDP-1 00ffffffffffff0009e5ca0b000000002f200104a51c137803de50a3544c99260f505400000001010101010101010101010101010101115cd01881e02d50302036001dbe1000001aa749d01881e02d50302036001dbe1000001a000000fe00424f452043510a202020202020000000fe004e4531333546424d2d4e34310a0073 2 | -------------------------------------------------------------------------------- /.config/autorandr/settings.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | match-edid=true 3 | -------------------------------------------------------------------------------- /.config/dunst/dunstrc: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | [global] 18 | font = "Source Code Pro" 9 19 | 20 | # Allow a small subset of html markup: 21 | # bold 22 | # italic 23 | # strikethrough 24 | # underline 25 | # 26 | # For a complete reference see 27 | # . 28 | # If markup is not allowed, those tags will be stripped out of the 29 | # message. 30 | allow_markup = yes 31 | 32 | # The format of the message. Possible variables are: 33 | # %a appname 34 | # %s summary 35 | # %b body 36 | # %i iconname (including its path) 37 | # %I iconname (without its path) 38 | # %p progress value if set ([ 0%] to [100%]) or nothing 39 | # Markup is allowed 40 | format = "%a%p: %s -- %b" 41 | 42 | # Sort messages by urgency. 43 | sort = yes 44 | 45 | # Show how many messages are currently hidden (because of geometry). 46 | indicate_hidden = yes 47 | 48 | # Alignment of message text. 49 | # Possible values are "left", "center" and "right". 50 | alignment = left 51 | 52 | # The frequency with wich text that is longer than the notification 53 | # window allows bounces back and forth. 54 | # This option conflicts with "word_wrap". 55 | # Set to 0 to disable. 56 | bounce_freq = 0 57 | 58 | # Show age of message if message is older than show_age_threshold 59 | # seconds. 60 | # Set to -1 to disable. 61 | show_age_threshold = 60 62 | 63 | # Split notifications into multiple lines if they don't fit into 64 | # geometry. 65 | word_wrap = yes 66 | 67 | # Ignore newlines '\n' in notifications. 68 | ignore_newline = no 69 | 70 | # The geometry of the window: 71 | # [{width}]x{height}[+/-{x}+/-{y}] 72 | # The geometry of the message window. 73 | # The height is measured in number of notifications everything else 74 | # in pixels. If the width is omitted but the height is given 75 | # ("-geometry x2"), the message window expands over the whole screen 76 | # (dmenu-like). If width is 0, the window expands to the longest 77 | # message displayed. A positive x is measured from the left, a 78 | # negative from the right side of the screen. Y is measured from 79 | # the top and down respectevly. 80 | # The width can be negative. In this case the actual width is the 81 | # screen width minus the width defined in within the geometry option. 82 | geometry = "300x5-30+20" 83 | 84 | # Shrink window if it's smaller than the width. Will be ignored if 85 | # width is 0. 86 | shrink = no 87 | 88 | # The transparency of the window. Range: [0; 100]. 89 | # This option will only work if a compositing windowmanager is 90 | # present (e.g. xcompmgr, compiz, etc.). 91 | transparency = 25 92 | 93 | # Don't remove messages, if the user is idle (no mouse or keyboard input) 94 | # for longer than idle_threshold seconds. 95 | # Set to 0 to disable. 96 | idle_threshold = 120 97 | 98 | # Which monitor should the notifications be displayed on. 99 | monitor = 0 100 | 101 | # Display notification on focused monitor. Possible modes are: 102 | # mouse: follow mouse pointer 103 | # keyboard: follow window with keyboard focus 104 | # none: don't follow anything 105 | # 106 | # "keyboard" needs a windowmanager that exports the 107 | # _NET_ACTIVE_WINDOW property. 108 | # This should be the case for almost all modern windowmanagers. 109 | # 110 | # If this option is set to mouse or keyboard, the monitor option 111 | # will be ignored. 112 | follow = keyboard 113 | 114 | # Should a notification popped up from history be sticky or timeout 115 | # as if it would normally do. 116 | sticky_history = yes 117 | 118 | # Maximum amount of notifications kept in history 119 | history_length = 20 120 | 121 | # Display indicators for URLs (U) and actions (A). 122 | show_indicators = yes 123 | 124 | # The height of a single line. If the height is smaller than the 125 | # font height, it will get raised to the font height. 126 | # This adds empty space above and under the text. 127 | line_height = 0 128 | 129 | # Draw a line of "separatpr_height" pixel height between two 130 | # notifications. 131 | # Set to 0 to disable. 132 | separator_height = 2 133 | 134 | # Padding between text and separator. 135 | padding = 8 136 | 137 | # Horizontal padding. 138 | horizontal_padding = 8 139 | 140 | # Define a color for the separator. 141 | # possible values are: 142 | # * auto: dunst tries to find a color fitting to the background; 143 | # * foreground: use the same color as the foreground; 144 | # * frame: use the same color as the frame; 145 | # * anything else will be interpreted as a X color. 146 | separator_color = frame 147 | 148 | # Print a notification on startup. 149 | # This is mainly for error detection, since dbus (re-)starts dunst 150 | # automatically after a crash. 151 | startup_notification = false 152 | 153 | # dmenu path. 154 | dmenu = /usr/bin/dmenu -p dunst: 155 | 156 | # Browser for opening urls in context menu. 157 | browser = /usr/bin/chromium 158 | 159 | # Align icons left/right/off 160 | icon_position = off 161 | 162 | # Paths to default icons. 163 | icon_folders = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ 164 | 165 | [frame] 166 | width = 3 167 | color = "#aaaaaa" 168 | 169 | [shortcuts] 170 | 171 | # Shortcuts are specified as [modifier+][modifier+]...key 172 | # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", 173 | # "mod3" and "mod4" (windows-key). 174 | # Xev might be helpful to find names for keys. 175 | 176 | # Close notification. 177 | close = mod4+c 178 | 179 | # Close all notifications. 180 | close_all = mod4+shift+c 181 | 182 | # Redisplay last message(s). 183 | # On the US keyboard layout "grave" is normally above TAB and left 184 | # of "1". 185 | history = ctrl+grave 186 | 187 | # Context menu. 188 | context = ctrl+shift+period 189 | 190 | [urgency_low] 191 | # IMPORTANT: colors have to be defined in quotation marks. 192 | # Otherwise the "#" and following would be interpreted as a comment. 193 | background = "#222222" 194 | foreground = "#888888" 195 | timeout = 10 196 | 197 | [urgency_normal] 198 | background = "#285577" 199 | foreground = "#ffffff" 200 | timeout = 10 201 | 202 | [urgency_critical] 203 | background = "#900000" 204 | foreground = "#ffffff" 205 | timeout = 0 206 | 207 | 208 | # Every section that isn't one of the above is interpreted as a rules to 209 | # override settings for certain messages. 210 | # Messages can be matched by "appname", "summary", "body", "icon", "category", 211 | # "msg_urgency" and you can override the "timeout", "urgency", "foreground", 212 | # "background", "new_icon" and "format". 213 | # Shell-like globbing will get expanded. 214 | # 215 | # SCRIPTING 216 | # You can specify a script that gets run when the rule matches by 217 | # setting the "script" option. 218 | # The script will be called as follows: 219 | # script appname summary body icon urgency 220 | # where urgency can be "LOW", "NORMAL" or "CRITICAL". 221 | # 222 | # NOTE: if you don't want a notification to be displayed, set the format 223 | # to "". 224 | # NOTE: It might be helpful to run dunst -print in a terminal in order 225 | # to find fitting options for rules. 226 | 227 | #[espeak] 228 | # summary = "*" 229 | # script = dunst_espeak.sh 230 | 231 | #[script-test] 232 | # summary = "*script*" 233 | # script = dunst_test.sh 234 | 235 | #[ignore] 236 | # # This notification will not be displayed 237 | # summary = "foobar" 238 | # format = "" 239 | 240 | #[signed_on] 241 | # appname = Pidgin 242 | # summary = "*signed on*" 243 | # urgency = low 244 | # 245 | #[signed_off] 246 | # appname = Pidgin 247 | # summary = *signed off* 248 | # urgency = low 249 | # 250 | #[says] 251 | # appname = Pidgin 252 | # summary = *says* 253 | # urgency = critical 254 | # 255 | #[twitter] 256 | # appname = Pidgin 257 | # summary = *twitter.com* 258 | # urgency = normal 259 | # 260 | # vim: ft=cfg 261 | -------------------------------------------------------------------------------- /.config/fontconfig/conf.d/10-powerline-symbols.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | monospace 7 | PowerlineSymbols 8 | 9 | 10 | Droid Sans Mono 11 | PowerlineSymbols 12 | 13 | 14 | DejaVu Sans Mono 15 | PowerlineSymbols 16 | 17 | 18 | Envy Code R 19 | PowerlineSymbols 20 | 21 | 22 | Inconsolata 23 | PowerlineSymbols 24 | 25 | 26 | Lucida Console 27 | PowerlineSymbols 28 | 29 | 30 | Monaco 31 | PowerlineSymbols 32 | 33 | 34 | Pragmata 35 | PowerlineSymbols 36 | 37 | 38 | PragmataPro 39 | PowerlineSymbols 40 | 41 | 42 | Menlo 43 | PowerlineSymbols 44 | 45 | 46 | Source Code Pro 47 | PowerlineSymbols 48 | 49 | 50 | Consolas 51 | PowerlineSymbols 52 | 53 | 54 | Anonymous pro 55 | PowerlineSymbols 56 | 57 | 58 | Bitstream Vera Sans Mono 59 | PowerlineSymbols 60 | 61 | 62 | Liberation Mono 63 | PowerlineSymbols 64 | 65 | 66 | Ubuntu Mono 67 | PowerlineSymbols 68 | 69 | 70 | Meslo LG L 71 | PowerlineSymbols 72 | 73 | 74 | Meslo LG L DZ 75 | PowerlineSymbols 76 | 77 | 78 | Meslo LG M 79 | PowerlineSymbols 80 | 81 | 82 | Meslo LG M DZ 83 | PowerlineSymbols 84 | 85 | 86 | Meslo LG S 87 | PowerlineSymbols 88 | 89 | 90 | Meslo LG S DZ 91 | PowerlineSymbols 92 | 93 | 94 | -------------------------------------------------------------------------------- /.config/fontconfig/conf.d/30-dingbats.conf: -------------------------------------------------------------------------------- 1 | 2 | ZapfDingbats 3 | Dingbats 4 | 5 | -------------------------------------------------------------------------------- /.config/fontconfig/conf.d/70-cjk-fallback.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Japanese Cozette 7 | 8 | Cozette 9 | M PLUS 1 Medium 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.config/fontconfig/fonts/powerline-symbols.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyphar/dotfiles/a5bd82fd74bed346041d0fc9cf021ec42355d6c2/.config/fontconfig/fonts/powerline-symbols.otf -------------------------------------------------------------------------------- /.config/git/ignore: -------------------------------------------------------------------------------- 1 | # swap files 2 | .*.s[a-w][a-z] 3 | -------------------------------------------------------------------------------- /.config/i3/config: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Set the Super key as the modifier. 18 | set $mod Mod4 19 | set $alt Mod1 20 | 21 | set $bin .local/bin 22 | set $term alacritty 23 | 24 | font pango:Japanese Cozette 8 25 | 26 | # Make things usable. 27 | workspace_auto_back_and_forth yes 28 | focus_follows_mouse no 29 | 30 | # Use Mouse+$mod to drag floating windows to their wanted position 31 | floating_modifier $mod 32 | 33 | # Start a terminal. 34 | bindsym $mod+Return exec "$term" 35 | bindsym $mod+Shift+Return exec "$term -e '$bin/zsh-raw'" 36 | 37 | # Lock the i3 session. 38 | bindsym $mod+p exec "$bin/lockmyi3" 39 | # Switch away from the i3 session (and lock it too). 40 | bindsym $mod+x exec "$bin/lockmyi3 -g" 41 | 42 | # Kill focused window. 43 | bindsym $mod+Shift+q kill 44 | 45 | # Start dmenu. 46 | bindsym $mod+d exec "dmenu_run" 47 | # Take a screenshot (and copy to clipboard). 48 | bindsym $mod+t exec "maim -s -f png | xclip -selection clipboard -t image/png" 49 | bindsym $mod+Shift+t exec "maim -s -f png ~/screenshot-$(date '+%Y-%m-%dT%H%M%S')-$(cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 10).png" 50 | 51 | # Vim movements. 52 | bindsym $mod+h focus left 53 | bindsym $mod+j focus down 54 | bindsym $mod+k focus up 55 | bindsym $mod+l focus right 56 | 57 | # Move focused window. 58 | bindsym $mod+Shift+h move left 59 | bindsym $mod+Shift+j move down 60 | bindsym $mod+Shift+k move up 61 | bindsym $mod+Shift+l move right 62 | 63 | # Match my tmux split bindings. 64 | bindsym $mod+minus split h 65 | bindsym $mod+bar split v 66 | 67 | # Fullscreen mode. 68 | bindsym $mod+f fullscreen 69 | 70 | # Layout selection (stacked, tabbed, toggle split). 71 | bindsym $mod+s layout stacking 72 | bindsym $mod+w layout tabbed 73 | bindsym $mod+e layout toggle split 74 | 75 | # Change focus between tiling / floating windows. 76 | bindsym $mod+space focus mode_toggle 77 | 78 | # Toggle tiling / floating. 79 | bindsym $mod+Shift+space floating toggle 80 | 81 | # Focus child / parent containers. 82 | bindsym $mod+a focus parent 83 | bindsym $mod+Shift+a focus child 84 | 85 | # Switch workspaces. 86 | bindsym $mod+1 workspace 1 87 | bindsym $mod+2 workspace 2 88 | bindsym $mod+3 workspace 3 89 | bindsym $mod+4 workspace 4 90 | bindsym $mod+5 workspace 5 91 | bindsym $mod+6 workspace 6 92 | bindsym $mod+7 workspace 7 93 | bindsym $mod+8 workspace 8 94 | bindsym $mod+9 workspace 9 95 | bindsym $mod+0 workspace 10 96 | 97 | # Move containers to workspaces. 98 | bindsym $mod+Shift+1 move container to workspace 1 99 | bindsym $mod+Shift+2 move container to workspace 2 100 | bindsym $mod+Shift+3 move container to workspace 3 101 | bindsym $mod+Shift+4 move container to workspace 4 102 | bindsym $mod+Shift+5 move container to workspace 5 103 | bindsym $mod+Shift+6 move container to workspace 6 104 | bindsym $mod+Shift+7 move container to workspace 7 105 | bindsym $mod+Shift+8 move container to workspace 8 106 | bindsym $mod+Shift+9 move container to workspace 9 107 | bindsym $mod+Shift+0 move container to workspace 10 108 | 109 | # Reload / restart i3. 110 | bindsym $mod+Shift+r restart 111 | # Reload autorandr setup. 112 | bindsym $mod+Control+r exec "autorandr -c" 113 | bindsym $mod+Control+Shift+r exec "autorandr --load mobile" 114 | 115 | # Exits i3 -- with nagging to make sure you didn't do it by accident. 116 | bindsym $mod+Shift+x exec "i3-nagbar -t warning -m 'Do you really want to exit i3?' -b 'Yes' 'i3-msg exit'" 117 | 118 | # resize window (you can also use the mouse for that) 119 | mode "resize" { 120 | # Vim bindings. 121 | bindsym h resize shrink width 10 px or 10 ppt 122 | bindsym j resize grow height 10 px or 10 ppt 123 | bindsym k resize shrink height 10 px or 10 ppt 124 | bindsym l resize grow width 10 px or 10 ppt 125 | 126 | # RETURN TO SAFETY. 127 | bindsym Return mode "default" 128 | bindsym Escape mode "default" 129 | } 130 | 131 | # Enter the dragon. 132 | bindsym $mod+r mode "resize" 133 | 134 | # Start i3bar to display a workspace bar (plus the system information i3status 135 | # finds out, if available) 136 | bar { 137 | status_command i3status 138 | 139 | colors { 140 | background #0f0f0f 141 | statusline #dcdccc 142 | 143 | focused_workspace #ffffff #285577 144 | active_workspace #ffffff #333333 145 | inactive_workspace #888888 #222222 146 | urgent_workspace #ffffff #900000 147 | } 148 | } 149 | 150 | # Tile colours. 151 | # class border backgr. text indicator 152 | client.focused #333333 #3f3f3f #dcdccc #2e9ef4 153 | client.focused_inactive #333333 #5f676a #ffffff #484e50 154 | client.unfocused #333333 #222222 #888888 #292d2e 155 | client.urgent #2f343a #900000 #ffffff #900000 156 | 157 | # Hide borders. 158 | hide_edge_borders both 159 | 160 | # Run redshiftd. 161 | exec_always "$bin/redshiftd" 162 | 163 | # Start ibus-damon. 164 | exec_always "ibus-daemon -drx" 165 | 166 | # Configure my keyboards. For some reason .xprofile doesn't work. 167 | exec_always "$bin/configure-keyboards" 168 | 169 | # Set background and transparency. 170 | exec --no-startup-id picom 171 | exec --no-startup-id feh --bg-scale .local/share/wallpapers/wallpaper.jpg 172 | -------------------------------------------------------------------------------- /.config/i3status/config: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # i3status configuration file. 18 | # see "man i3status" for documentation. 19 | 20 | # It is important that this file is edited as UTF-8. 21 | # The following line should contain a sharp s: 22 | # ß 23 | # If the above line is not correctly displayed, fix your editor first! 24 | 25 | general { 26 | colors = true 27 | interval = 5 28 | } 29 | 30 | order += "disk /" 31 | order += "disk /home" 32 | order += "wireless _first_" 33 | order += "ethernet _first_" 34 | order += "battery all" 35 | order += "load" 36 | order += "tztime local" 37 | 38 | wireless _first_ { 39 | format_up = "W: (%quality at %essid) %ip" 40 | format_down = "W: down" 41 | } 42 | 43 | ethernet _first_ { 44 | # If you use %speed, i3status requires root privileges. 45 | # TODO: Can I just remove %speed, do I actually use it? 46 | format_up = "E: %ip (%speed)" 47 | format_down = "E: down" 48 | } 49 | 50 | battery all { 51 | format = "%status %percentage %remaining" 52 | } 53 | 54 | tztime local { 55 | format = "%a %Y-%m-%d %H:%M:%S" 56 | } 57 | 58 | load { 59 | format = "%1min" 60 | } 61 | 62 | # Include separate disk usage for / and /home, because most distributions have 63 | # separate parititons for both. In future it would be nice if i3status let you 64 | # display qgroup limits but that's actually a btrfs bug and not caused by 65 | # i3status. 66 | 67 | disk "/" { 68 | format = "root: %avail" 69 | } 70 | 71 | disk "/home" { 72 | format = "home: %avail" 73 | } 74 | -------------------------------------------------------------------------------- /.config/keepassxc/keepassxc.ini: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | [General] 18 | AutoReloadOnChange=true 19 | AutoSaveAfterEveryChange=true 20 | AutoSaveOnExit=true 21 | AutoTypeDelay=25 22 | AutoTypeEntryTitleMatch=true 23 | AutoTypeEntryURLMatch=true 24 | AutoTypeStartDelay=500 25 | BackupBeforeSave=false 26 | GlobalAutoTypeKey=0 27 | GlobalAutoTypeModifiers=0 28 | IgnoreGroupExpansion=true 29 | LastAttachmentDir=/home/cyphar 30 | LastChallengeResponse=@Variant(\0\0\0\x1c\0\0\0\0) 31 | LastDatabases=/home/cyphar/doc/secret/passwords.kdbx 32 | LastDir=/home/cyphar 33 | LastKeyFiles=@Variant(\0\0\0\x1c\0\0\0\0) 34 | MinimizeOnCopy=true 35 | OpenPreviousDatabasesOnStartup=true 36 | RememberLastDatabases=true 37 | RememberLastKeyFiles=true 38 | SSHAgent=false 39 | SingleInstance=true 40 | UseAtomicSaves=true 41 | UseGroupIconOnEntryCreation=true 42 | 43 | [Browser] 44 | AlwaysAllowAccess=false 45 | AlwaysAllowUpdate=false 46 | BestMatchOnly=false 47 | CustomProxyLocation= 48 | Enabled=true 49 | MatchUrlScheme=true 50 | SearchInAllDatabases=false 51 | ShowNotification=true 52 | SortByUsername=false 53 | SupportBrowserProxy=true 54 | SupportKphFields=true 55 | UnlockDatabase=true 56 | UpdateBinaryPath=true 57 | UseCustomProxy=false 58 | 59 | [GUI] 60 | DarkTrayIcon=false 61 | HideDetailsView=false 62 | Language=system 63 | MinimizeOnClose=false 64 | MinimizeOnStartup=false 65 | MinimizeToTray=false 66 | ShowTrayIcon=false 67 | 68 | [Http] 69 | AlwaysAllowAccess=false 70 | AlwaysAllowUpdate=false 71 | BestMatchOnly=false 72 | DeprecationNoticeShown=1 73 | Enabled=false 74 | MatchUrlScheme=true 75 | Port=19455 76 | SearchInAllDatabases=false 77 | ShowNotification=true 78 | SortByUsername=false 79 | SupportKphFields=true 80 | UnlockDatabase=true 81 | generator\EASCII=false 82 | generator\EnsureEvery=true 83 | generator\ExcludeAlike=true 84 | generator\Length=32 85 | generator\LowerCase=true 86 | generator\Numbers=true 87 | generator\SpecialChars=false 88 | generator\UpperCase=true 89 | 90 | [generator] 91 | EASCII=false 92 | EnsureEvery=true 93 | ExcludeAlike=true 94 | Length=32 95 | LowerCase=true 96 | Numbers=true 97 | SpecialChars=true 98 | Type=0 99 | UpperCase=true 100 | WordCount=6 101 | WordList=eff_large.wordlist 102 | WordSeparator=" " 103 | 104 | [security] 105 | IconDownloadFallbackToGoogle=false 106 | autotypeask=true 107 | clearclipboard=true 108 | clearclipboardtimeout=10 109 | hidenotes=false 110 | hidepassworddetails=true 111 | lockdatabaseidle=true 112 | lockdatabaseidlesec=9999 113 | lockdatabaseminimize=false 114 | lockdatabasescreenlock=true 115 | passwordscleartext=false 116 | passwordsrepeat=false 117 | relockautotype=false 118 | -------------------------------------------------------------------------------- /.config/mpv/input.conf: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Disable "q" for quit, since I can close it in i3 just as easily. 18 | q ignore 19 | Q ignore 20 | -------------------------------------------------------------------------------- /.config/mpv/mpv.conf: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Always use Japanese subtitles, and prefer Japanese audio. 18 | alang=jpn,jp,eng,en 19 | slang=jpn,jp 20 | 21 | # Make subtitles more sane. 22 | sub-font=IPAGothic 23 | sub-font-size=40 24 | sub-ass-override=strip 25 | 26 | # Don't let yt-dlp pick a stupidly high resolution video. 27 | ytdl-format=bestvideo[height<=?1080]+bestaudio/best[height<=?1080] 28 | -------------------------------------------------------------------------------- /.config/mpv/script-opts/subs2srs.conf: -------------------------------------------------------------------------------- 1 | #################### 2 | # General settings # 3 | #################### 4 | 5 | # The deck will be created if it doesn't exist. Subdecks are supported. 6 | deck_name=日本語::文::例文 7 | 8 | # Model names are listed in `Tools -> Manage note types` menu in Anki. 9 | model_name=Japanese Mined Sentences 10 | 11 | # Field names as they appear in the selected note type. 12 | sentence_field=SentKanji 13 | audio_field=SentAudio 14 | image_field=Image 15 | 16 | miscinfo_field=Source 17 | miscinfo_format=

%n (%t)

18 | 19 | # Disable secondary subs. 20 | secondary_field= 21 | secondary_sub_lang= 22 | secondary_sub_visibility=never 23 | 24 | # Make %n actually use the whole episode name. This was broken upstream once, 25 | # so forcefully disable all of the tag fuckery options. 26 | tag_del_episode_num=no 27 | tag_del_after_episode_num=no 28 | tag_filename_lowercase=no 29 | 30 | # The tag that is added to new notes. 31 | # Leave nothing after `=` to disable tagging completely. 32 | note_tag=subs2srs 33 | 34 | # Size of the font used in the menu 35 | menu_font_size=24 36 | 37 | ####################################### 38 | # Custom encoding arguments # 39 | ####################################### 40 | 41 | # Normalise loudness, rather than using the player volume. 42 | tie_volumes=no 43 | ffmpeg_audio_args=-af loudnorm=I=-23:LRA=3:dual_mono=true 44 | mpv_audio_args=--af-append=loudnorm=I=-23:LRA=3:dual_mono=true 45 | 46 | # By default, set to remove silence from audio clips. 47 | # We cannot use silenceremove because it breaks long subtitle lines. 48 | #mpv_audio_args=--af-append=silenceremove=1:0:-50dB 49 | #ffmpeg_audio_args=-af silenceremove=1:0:-50dB 50 | 51 | ############################################## 52 | # Togglebles. Possble values: `yes` or `no`. # 53 | ############################################## 54 | 55 | # When mpv starts, automatically copy subs to the clipboard as they appear on 56 | # screen. This option can be also toggled in the addon's OSD menu. 57 | autoclip=yes 58 | 59 | # Remove all spaces from the subtitle text. 60 | # Only makes sense for languages without spaces like Japanese. 61 | nuke_spaces=yes 62 | 63 | # Remove text in parentheses that may interfere with Yomichan 64 | # before copying subtitles to the clipboard 65 | clipboard_trim_enabled=yes 66 | 67 | # Add media to fields before or after existing data 68 | append_media=yes 69 | 70 | ################## 71 | # Image settings # 72 | ################## 73 | 74 | # Snapshot format. 75 | snapshot_format=webp 76 | #snapshot_format=jpg 77 | 78 | # Quality of produced image files. 0 = lowest, 100=highest. 79 | snapshot_quality=40 80 | 81 | # Image dimensions 82 | # If either (but not both) of the width or height parameters is -2, 83 | # the value will be calculated preserving the aspect-ratio. 84 | snapshot_width=-2 85 | snapshot_height=400 86 | 87 | ################## 88 | # Audio settings # 89 | ################## 90 | 91 | # Audio format. 92 | audio_format=opus 93 | #audio_format=mp3 94 | 95 | # Sane values are 16k-32k for opus, 64k-128k for mp3. 96 | audio_bitrate=20k 97 | 98 | # Set a pad to the dialog timings. 99 | audio_padding=0.2 100 | 101 | ####################################### 102 | # Forvo support (Yomichan users only) # 103 | ####################################### 104 | 105 | # yes - fetch audio from Forvo if Yomichan couldn't find the audio (default) 106 | # always - always fetch audio from Forvo and replace the audio added by Yomichan 107 | # no - never use Forvo 108 | use_forvo=yes 109 | 110 | # Vocab field should be equal to {expression} field in Yomichan 111 | vocab_field=VocabKanji 112 | 113 | # Vocab Audio field should be equal to {audio} field in Yomichan 114 | vocab_audio_field=VocabAudio 115 | -------------------------------------------------------------------------------- /.config/mpv/script-opts/ytdl_hook.conf: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Use yt-dlp -- this is the default on mpv 0.34.0. 18 | ytdl_path=/home/cyphar/.local/bin/yt-dlp 19 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/lua.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | " Use soft tabs. 18 | setlocal tabstop=4 19 | setlocal shiftwidth=4 20 | setlocal softtabstop 21 | setlocal expandtab 22 | 23 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/python.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | " We are using hard tabs, like Cthulu intended. 18 | setlocal tabstop=4 19 | setlocal shiftwidth=4 20 | setlocal noexpandtab 21 | -------------------------------------------------------------------------------- /.config/nvim/autoload/pathogen.vim: -------------------------------------------------------------------------------- 1 | " pathogen.vim - path option manipulation 2 | " Maintainer: Tim Pope 3 | " Version: 2.0 4 | 5 | " Install in ~/.vim/autoload (or ~\vimfiles\autoload). 6 | " 7 | " For management of individually installed plugins in ~/.vim/bundle (or 8 | " ~\vimfiles\bundle), adding `call pathogen#infect()` to your .vimrc 9 | " prior to `filetype plugin indent on` is the only other setup necessary. 10 | " 11 | " The API is documented inline below. For maximum ease of reading, 12 | " :set foldmethod=marker 13 | 14 | if exists("g:loaded_pathogen") || &cp 15 | finish 16 | endif 17 | let g:loaded_pathogen = 1 18 | 19 | " Point of entry for basic default usage. Give a directory name to invoke 20 | " pathogen#runtime_append_all_bundles() (defaults to "bundle"), or a full path 21 | " to invoke pathogen#runtime_prepend_subdirectories(). Afterwards, 22 | " pathogen#cycle_filetype() is invoked. 23 | function! pathogen#infect(...) abort " {{{1 24 | let source_path = a:0 ? a:1 : 'bundle' 25 | if source_path =~# '[\\/]' 26 | call pathogen#runtime_prepend_subdirectories(source_path) 27 | else 28 | call pathogen#runtime_append_all_bundles(source_path) 29 | endif 30 | call pathogen#cycle_filetype() 31 | endfunction " }}}1 32 | 33 | " Split a path into a list. 34 | function! pathogen#split(path) abort " {{{1 35 | if type(a:path) == type([]) | return a:path | endif 36 | let split = split(a:path,'\\\@"),'!isdirectory(v:val)')) && (!filereadable(dir.sep.'doc'.sep.'tags') || filewritable(dir.sep.'doc'.sep.'tags')) 170 | helptags `=dir.'/doc'` 171 | endif 172 | endfor 173 | endfunction " }}}1 174 | 175 | command! -bar Helptags :call pathogen#helptags() 176 | 177 | " Like findfile(), but hardcoded to use the runtimepath. 178 | function! pathogen#runtime_findfile(file,count) "{{{1 179 | let rtp = pathogen#join(1,pathogen#split(&rtp)) 180 | let file = findfile(a:file,rtp,a:count) 181 | if file ==# '' 182 | return '' 183 | else 184 | return fnamemodify(file,':p') 185 | endif 186 | endfunction " }}}1 187 | 188 | " Backport of fnameescape(). 189 | function! pathogen#fnameescape(string) " {{{1 190 | if exists('*fnameescape') 191 | return fnameescape(a:string) 192 | elseif a:string ==# '-' 193 | return '\-' 194 | else 195 | return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','') 196 | endif 197 | endfunction " }}}1 198 | 199 | if exists(':Vedit') 200 | finish 201 | endif 202 | 203 | function! s:find(count,cmd,file,lcd) " {{{1 204 | let rtp = pathogen#join(1,pathogen#split(&runtimepath)) 205 | let file = pathogen#runtime_findfile(a:file,a:count) 206 | if file ==# '' 207 | return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'" 208 | elseif a:lcd 209 | let path = file[0:-strlen(a:file)-2] 210 | execute 'lcd `=path`' 211 | return a:cmd.' '.pathogen#fnameescape(a:file) 212 | else 213 | return a:cmd.' '.pathogen#fnameescape(file) 214 | endif 215 | endfunction " }}}1 216 | 217 | function! s:Findcomplete(A,L,P) " {{{1 218 | let sep = pathogen#separator() 219 | let cheats = { 220 | \'a': 'autoload', 221 | \'d': 'doc', 222 | \'f': 'ftplugin', 223 | \'i': 'indent', 224 | \'p': 'plugin', 225 | \'s': 'syntax'} 226 | if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0]) 227 | let request = cheats[a:A[0]].a:A[1:-1] 228 | else 229 | let request = a:A 230 | endif 231 | let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*' 232 | let found = {} 233 | for path in pathogen#split(&runtimepath) 234 | let path = expand(path, ':p') 235 | let matches = split(glob(path.sep.pattern),"\n") 236 | call map(matches,'isdirectory(v:val) ? v:val.sep : v:val') 237 | call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]') 238 | for match in matches 239 | let found[match] = 1 240 | endfor 241 | endfor 242 | return sort(keys(found)) 243 | endfunction " }}}1 244 | 245 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(,'edit',,0) 246 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(,'edit',,0) 247 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen :execute s:find(,'edit',,1) 248 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit :execute s:find(,'split',,1) 249 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit :execute s:find(,'vsplit',,1) 250 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(,'tabedit',,1) 251 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(,'pedit',,1) 252 | command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(,'read',,1) 253 | 254 | " vim:set et sw=2: 255 | -------------------------------------------------------------------------------- /.config/nvim/colors/railscasts.vim: -------------------------------------------------------------------------------- 1 | " Vim color scheme based on http://github.com/jpo/vim-railscasts-theme 2 | " 3 | " Name: railscasts.vim 4 | " Maintainer: Ryan Bates 5 | " License: MIT 6 | 7 | set background=dark 8 | hi clear 9 | if exists("syntax_on") 10 | syntax reset 11 | endif 12 | let g:colors_name = "railscasts" 13 | 14 | " Colors 15 | " Brown #BC9357 16 | " Dark Blue #6D9CBD 17 | " Dark Green #509E50 18 | " Dark Orange #CC7733 19 | " Light Blue #CFCFFF 20 | " Light Green #A5C160 21 | " Tan #FFC66D 22 | " Red #DA4938 23 | 24 | hi Normal guifg=#E6E1DC guibg=#232323 25 | hi Cursor guibg=#FFFFFF 26 | hi CursorLine guibg=#333435 27 | hi LineNr guifg=#666666 28 | hi Visual guibg=#5A647E 29 | hi Search guifg=NONE guibg=#131313 gui=NONE 30 | hi Folded guifg=#F6F3E8 guibg=#444444 gui=NONE 31 | hi Directory guifg=#A5C160 gui=NONE 32 | hi Error guifg=#FFFFFF guibg=#990000 33 | hi MatchParen guifg=NONE guibg=#131313 34 | hi Title guifg=#E6E1DC 35 | 36 | hi Comment guifg=#BC9357 guibg=NONE gui=italic 37 | hi! link Todo Comment 38 | 39 | hi String guifg=#A5C160 40 | hi! link Number String 41 | hi! link rubyStringDelimiter String 42 | 43 | " nil, self, symbols 44 | hi Constant guifg=#6D9CBD 45 | 46 | " def, end, include, load, require, alias, super, yield, lambda, proc 47 | hi Define guifg=#CC7733 gui=NONE 48 | hi! link Include Define 49 | hi! link Keyword Define 50 | hi! link Macro Define 51 | 52 | " #{foo}, <%= bar %> 53 | hi Delimiter guifg=#509E50 54 | " hi erubyDelimiter guifg=NONE 55 | 56 | " function name (after def) 57 | hi Function guifg=#FFC66D gui=NONE 58 | 59 | "@var, @@var, $var 60 | hi Identifier guifg=#CFCFFF gui=NONE 61 | 62 | " #if, #else, #endif 63 | 64 | " case, begin, do, for, if, unless, while, until, else 65 | hi Statement guifg=#CC7733 gui=NONE 66 | hi! link PreProc Statement 67 | hi! link PreCondit Statement 68 | 69 | " SomeClassName 70 | hi Type guifg=NONE gui=NONE 71 | 72 | " has_many, respond_to, params 73 | hi railsMethod guifg=#DA4938 gui=NONE 74 | 75 | hi DiffAdd guifg=#E6E1DC guibg=#144212 76 | hi DiffDelete guifg=#E6E1DC guibg=#660000 77 | 78 | hi xmlTag guifg=#E8BF6A 79 | hi! link xmlTagName xmlTag 80 | hi! link xmlEndTag xmlTag 81 | hi! link xmlArg xmlTag 82 | hi! link htmlTag xmlTag 83 | hi! link htmlTagName xmlTagName 84 | hi! link htmlEndTag xmlEndTag 85 | hi! link htmlArg xmlArg 86 | 87 | " Popup Menu 88 | " ---------- 89 | " normal item in popup 90 | hi Pmenu guifg=#F6F3E8 guibg=#444444 gui=NONE 91 | " selected item in popup 92 | hi PmenuSel guifg=#000000 guibg=#A5C160 gui=NONE 93 | " scrollbar in popup 94 | hi PMenuSbar guibg=#5A647E gui=NONE 95 | " thumb of the scrollbar in the popup 96 | hi PMenuThumb guibg=#AAAAAA gui=NONE 97 | 98 | -------------------------------------------------------------------------------- /.config/nvim/colors/solarizeddark.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | " Vim color file - solarizeddark 18 | " Generated by http://bytefluent.com/vivify 2012-12-24 19 | set background=dark 20 | if version > 580 21 | hi clear 22 | if exists("syntax_on") 23 | syntax reset 24 | endif 25 | endif 26 | 27 | set t_Co=256 28 | let g:colors_name = "solarizeddark" 29 | 30 | " nvim changed their colourscheme in 0.10, making old colourschemes break. 31 | " Load the "legacy" colour scheme to keep the old scheme working until I 32 | " rewrite it. 33 | colorscheme vim 34 | 35 | hi IncSearch guifg=#cb4b16 guibg=NONE guisp=NONE gui=NONE ctermfg=166 ctermbg=NONE cterm=NONE 36 | hi WildMenu guifg=#eee8d5 guibg=#073642 guisp=#073642 gui=NONE ctermfg=230 ctermbg=23 cterm=NONE 37 | hi SignColumn guifg=#839496 guibg=#bebebe guisp=#bebebe gui=NONE ctermfg=66 ctermbg=7 cterm=NONE 38 | hi SpecialComment guifg=#dc322f guibg=NONE guisp=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=NONE 39 | hi Typedef guifg=#b58900 guibg=NONE guisp=NONE gui=NONE ctermfg=136 ctermbg=NONE cterm=NONE 40 | hi Title guifg=#cb4b16 guibg=NONE guisp=NONE gui=bold ctermfg=166 ctermbg=NONE cterm=bold 41 | hi Folded guifg=#839496 guibg=#073642 guisp=#073642 gui=bold ctermfg=66 ctermbg=23 cterm=bold 42 | hi PreCondit guifg=#cb4b16 guibg=NONE guisp=NONE gui=NONE ctermfg=166 ctermbg=NONE cterm=NONE 43 | hi Include guifg=#cb4b16 guibg=NONE guisp=NONE gui=NONE ctermfg=166 ctermbg=NONE cterm=NONE 44 | hi Float guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 45 | hi StatusLineNC guifg=#657b83 guibg=#073642 guisp=#073642 gui=NONE ctermfg=66 ctermbg=23 cterm=NONE 46 | hi CTagsMember guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 47 | hi NonText guifg=#657b83 guibg=NONE guisp=NONE gui=bold ctermfg=66 ctermbg=NONE cterm=bold 48 | hi CTagsGlobalConstant guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 49 | hi DiffText guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 50 | hi ErrorMsg guifg=#ffffff guibg=#bf0000 guisp=#bf0000 gui=NONE ctermfg=15 ctermbg=1 cterm=NONE 51 | hi Ignore guifg=#000000 guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE 52 | hi Debug guifg=#dc322f guibg=NONE guisp=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=NONE 53 | hi PMenuSbar guifg=#eee8d5 guibg=#839496 guisp=#839496 gui=NONE ctermfg=230 ctermbg=66 cterm=NONE 54 | hi Identifier guifg=#268bd2 guibg=NONE guisp=NONE gui=bold ctermfg=32 ctermbg=NONE cterm=bold 55 | hi SpecialChar guifg=#dc322f guibg=NONE guisp=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=NONE 56 | hi Conditional guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 57 | hi StorageClass guifg=#b58900 guibg=NONE guisp=NONE gui=NONE ctermfg=136 ctermbg=NONE cterm=NONE 58 | hi Todo guifg=#eeeeee guibg=#ff0000 guisp=#ff0000 gui=bold ctermfg=255 ctermbg=196 cterm=bold 59 | hi Special guifg=#dc322f guibg=NONE guisp=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=NONE 60 | hi LineNr guifg=#91abb3 guibg=#000000 guisp=#000000 gui=NONE ctermfg=109 ctermbg=NONE cterm=NONE 61 | hi StatusLine guifg=#93a1a1 guibg=#073642 guisp=#073642 gui=bold ctermfg=109 ctermbg=23 cterm=bold 62 | hi Normal guifg=#ffffff guibg=#000000 guisp=#000000 gui=NONE ctermfg=15 ctermbg=NONE cterm=NONE 63 | hi Label guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 64 | hi CTagsImport guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 65 | hi PMenuSel guifg=#586e75 guibg=#eee8d5 guisp=#eee8d5 gui=NONE ctermfg=66 ctermbg=230 cterm=NONE 66 | hi Search guifg=#b58900 guibg=#00ffff guisp=#00ffff gui=NONE ctermfg=136 ctermbg=14 cterm=NONE 67 | hi CTagsGlobalVariable guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 68 | hi Delimiter guifg=#dc322f guibg=NONE guisp=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=NONE 69 | hi Statement guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 70 | hi SpellRare guifg=#e0e3e0 guibg=#00ff44 guisp=#00ff44 gui=NONE ctermfg=151 ctermbg=47 cterm=NONE 71 | hi EnumerationValue guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 72 | hi Comment guifg=#586e75 guibg=NONE guisp=NONE gui=italic ctermfg=66 ctermbg=NONE cterm=NONE 73 | hi Character guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 74 | hi TabLineSel guifg=#586e75 guibg=#eee8d5 guisp=#eee8d5 gui=bold ctermfg=66 ctermbg=230 cterm=bold 75 | hi Number guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 76 | hi Boolean guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 77 | hi Operator guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 78 | hi CursorLine guifg=#e2e4e5 guibg=#073642 guisp=#073642 gui=NONE ctermfg=254 ctermbg=23 cterm=NONE 79 | hi Union guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 80 | hi TabLineFill guifg=#b9d6d9 guibg=#041e24 guisp=#041e24 gui=NONE ctermfg=152 ctermbg=23 cterm=NONE 81 | hi Question guifg=#2aa198 guibg=NONE guisp=NONE gui=bold ctermfg=37 ctermbg=NONE cterm=bold 82 | hi WarningMsg guifg=#dc322f guibg=NONE guisp=NONE gui=bold ctermfg=160 ctermbg=NONE cterm=bold 83 | hi VisualNOS guifg=#e2e4e5 guibg=#073642 guisp=#073642 gui=bold ctermfg=254 ctermbg=23 cterm=bold 84 | hi DiffDelete guifg=#dc322f guibg=#073642 guisp=#073642 gui=bold ctermfg=160 ctermbg=23 cterm=bold 85 | hi ModeMsg guifg=#268bd2 guibg=NONE guisp=NONE gui=bold ctermfg=32 ctermbg=NONE cterm=bold 86 | hi CursorColumn guifg=#e2e4e5 guibg=#073642 guisp=#073642 gui=NONE ctermfg=254 ctermbg=23 cterm=NONE 87 | hi Define guifg=#cb4b16 guibg=NONE guisp=NONE gui=NONE ctermfg=166 ctermbg=NONE cterm=NONE 88 | hi Function guifg=#268bd2 guibg=NONE guisp=NONE gui=bold ctermfg=32 ctermbg=NONE cterm=bold 89 | hi FoldColumn guifg=#839496 guibg=#073642 guisp=#073642 gui=NONE ctermfg=66 ctermbg=23 cterm=NONE 90 | hi PreProc guifg=#cb4b16 guibg=NONE guisp=NONE gui=NONE ctermfg=166 ctermbg=NONE cterm=NONE 91 | hi EnumerationName guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 92 | hi Visual guifg=#586e75 guibg=#002b36 guisp=#002b36 gui=NONE ctermfg=66 ctermbg=23 cterm=NONE 93 | hi MoreMsg guifg=#268bd2 guibg=NONE guisp=NONE gui=NONE ctermfg=32 ctermbg=NONE cterm=NONE 94 | hi SpellCap guifg=#e3e0e0 guibg=#4236eb guisp=#4236eb gui=NONE ctermfg=254 ctermbg=13 cterm=NONE 95 | hi VertSplit guifg=#657b83 guibg=#657b83 guisp=#657b83 gui=NONE ctermfg=66 ctermbg=66 cterm=NONE 96 | hi Exception guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 97 | hi Keyword guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 98 | hi Type guifg=#b58900 guibg=NONE guisp=NONE gui=NONE ctermfg=136 ctermbg=NONE cterm=NONE 99 | hi DiffChange guifg=#b58900 guibg=#073642 guisp=#073642 gui=bold ctermfg=136 ctermbg=23 cterm=bold 100 | hi Cursor guifg=#002b36 guibg=#839496 guisp=#839496 gui=NONE ctermfg=23 ctermbg=66 cterm=NONE 101 | hi SpellLocal guifg=#e2e4e5 guibg=#ffff00 guisp=#ffff00 gui=NONE ctermfg=254 ctermbg=11 cterm=NONE 102 | hi Error guifg=#dc322f guibg=#8080ff guisp=#8080ff gui=bold ctermfg=160 ctermbg=12 cterm=bold 103 | hi PMenu guifg=#839496 guibg=#073642 guisp=#073642 gui=NONE ctermfg=66 ctermbg=23 cterm=NONE 104 | hi SpecialKey guifg=#657b83 guibg=#073642 guisp=#073642 gui=bold ctermfg=66 ctermbg=23 cterm=bold 105 | hi Constant guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 106 | hi DefinedName guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 107 | hi Tag guifg=#dc322f guibg=NONE guisp=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=NONE 108 | hi String guifg=#2aa198 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 109 | hi PMenuThumb guifg=#839496 guibg=#002b36 guisp=#002b36 gui=NONE ctermfg=66 ctermbg=23 cterm=NONE 110 | hi MatchParen guifg=#dc322f guibg=#586e75 guisp=#586e75 gui=bold ctermfg=160 ctermbg=66 cterm=bold 111 | hi LocalVariable guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 112 | hi Repeat guifg=#719e07 guibg=NONE guisp=NONE gui=NONE ctermfg=106 ctermbg=NONE cterm=NONE 113 | hi SpellBad guifg=#e2e4e5 guibg=#8080ff guisp=#8080ff gui=NONE ctermfg=254 ctermbg=12 cterm=NONE 114 | hi CTagsClass guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 115 | hi Directory guifg=#268bd2 guibg=NONE guisp=NONE gui=NONE ctermfg=32 ctermbg=NONE cterm=NONE 116 | hi Structure guifg=#b58900 guibg=NONE guisp=NONE gui=NONE ctermfg=136 ctermbg=NONE cterm=NONE 117 | hi Macro guifg=#cb4b16 guibg=NONE guisp=NONE gui=NONE ctermfg=166 ctermbg=NONE cterm=NONE 118 | hi Underlined guifg=#6c71c4 guibg=NONE guisp=NONE gui=underline ctermfg=61 ctermbg=NONE cterm=underline 119 | hi DiffAdd guifg=#719e07 guibg=#073642 guisp=#073642 gui=bold ctermfg=106 ctermbg=23 cterm=bold 120 | hi TabLine guifg=#839496 guibg=#073642 guisp=#073642 gui=NONE ctermfg=66 ctermbg=23 cterm=NONE 121 | hi pythonbuiltin guifg=#839496 guibg=NONE guisp=NONE gui=NONE ctermfg=66 ctermbg=NONE cterm=NONE 122 | hi phpstringdouble guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 123 | hi rubyescape guifg=#ffffff guibg=NONE guisp=NONE gui=NONE ctermfg=15 ctermbg=NONE cterm=NONE 124 | hi htmltagname guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 125 | hi javascriptstrings guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 126 | hi rubyregexpdelimiter guifg=#FF8000 guibg=NONE guisp=NONE gui=NONE ctermfg=208 ctermbg=NONE cterm=NONE 127 | hi htmlstring guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 128 | hi cursorim guifg=#262626 guibg=#c6c6c6 guisp=#c6c6c6 gui=NONE ctermfg=235 ctermbg=251 cterm=NONE 129 | hi phpstringsingle guifg=#e2e4e5 guibg=NONE guisp=NONE gui=NONE ctermfg=254 ctermbg=NONE cterm=NONE 130 | hi rubyinterpolationdelimiter guifg=#00A0A0 guibg=NONE guisp=NONE gui=NONE ctermfg=37 ctermbg=NONE cterm=NONE 131 | hi rubycontrol guifg=#6699CC guibg=NONE guisp=NONE gui=NONE ctermfg=68 ctermbg=NONE cterm=NONE 132 | hi colorcolumn guifg=NONE guibg=#303030 guisp=#303030 gui=NONE ctermfg=NONE ctermbg=236 cterm=NONE 133 | hi rubystringdelimiter guifg=#336633 guibg=NONE guisp=NONE gui=NONE ctermfg=65 ctermbg=NONE cterm=NONE 134 | hi rubyregexp guifg=#B18A3D guibg=NONE guisp=NONE gui=NONE ctermfg=137 ctermbg=NONE cterm=NONE 135 | hi cursorlinenr guifg=#8a8a8a guibg=#262626 guisp=#262626 gui=NONE ctermfg=245 ctermbg=235 cterm=NONE 136 | hi longlinewarning guifg=NONE guibg=#371F1C guisp=#371F1C gui=underline ctermfg=NONE ctermbg=237 cterm=underline 137 | hi javadocseetag guifg=#CCCCCC guibg=NONE guisp=NONE gui=NONE ctermfg=252 ctermbg=NONE cterm=NONE 138 | "hi clear -- no settings -- 139 | -------------------------------------------------------------------------------- /.config/nvim/ftdetect/dockerfile.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | au BufNewFile,BufRead Dockerfile set filetype=dockerfile 18 | -------------------------------------------------------------------------------- /.config/nvim/ftdetect/markdown.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | " Make sure that *.md and *.MD files are recognised as being markdown 18 | " (not modula2) 19 | au BufRead,BufNewFile *.md,*.MD set filetype=markdown 20 | -------------------------------------------------------------------------------- /.config/nvim/init.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | " The reason this file is released under the GPLv3 is because vim 18 | " configuration files are technically source code, and I will probably 19 | " end up adding more complicated configurations as NeoVim gets Lua 20 | " support into the configuration file handling. 21 | 22 | " Activate pathogen and include all bundles in the .vim/bundle directory. 23 | call pathogen#infect() 24 | 25 | " Ensure that this config is only used with Vim and not with Vi. 26 | set nocompatible 27 | 28 | " Make backspace work. 29 | set backspace=indent,eol,start 30 | 31 | " Suffixes that get lower priority when doing tab completion for filenames. 32 | " These are files we are not likely to want to edit or read. 33 | set suffixes=.bak,~,.swp,.o,.info,.aux,.log,.dvi,.bbl,.blg,.brf,.cb,.ind,.idx,.ilg,.inx,.out,.toc 34 | 35 | " Now we set some defaults for the editor 36 | set history=50 37 | set ruler 38 | 39 | " Nothing good ever came out of modeline. 40 | " Seriously. Talk about a security hole. 41 | set nomodeline 42 | 43 | augroup trailing_whitespace_show 44 | autocmd! 45 | " Make trailing whitespace red. 46 | autocmd ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red 47 | autocmd BufWinEnter,InsertEnter,InsertLeave * match ExtraWhitespace /\s\+$/ 48 | " Can slow things down, but show trailing whitespace as red while typing. 49 | autocmd InsertCharPre * match ExtraWhitespace /\s\+$/ 50 | augroup END 51 | 52 | augroup trailing_whitespace_kill 53 | autocmd! 54 | " Delete all trailing whitespace on-save. 55 | autocmd FileWritePre,FileAppendPre,FilterWritePre,BufWritePre * 56 | \ let w:wv = winsaveview() | 57 | \ :%s/\s\+$//e | 58 | \ call winrestview(w:wv) 59 | augroup END 60 | 61 | " Hopefully I can remove this some day when 80 characters is no longer the 62 | " standard. 63 | set colorcolumn=80 64 | 65 | " Enable block indentation and filetype-stuff. 66 | if has('autocmd') 67 | filetype indent plugin on 68 | endif 69 | 70 | " Omnicompletion 71 | set omnifunc=syntaxcomplete#Complete 72 | 73 | " Enable syntax highlighting. 74 | if &t_Co > 2 || has('gui_running') 75 | syntax enable 76 | endif 77 | 78 | " Dark-As-My-Soul colourscheme. 79 | set background=dark 80 | colorscheme solarizeddark 81 | " Make sure the background is transparent. 82 | hi NonText ctermbg=NONE 83 | hi Normal guibg=NONE ctermbg=NONE 84 | 85 | " Rebind the mapleader. 86 | let mapleader = "?" 87 | 88 | " Basic stuff. 89 | set hidden 90 | set autoread 91 | set noerrorbells 92 | set nowrap 93 | 94 | " SENTENCE DOUBLE-SPACING SHOULDN'T BE THE DEFAULT. 95 | set nojoinspaces 96 | 97 | " Put swap files inside the same directory as the file. 98 | set directory=. 99 | 100 | " Line numbering. 101 | set number relativenumber 102 | augroup relativenumber_toggle 103 | autocmd! 104 | autocmd BufEnter,FocusGained,InsertLeave * set relativenumber 105 | autocmd BufLeave,FocusLost,InsertEnter * set norelativenumber 106 | augroup END 107 | 108 | " I don't use arrow keys. 109 | map 110 | imap 111 | map 112 | imap 113 | map 114 | map 115 | imap 116 | imap 117 | 118 | " No mouse control. 119 | set mouse= 120 | 121 | " We are using hard tabs, like Cthulu intended. 122 | set tabstop=4 123 | set shiftwidth=4 124 | set noexpandtab 125 | 126 | " Did someone say glyphs? 127 | set encoding=utf-8 128 | 129 | " Set up airline 130 | set laststatus=2 131 | set noshowmode 132 | let g:airline_powerline_fonts=1 133 | let g:airline_theme='wombat' 134 | let g:airline#extensions#syntastic#enabled=1 135 | 136 | " Exit every mode quickly 137 | if !has('gui_running') 138 | set ttimeoutlen=10 139 | augroup FastEscape 140 | autocmd! 141 | autocmd InsertEnter * set timeoutlen=0 142 | autocmd InsertLeave * set timeoutlen=1000 143 | augroup END 144 | endif 145 | 146 | " Paste-related stuff. 147 | "set pastetoggle= 148 | set clipboard+=unnamedplus 149 | autocmd InsertLeave * set nopaste 150 | 151 | " Scrolling is crucial. 152 | set scrolloff=8 153 | set sidescrolloff=15 154 | set sidescroll=1 155 | 156 | " Syntastic stuff. 157 | set statusline+=%#warningmsg# 158 | set statusline+=%{SyntasticStatuslineFlag()} 159 | set statusline+=%* 160 | let g:syntastic_enable_signs=1 161 | let g:syntastic_loc_list_height=3 162 | 163 | " Syntastic errors. 164 | map :Errors 165 | map . :lprev 166 | map / :lnext 167 | 168 | " Set up delimit-mate. 169 | " XXX: These are objectively horrible, I need to fix this. 170 | let delimitMate_matchpairs = "(:),[:],{:}" 171 | let delimitMate_quotes = "\" ' `" 172 | let delimitMate_nesting_quotes = ['"', "'", "`"] 173 | 174 | " Enable all the things. 175 | let delimitMate_expand_cr = 1 176 | let delimitMate_expand_space = 1 177 | let delimitMate_jump_expansion = 1 178 | let delimitMate_smart_quotes = 1 179 | let delimitMate_balance_matchpairs = 1 180 | 181 | " Enable rustfmt-on-save. 182 | let g:rustfmt_autosave = 1 183 | 184 | " Make append() look like it's inserting after the current line. 185 | function! AppendLine(text) 186 | let w:wv = winsaveview() 187 | call append('.', a:text) 188 | call winrestview(w:wv) 189 | endfunction 190 | 191 | " Some helpful macros while dealing with LKML. 192 | map Ks :call AppendLine("Signed-off-by: Aleksa Sarai ") 193 | map Ka :call AppendLine("Acked-by: Aleksa Sarai ") 194 | map Kr :call AppendLine("Reviewed-by: Aleksa Sarai ") 195 | 196 | " Easier tab management. 197 | map n :tabprev 198 | map m :tabnext 199 | map tn :tabnew 200 | map td :tabclose 201 | 202 | " Easier split management. 203 | map sh :vsp . 204 | map sv :sp . 205 | noremap 206 | noremap 207 | noremap 208 | noremap 209 | 210 | " Shortcuts for end and home. 211 | map 212 | map 213 | 214 | " Inserting the date is important for certain cases (see: GPG messages). 215 | " XXX: It'd be nice if we could do this with Vim's functions. 216 | noremap d :read !date 217 | inoremap d :read !date 218 | 219 | " Speling iz gode. 220 | noremap sc :setlocal spell! spelllang=en_au 221 | inoremap sc :setlocal spell! spelllang=en_au 222 | 223 | " Increment and decrement lists. 224 | nnoremap + 225 | vnoremap + ggv 226 | nnoremap - 227 | vnoremap - ggv 228 | 229 | " Reselect the deselected blocks in visual mode. 230 | vnoremap < >gv 232 | 233 | " Stop your shift-finger from falling off. 234 | " Trust me, this *really* helps. 235 | nore ; : 236 | nore , ; 237 | -------------------------------------------------------------------------------- /.config/nvim/syntax/dockerfile.vim: -------------------------------------------------------------------------------- 1 | " dockerfile.vim - Syntax highlighting for Dockerfiles 2 | " Maintainer: Honza Pokorny 3 | " Version: 0.5 4 | 5 | if exists("b:current_syntax") 6 | finish 7 | endif 8 | 9 | let b:current_syntax = "dockerfile" 10 | 11 | syntax case ignore 12 | 13 | syntax match dockerfileKeyword /\v^\s*(ONBUILD\s+)?(ADD|CMD|ENTRYPOINT|ENV|EXPOSE|FROM|MAINTAINER|RUN|USER|VOLUME|WORKDIR|COPY)\s/ 14 | highlight link dockerfileKeyword Keyword 15 | 16 | syntax region dockerfileString start=/\v"/ skip=/\v\\./ end=/\v"/ 17 | highlight link dockerfileString String 18 | 19 | syntax match dockerfileComment "\v^\s*#.*$" 20 | highlight link dockerfileComment Comment 21 | 22 | set commentstring=#\ %s 23 | -------------------------------------------------------------------------------- /.config/nvim/syntax/mail.vim: -------------------------------------------------------------------------------- 1 | " dotfiles: collection of my personal dotfiles 2 | " Copyright (C) 2012-2023 Aleksa Sarai 3 | " 4 | " This program is free software: you can redistribute it and/or modify 5 | " it under the terms of the GNU General Public License as published by 6 | " the Free Software Foundation, either version 3 of the License, or 7 | " (at your option) any later version. 8 | " 9 | " This program is distributed in the hope that it will be useful, 10 | " but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | " GNU General Public License for more details. 13 | " 14 | " You should have received a copy of the GNU General Public License 15 | " along with this program. If not, see . 16 | 17 | " Don't kill trailing whitespace on-save. 18 | augroup trailing_whitespace_kill 19 | autocmd! 20 | augroup END 21 | -------------------------------------------------------------------------------- /.config/redshift.conf: -------------------------------------------------------------------------------- 1 | [redshift] 2 | temp-day=5500K 3 | brightness-day=1.0 4 | temp-night=1800K 5 | brightness-night=0.8 6 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | [core] 18 | # Recommended kernel default. It's amazing how many things this breaks. 19 | abbrev = 12 20 | 21 | # Whitespace. 22 | whitespace = trailing-space,space-before-tab 23 | 24 | [user] 25 | # XXX: Change this when you're using these configs. 26 | name = Aleksa Sarai 27 | email = cyphar@cyphar.com 28 | 29 | [commit] 30 | # Sign every commit. People have complicated views on this, but in 31 | # general I'm of the belief that not signing commits means that 32 | # you're putting far too much faith in maintainers manually 33 | # verifying source code before releasing it. We don't check every 34 | # line of code before signing a tag, so sign every commit I've 35 | # authored. 36 | gpgsign = true 37 | 38 | [gpg] 39 | program = gpg2 40 | 41 | [init] 42 | defaultBranch = "main" 43 | 44 | [alias] 45 | # Very useful aliases for getting the state of a repo. 46 | id = "rev-parse --verify HEAD" 47 | lg = "log --graph --abbrev-commit \ 48 | --pretty=format:'%Cred%h %C(bold red)(%G?)%Creset -%C(yellow)%d%Creset %s %Cgreen(%ar %C(bold green)%cr) %C(bold blue)<%an>%Creset'" 49 | # Short form for kernel comments. 50 | one = "show -s --pretty='format:%h (\"%s\")'" 51 | 52 | # Information about the current checked out repo. 53 | # These are just better versions of the defaults. 54 | st = "status --long" 55 | tg = "tag -l" 56 | br = "branch -v" 57 | re = "remote -v" 58 | 59 | # The obvious counterpart to git-grep. 60 | sed = !"sed() { git ls-files --no-recurse-submodules -z | \ 61 | xargs -0 -I:: find :: -maxdepth 0 -type f -print0 | \ 62 | xargs -0 sed -Ei \"$@\"; }; sed" 63 | 64 | # Updates and merging. 65 | up = "pull --rebase" 66 | sup = "submodule foreach --recursive git pull origin master" 67 | sin = "submodule update --init --recursive" 68 | mm = "merge --no-ff --log" 69 | 70 | # Pulls / checks out a GitHub pull request from origin. 71 | # TODO: Improve this so it also works with Gogs and GitLab. 72 | pr = !"pr() { git fetch origin pull/$1/head:pr-$1; }; pr" 73 | cpr = !"cpr() { git fetch origin pull/$1/head:pr-$1 && git checkout pr-$1; }; cpr" 74 | # Short-hand for "git pr ...; git mm ..." 75 | mpr = !"mpr() { git fetch origin pull/$1/head && git mm FETCH_HEAD; }; mpr" 76 | 77 | # Commit all the things! 78 | cc = !"cc() { git add -A && git commit -av; }; cc" 79 | 80 | # Rebasing. 81 | reb = !"reb() { git rebase -i HEAD~$i; }; reb" 82 | 83 | # Finding commits. 84 | ft = !"ft() { git tag --contains $1; }; ft" 85 | fb = !"fb() { git branch -a --contains $1; }; fb" 86 | 87 | # Cleaning up a repo. Deletes commits already merged against master. 88 | dm = !"dm() { git branch --merged | grep -v '\\*' | xargs -n 1 -- git branch -d; }; dm" 89 | 90 | # Get the list of authors and commiters from a range-ish. 91 | la = !"la() { git log --pretty=format:'%aN <%ae>' $1 | sort -u; }; la" 92 | lc = !"lc() { git log --pretty=format:'%cN <%ce>' $1 | sort -u; }; lc" 93 | 94 | # Get the count of authors and commiters from a range-ish. 95 | lla = !"lla() { git log --pretty=format:'%aN <%ae>' $1 | sort | uniq -c | sort -k1 -nr; }; lla" 96 | llc = !"llc() { git log --pretty=format:'%cN <%ce>' $1 | sort | uniq -c | sort -k1 -nr; }; llc" 97 | 98 | # Get more information in git-show. 99 | sf = !"sf() { git show --format=full --show-signature $1; }; sf" 100 | 101 | # Email wrapper. 102 | se = "send-email --no-format-patch --no-chain-reply-to" 103 | 104 | # Search for merge commits. 105 | find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'" 106 | show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'" 107 | 108 | [color] 109 | # Enable colours because we're not in the 80s anymore, Toto. 110 | ui = true 111 | interactive = always 112 | 113 | [color "branch"] 114 | current = yellow reverse 115 | local = yellow 116 | remote = green 117 | upstream = red 118 | 119 | [color "diff"] 120 | meta = yellow bold 121 | frag = magenta bold 122 | func = yellow 123 | old = red 124 | new = green 125 | 126 | [color "status"] 127 | added = green 128 | changed = yellow 129 | untracked = red 130 | 131 | [color "grep"] 132 | filename = magenta 133 | linenumber = blue 134 | separator = cyan 135 | function = yellow 136 | 137 | [credential] 138 | helper = cache 139 | 140 | [merge] 141 | tool = vimdiff 142 | 143 | [push] 144 | default = simple 145 | 146 | [apply] 147 | # Make sure whitespace is clean when we commit it. 148 | whitespace = fix 149 | 150 | [sendemail] 151 | identity = linux 152 | 153 | [sendemail.linux] 154 | smtpDomain = "[redacted]" 155 | smtpUser = cyphar@cyphar.com 156 | smtpServer = smtp.mailbox.org 157 | smtpServerPort = 465 158 | smtpEncryption = ssl 159 | toCmd = "kernel-git-send-email-helper -t" 160 | ccCmd = "kernel-git-send-email-helper -c" 161 | 162 | [patatt] 163 | signingkey = openpgp:C9C370B246B09F6DBCFC744C34401015D1D2D386 164 | 165 | [b4] 166 | sendemail-identity = linux 167 | 168 | [credential "smtp://smtp.mailbox.org:465"] 169 | # TODO: I should really replace this with something better that actually 170 | # reads the credential request and is a proper credential helper. 171 | helper = !"f() { echo username=cyphar@cyphar.com; echo password=$(keepassxc-helper '/Shared/Email/Mailbox'); }; f" 172 | 173 | [blame] 174 | # This file is fairly standard, so just use it for all repos. 175 | ignoreRevsFile = .git-blame-ignore-revs 176 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | *~ 18 | [._]*.s[a-w][a-z] 19 | [._]s[a-w][a-z] 20 | /.mbsyncrc*.lock 21 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | [submodule ".config/nvim/bundle/delimit-mate"] 18 | path = .config/nvim/bundle/delimit-mate 19 | url = https://github.com/Raimondi/delimitMate.git 20 | [submodule ".config/nvim/bundle/surround"] 21 | path = .config/nvim/bundle/surround 22 | url = https://github.com/tpope/vim-surround.git 23 | [submodule ".config/nvim/bundle/nerdcommenter"] 24 | path = .config/nvim/bundle/nerdcommenter 25 | url = https://github.com/scrooloose/nerdcommenter.git 26 | [submodule ".config/nvim/bundle/nerdtree"] 27 | path = .config/nvim/bundle/nerdtree 28 | url = https://github.com/scrooloose/nerdtree.git 29 | [submodule ".config/nvim/bundle/csapprox"] 30 | path = .config/nvim/bundle/csapprox 31 | url = https://github.com/vim-scripts/CSApprox 32 | [submodule ".config/nvim/bundle/supertab"] 33 | path = .config/nvim/bundle/supertab 34 | url = https://github.com/ervandew/supertab.git 35 | branch = main 36 | [submodule ".config/nvim/bundle/go"] 37 | path = .config/nvim/bundle/go 38 | url = https://github.com/fatih/vim-go.git 39 | [submodule ".config/nvim/bundle/syntastic"] 40 | path = .config/nvim/bundle/syntastic 41 | url = https://github.com/scrooloose/syntastic.git 42 | [submodule ".config/nvim/bundle/airline"] 43 | path = .config/nvim/bundle/airline 44 | url = https://github.com/vim-airline/vim-airline.git 45 | [submodule ".config/nvim/bundle/airline-themes"] 46 | path = .config/nvim/bundle/airline-themes 47 | url = https://github.com/vim-airline/vim-airline-themes.git 48 | [submodule ".config/nvim/bundle/rust"] 49 | path = .config/nvim/bundle/rust 50 | url = https://github.com/rust-lang/rust.vim.git 51 | [submodule ".config/nvim/bundle/bats"] 52 | path = .config/nvim/bundle/bats 53 | url = https://github.com/vim-scripts/bats.vim.git 54 | -------------------------------------------------------------------------------- /.local/bin/battery-level: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | function bail() { 21 | echo "battery-level: $@" >&2 22 | exit 1 23 | } 24 | 25 | function usage() { 26 | cat >&2 <<-EOF 27 | usage: battery-level [-h] [-x ] ... 28 | 29 | Check the given conditions against the current battery level, exiting with 30 | a non-zero exit code if any of the conditions are not met. 31 | 32 | -x is a shorthand for ( battery-level && ||: ) 33 | 34 | There are only a few supported conditions, and they are specified using the 35 | syntax :: 36 | 37 | status: Status is (grep -i) matched against . 38 | capacity_level: Capacity-level is (grep -i) matched against . 39 | capacity: Capacity (percent) is arithmetically compared to the 40 | given as though it had been passed to 41 | (( \$capacity )). 42 | 43 | The primary usecase is to add something like the following to /etc/crontab: 44 | 45 | * * * * * battery-level -x "systemctl suspend" 'status:discharging' 'capacity:<3' 46 | EOF 47 | } 48 | 49 | # Get the options. 50 | local COMMAND= 51 | while getopts "x:h" OPT; do 52 | case "$OPT" in 53 | (x) 54 | COMMAND="$OPTARG" 55 | ;; 56 | (h) 57 | usage 58 | exit 0;; 59 | esac 60 | done 61 | 62 | # Get the set of conditions. 63 | shift "$(($OPTIND - 1))" 64 | local conditions=("$@") 65 | 66 | # What batteries are present in the system? 67 | local batteries=() 68 | for dir in /sys/class/power_supply/* 69 | do 70 | grep -qi "^battery$" "$dir/type" || continue 71 | batteries+=("$dir") 72 | done 73 | 74 | # We only support single-battery mode. 75 | [[ "${#batteries[@]}" -gt 0 ]] || bail "No batteries found." 76 | [[ "${#batteries[@]}" -eq 1 ]] || bail "More than one battery found: ${batteries[@]}" 77 | local battery="${batteries[@]}" 78 | 79 | # Let's evalute the conditionals... 80 | local error= 81 | for cond in "${conditions[@]}" 82 | do 83 | cond_type="$(cut -d: -f1 <<<"$cond")" 84 | cond_body="$(cut -d: -f2- <<<"$cond")" 85 | case "$cond_type" in 86 | (status|capacity_level) 87 | grep -qi "^$cond_body$" <"$battery/$cond_type" || error=1 88 | ;; 89 | (capacity) 90 | (( $(<"$battery/capacity") $cond_body )) || error=1 91 | ;; 92 | esac 93 | done 94 | 95 | # No command, just exit with the current error state. 96 | [ -n "$COMMAND" ] || exit "$error" 97 | # Run the command if there was no error. 98 | [ -n "$error" ] || exec zsh -c "$COMMAND" 99 | -------------------------------------------------------------------------------- /.local/bin/configure-keyboards: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (C) 2012-2019 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # setxkbmap_name [...] 18 | function setxkbmap_name() { 19 | device_name="keyboard:$1" 20 | shift 21 | device_id="$(xinput list --id-only "$device_name" ||:)" 22 | if [ -n "$device_id" ] 23 | then 24 | setxkbmap -device "$device_id" "$@" 25 | fi 26 | } 27 | 28 | # NOTE: For now, I've disabled the per-keyboard configurations here. For some 29 | # reason, some aspect of the multi-layout configuration makes it such that you 30 | # cannot configure both multi-layout keyboards and single-layout keyboards... 31 | 32 | # Set up us<->jp keymap switching for the default keyboard. It turns out that 33 | # configuring this using xorg.conf.d has been broken for more than a decade[1] 34 | # and so it's much simpler to just do it manually. 35 | # 36 | # [1]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/291 37 | #setxkbmap_name "AT Translated Set 2 keyboard" -layout us,jp -model thinkpad,microsoftpro -option grp:ralt_rshift_toggle 38 | # As a fallback, set the master keyboard... 39 | setxkbmap -layout us,jp -model thinkpad,microsoftpro -option grp:ralt_rshift_toggle 40 | 41 | # Configure my Japanese keyboards to just use a Japanese layout. As with layout 42 | # switching, trying to do this in xorg.conf.d didn't work at all. 43 | #setxkbmap_name "Logitech ERGO K860" -layout jp -model microsoftpro 44 | #setxkbmap_name "MOBO K2TF83J Keyboard" -layout jp 45 | -------------------------------------------------------------------------------- /.local/bin/git-lh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | list-contributors() { 21 | logargs=("$@") 22 | 23 | git log --format=email "${logargs[@]}" | \ 24 | sed -nE '/^(From|[A-Za-z-]*-by):\s*/ s/^(From|[A-Za-z-]*-by):\s*(.*)/\2/ p' | \ 25 | sort -u 26 | } 27 | 28 | cmd="$(basename "$0")" 29 | case "$cmd" in 30 | git-lh) # "list helpers" 31 | list-contributors "$@" 32 | ;; 33 | *) 34 | echo "unknown command $cmd" >&2 35 | exit 1 36 | ;; 37 | esac 38 | -------------------------------------------------------------------------------- /.local/bin/kboot: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # kboot is a qemu wrapper that allows us to boot a test kernel (with 19 | # out-of-tree modules) within a VM for fast kernel development. 20 | 21 | set -Eeuo pipefail 22 | 23 | QEMU="qemu-system-x86_64" 24 | KERNEL_STORE="$HOME/build/kernel" 25 | mkdir -p "$KERNEL_STORE" 26 | 27 | function bail() { 28 | echo "kboot: $@" >&2 29 | exit 1 30 | } 31 | 32 | function usage() { 33 | cat >&2 <<-EOF 34 | usage: kboot help 35 | kboot install 36 | kboot build [-m ]... [-b ]... [] 37 | kboot boot [] 38 | 39 | KERNEL_STORE=$KERNEL_STORE 40 | 41 | Boots a kernel inside QEMU (useful for testing purposes). There are a few 42 | subcommands used for kboot: 43 | 44 | help: Show this help message. 45 | 46 | install: Install an already-built Linux tree, and build a basic initramfs. 47 | This command must be run within a checkout of the Linux source, 48 | and already be built with "make bzImage modules"). By default, 49 | this will run "build" as well (but you can re-run it 50 | explicitly). 51 | 52 | build: Builds an initramfs for the given . If you want to add 53 | any extra modules, you should specify them using -m and add them 54 | to \$KERNEL_STORE//mods/. If you need a specific binary 55 | in the initramfs, you can specify it with -b. 56 | 57 | boot: Boots the kernel using $QEMU. All I/O is done to the 58 | terminal (ctrl-a+c to get the QEMU management shell). 59 | 60 | A normal user would probably be happy with just doing this: 61 | 62 | % kboot install 63 | % kboot boot 64 | ... 65 | 66 | If is not specified, the latest version (in terms of mtime) is 67 | used. 68 | EOF 69 | } 70 | 71 | function latest_version() { 72 | basename "$(ls -t "$KERNEL_STORE" | head -1)" 73 | } 74 | 75 | function cmd_help() { 76 | echo "kboot help" "$@" 77 | [ "$#" -eq 0 ] || bail "Too many arguments to 'kboot install'." 78 | 79 | usage 80 | exit 0 81 | } 82 | 83 | function cmd_install() { 84 | echo "kboot install" "$@" 85 | [ "$#" -eq 0 ] || bail "Too many arguments to 'kboot install'." 86 | 87 | local version="$(make kernelrelease)" 88 | local store="$KERNEL_STORE/$version" 89 | mkdir -p "$store" 90 | 91 | set -x 92 | cp arch/x86/boot/bzImage "$store/vmlinuz" 93 | make INSTALL_MOD_PATH="$store/mods/" modules_install 94 | touch "$store" 95 | cmd_build "$version" 96 | } 97 | 98 | function cmd_build() { 99 | echo "kboot build" "$@" 100 | 101 | local modules=() 102 | local binaries=() 103 | local version="$(latest_version)" 104 | while getopts "m:b:" OPT; do 105 | case "$OPT" in 106 | (m) 107 | modules+=("$OPTARG") 108 | ;; 109 | (b) 110 | binaries+=("$OPTARG") 111 | ;; 112 | esac 113 | done 114 | 115 | # [] 116 | [ "$OPTIND" -lt 1 ] || shift "$(($OPTIND - 1))" 117 | [ "$#" -le 1 ] || bail "Too many arguments to 'kboot build'." 118 | [ "$#" -lt 1 ] || version="$1" 119 | 120 | local store="$KERNEL_STORE/$version" 121 | set -x 122 | /sbin/depmod -a --basedir "$store/mods/" "$version" 123 | dracut --kver "$version" --kmoddir "$store/mods/lib/modules/$version" \ 124 | --modules "bash base shutdown network ifcfg" \ 125 | --add-drivers "configfs ${modules[@]}" \ 126 | --install "ps grep ${binaries[@]}" \ 127 | --no-hostonly --no-hostonly-cmdline \ 128 | --force "$store/initramfs" 129 | } 130 | 131 | function cmd_boot() { 132 | echo "kboot boot" "$@" 133 | local version="$(latest_version)" 134 | 135 | # [] 136 | [ "$#" -le 1 ] || bail "Too many arguments to 'kboot boot'." 137 | [ "$#" -lt 1 ] || version="$1" 138 | 139 | local store="$KERNEL_STORE/$version" 140 | set -x 141 | "$QEMU" -enable-kvm -m 2048 -smp 2 \ 142 | -kernel "$store/vmlinuz" -initrd "$store/initramfs" \ 143 | -nographic -append "ip=dhcp rd.shell=1 console=ttyS0" \ 144 | -device e1000,netdev=network0 \ 145 | -netdev user,id=network0 146 | } 147 | 148 | [ "$#" -ge 1 ] || bail "Missing argument, run 'kboot help'." 149 | 150 | # Run the command with rest of the arguments -- a poor man's subcommand. 151 | fn="cmd_$1" ; shift 152 | "$fn" "$@" 153 | -------------------------------------------------------------------------------- /.local/bin/keepassxc-helper: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # keepassxc-helper is used as part of my Mutt configuration to automate getting 19 | # passwords without storing the password (even in encrypted form) in my 20 | # mailbox. Mutt only allows you to use the first line of output as a variable 21 | # (and it doesn't allow interactive prompts) so we have to improvise. 22 | 23 | # NOTE: keepassxc-cli has a really badly defined UX. I've done some work to fix 24 | # the changes in v2.3.0 which will allow scripting to be done in a *far* 25 | # more sane way. See keepassxc#1289 and keepassxc#1280. 26 | 27 | set -e 28 | 29 | KDBX="$HOME/doc/secret/passwords.kdbx" 30 | ATTRIBUTE="Password" 31 | RETRY=3 32 | 33 | # Output help page. 34 | function usage() { 35 | cat <] [-k ] 37 | 38 | A wrapper around 'keepassxc-cli show' which provides a GUI password prompt. It 39 | is usable from a Mutt context (which is how I personally manage my passwords 40 | for Mutt and offlineimap -- this has an obvious downside of not really working 41 | over SSH unless you do X11 forwarding). 42 | 43 | Options: 44 | -a -- Attribute of the entry to output (default: "$ATTRIBUTE"). 45 | -k -- Path the KeePassXC database (default: $KDBX). 46 | -- Entry name passed to 'keepassxc-cli show'. 47 | EOH 48 | } 49 | 50 | function bail() { 51 | echo "$@" >&2 52 | usage 53 | exit 1 54 | } 55 | 56 | # Succeeds if $1 is older than $2. 57 | function version_isolder() { 58 | [[ "$(printf "$1\n$2\n" | sort -V | head -n1)" == "$1" ]] || return 1 59 | } 60 | 61 | # Get the options. 62 | while getopts "a:p:h" OPT; do 63 | case "$OPT" in 64 | (a) 65 | ATTRIBUTE="${OPTARG}" 66 | ;; 67 | (k) 68 | KDBX="${OPTARG}" 69 | ;; 70 | (h) 71 | usage 72 | exit 0;; 73 | esac 74 | done 75 | [[ "$OPTIND" -le "$#" ]] || bail "Missing operand." 76 | shift $(($OPTIND - 1)) 77 | [[ "$#" -eq 1 ]] || bail "Incorrect number of operands." 78 | ENTRY="$1" 79 | 80 | # Get keepass version. In 2.3.0 and later the API has changed quite a lot. 81 | KEEPASSXC_VERSION="$(keepassxc-cli --version)" 82 | 83 | if ( version_isolder "$KEEPASSXC_VERSION" "2.3.0" ) 84 | then 85 | # Cannot use --attributes in older KeePassXC versions. 86 | bail "Cannot use --attributes with pre-2.3.0 KeePassXC versions." 87 | fi 88 | 89 | RETRY_NUM=0 90 | RETRY_MAX=5 91 | while true 92 | do 93 | # If the requested entry is under /Shared (which is shared through the 94 | # SecretService DBus API) and is a Password, then we can request it through 95 | # the API without asking for the database password. 96 | if [[ "$ENTRY" =~ ^/Shared/ ]] 97 | then 98 | # SecretService entries don't have the "/Shared" prefix. 99 | SS_ENTRY="${ENTRY#"/Shared"}" 100 | 101 | if [[ "$ATTRIBUTE" == "Password" ]] 102 | then 103 | #output="$(secret-tool lookup Path "$SS_ENTRY")" 104 | cmd='secret-tool lookup Path "$SS_ENTRY"' 105 | else 106 | #output="$(secret-tool search Path "$SS_ENTRY" 2>&1 | grep -oP "^attribute.$ATTRIBUTE\s*=\s*\K.*$")" 107 | cmd='secret-tool search Path "$SS_ENTRY" 2>&1 | grep -oP "^attribute.$ATTRIBUTE\s*=\s*\K.*$"' 108 | fi 109 | 110 | if ( eval "$cmd" &>/dev/null ) 111 | then 112 | eval "$cmd" 113 | exit 0 114 | fi 115 | fi 116 | 117 | if [ "$RETRY_NUM" -eq 0 ] 118 | then 119 | PROMPT="Password for '$KDBX': " 120 | elif [ "$RETRY_NUM" -lt "$RETRY_MAX" ] 121 | then 122 | PROMPT="Bad password, re-enter password for '$KDBX': " 123 | else 124 | bail "Could not unlock '$KDBX': bad password." 125 | fi 126 | 127 | # Get the password. 128 | #DISPLAY="${DISPLAY:?DISPLAY is not set.}" 129 | #DB_PASSWORD="$(zenity --password --title="KeePassXC Password" --display="$DISPLAY" 2>/dev/null)" 130 | read -rs "DB_PASSWORD?$PROMPT" ; printf '\n' >&2 131 | if [[ -z "$DB_PASSWORD" ]] 132 | then 133 | echo "Empty passwords are not accepted." >&2 134 | continue 135 | fi 136 | 137 | RETRY_NUM="$(($RETRY_NUM + 1))" 138 | 139 | # Make sure the password actually works and then Get the thing we wanted from 140 | # KeePassXC. 141 | if (version_isolder "$KEEPASSXC_VERSION" "2.3.0") 142 | then 143 | echo "$DB_PASSWORD" | keepassxc-cli ls "$KDBX" &>/dev/null || continue 144 | KP_PASSWORD="$(echo "$DB_PASSWORD" | keepassxc-cli show --attributes "$ATTRIBUTE" "$KDBX" "$ENTRY" | tail -1)" 145 | else 146 | echo "$DB_PASSWORD" | keepassxc-cli list "$KDBX" &>/dev/null || continue 147 | KP_PASSWORD="$(echo "$DB_PASSWORD" | keepassxc-cli show $KDBX $* | tail -1)" 148 | fi 149 | break 150 | done 151 | 152 | # And echo just the password. 153 | echo "$KP_PASSWORD" 154 | -------------------------------------------------------------------------------- /.local/bin/kernel-git-send-email-helper: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # kernel-git-send-email-helper is a very small wrapper around 19 | # scripts/get_maintainer.pl to handle cover letters (send them to everyone at 20 | # least one of the patches gets addressed to) and handle both --to-cmd and 21 | # --cc-cmd slightly differently. 22 | 23 | set -Eeuo pipefail 24 | 25 | function bail() { 26 | echo "$@" >&2 27 | exit 1 28 | } 29 | 30 | function usage() { 31 | bail "usage: $0 [-tc] <1234-foo.patch>..." 32 | } 33 | 34 | [ -x ./scripts/get_maintainer.pl ] || bail "kernel-git-send-email-helper must be run in linux source tree root" 35 | 36 | args=("--no-rolestats") 37 | while getopts "tc" o; do 38 | case "$o" in 39 | t) 40 | # --to-cmd 41 | args+=("--no-l" "--m" "--r") 42 | ;; 43 | c) 44 | # --cc-cmd 45 | args+=("--l" "--no-m" "--no-r" "--no-git" "--no-git-fallback") 46 | ;; 47 | *) 48 | usage 49 | ;; 50 | esac 51 | done 52 | shift $((OPTIND-1)) 53 | 54 | [ "$#" -gt 0 ] || usage 55 | 56 | if [ "$#" -eq 1 ] && [[ "$(basename $1)" =~ ^(.*-)?0000-cover-letter.patch$ ]] 57 | then 58 | # This is a cover-letter -- collect all of the people who will be sent a 59 | # mail by the other .patch files in the same series (we assume there are no 60 | # stale patches and all of the relevant patches in the patchset -- and 61 | # nothing else -- has the same prefix). 62 | coverletter="$1" 63 | patch_dir="$(dirname "$coverletter")" 64 | patch_prefix="$(sed -E 's/^(.*)0000-cover-letter.patch$/\1/' <<<"$(basename "$coverletter")")" 65 | ./scripts/get_maintainer.pl "${args[@]}" "$patch_dir/$patch_prefix"*.patch 2>/dev/null 66 | else 67 | ./scripts/get_maintainer.pl "${args[@]}" "$@" 68 | fi 69 | -------------------------------------------------------------------------------- /.local/bin/lockmyi3: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | screenshot="$(mktemp --tmpdir lockymi3-screenshot.XXXXXX.png)" 21 | lockimg="$(mktemp --tmpdir lockymi3-lockscreen.XXXXXX.png)" 22 | trap "rm -f '$screenshot' '$lockimg'" EXIT 23 | 24 | # Output help page. 25 | function _help() { 26 | cat <] [options]... 28 | 29 | Locks your screen with i3lock, using a pixelated version of the current screen 30 | as the background. The semantics of the "current screen" are borrowed from 31 | ImageMagick's 'import -screen -window root' options. 32 | 33 | Options: 34 | -g -- Switch-to-greeter after screen lock. 35 | -p -- Set the the size of each blocky pixel to (in pixels). 36 | options -- Options that are passed through to i3lock. 37 | EOH 38 | } 39 | 40 | # Get the options. 41 | local __block_size=20 42 | local __switch_to_greeter= 43 | while getopts "ghp:" __opt; do 44 | case "$__opt" in 45 | (g) 46 | __switch_to_greeter=1 47 | ;; 48 | (h) 49 | _help 50 | exit 0 51 | ;; 52 | (p) 53 | __block_size="${OPTARG}" 54 | ;; 55 | esac 56 | done 57 | 58 | # Get pass-through options. 59 | shift "$((OPTIND-1))" 60 | 61 | # Gets the (width, height) of the screen. 62 | read __screen_x __screen_y <<<$(xrandr -q | awk ' 63 | # xrandr tells us screen sizes. 64 | $1 == "Screen" { 65 | # Line is of the form: 66 | # Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767 67 | for (i = 1; i <= NF && $i != "current"; i++) 68 | ; 69 | 70 | # We did not find "current". 71 | if ($i != "current") 72 | exit 1; 73 | 74 | # Output the dimensions (there may be a trailing comma). 75 | print $(i+1), $(i+3); 76 | exit; 77 | }' | tr -d ,) 78 | 79 | # Calculate the "reduced" height and width for the down-scaling. 80 | local __reduced_x="$((__screen_x/__block_size))" 81 | local __reduced_y="$((__screen_y/__block_size))" 82 | 83 | # Actually do the locking. Since `convert -scale` doesn't do blurring, scaling 84 | # down and then back up is an efficient method of producing a pixelated image. 85 | import -screen -window root -silent "png:$screenshot" 86 | convert "png:$screenshot" \ 87 | -scale '!'"${__reduced_x}x${__reduced_y}" \ 88 | -scale '!'"${__screen_x}x${__screen_y}" \ 89 | "png:$lockimg" 90 | i3lock "$@" -i "$lockimg" 91 | 92 | # Switch greeters if we have been asked to. There isn't really a nice way of 93 | # doing this that is agnostic to DM (since gdmflexiserver is GNOME specific). 94 | # So we just use dm-tool -- screw it. Note that dm-tool is *not* secure (the 95 | # tty is just switched -- your old session is trivially accessible) and you 96 | # must always pair it with i3lock. 97 | [[ "$__switch_to_greeter" ]] && dm-tool switch-to-greeter 98 | -------------------------------------------------------------------------------- /.local/bin/mail-generate-msgid: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This generates lore-friendly message-id headers that are safe, unique, and 3 | # provide better UX for someone using lore to retrieve messages. 4 | 5 | set -Eeuo pipefail 6 | 7 | function rand() { 8 | # Technically all of the characters in standard base64 are allowed 9 | # according to RFC 5322, but it seems possible that some MTA would have an 10 | # issue with "/" in a Message-ID, so best to just stick to standard things 11 | # people have in their Message-ID. 12 | openssl rand -base64 "$1" | tr -dc "a-zA-Z0-9" 13 | } 14 | 15 | hostname="${1:-cyphar}" 16 | if ( diceware &>/dev/null ) ; then 17 | # Try to use some unique words to make it slightly easier to differentiate 18 | # Message-IDs. 19 | unique="$(diceware --no-caps -d. -n2 -w en_adjectives en_nouns)-$(rand 9)" 20 | else 21 | # ... otherwise just use some random garbage. 22 | unique="$(rand 27)" 23 | fi 24 | echo "$(date -u '+%Y%m%d.%H%M%S')-$unique@$hostname" 25 | -------------------------------------------------------------------------------- /.local/bin/mbsync-helper: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # mbsync-helper allows us to run mbsync with a given interval in the 19 | # background. It also removes the need to run PassCmd on each mbsync call, by 20 | # replacing PassCmd lines with the result of executing them. 21 | 22 | set -e 23 | 24 | INTERVAL="15m" 25 | MBSYNCRC="$HOME/.mbsyncrc" 26 | 27 | # Output help page. 28 | function usage() { 29 | cat <] [-c ] 31 | 32 | A wrapper around 'mbsync' which provides auto-retry support with the given 33 | interval. It is usable from a Mutt context (and it echos the INBOX path to 34 | stdout, which means it can be used as a variable in Mutt). 35 | 36 | Options: 37 | -i -- Number of seconds between each invocation of 'mbsync' (default: $INTERVAL). 38 | -c -- Base configuration to run mbsync under (default: "$MBSYNCRC"). 39 | EOH 40 | } 41 | 42 | function bail() { 43 | echo "$@" >&2 44 | exit 1 45 | } 46 | 47 | function bail_usage() { 48 | echo "$@" >&2 49 | usage 50 | exit 1 51 | } 52 | 53 | # Get the options. 54 | while getopts "hi:c:" OPT; do 55 | case "$OPT" in 56 | (i) 57 | INTERVAL="${OPTARG}" 58 | ;; 59 | (c) 60 | MBSYNCRC="${OPTARG}" 61 | ;; 62 | (h) 63 | usage 64 | exit 0;; 65 | (\?) 66 | bail_usage 67 | ;; 68 | esac 69 | done 70 | 71 | # Make sure that we don't run more than one mbsyncrc instance. 72 | MBSYNCRC_LOCK="$MBSYNCRC.lock" 73 | if [ -f "$MBSYNCRC_LOCK" ] 74 | then 75 | pid="$(cat "$MBSYNCRC_LOCK")" 76 | if ( ps --pid="$pid" -o args 2>/dev/null | grep "mbsync-script" &>/dev/null ) 77 | then 78 | bail "mbsync already running as pid $pid" 79 | fi 80 | rm -f "$MBSYNCRC_LOCK" 81 | fi 82 | ! [ -e "$MBSYNCRC_LOCK" ] || bail "$MBSYNCRC_LOCK exists and is not a file." 83 | 84 | # Set up our temporary mbsyncrc. 85 | TMP_MBSYNCRC="$(mktemp --tmpdir mbsyncrc-helper.XXXXX)" 86 | chmod 0600 "$TMP_MBSYNCRC" 87 | trap "{ rm -rf '$TMP_MBSYNCRC'; exit 255; }" SIGINT SIGTERM 88 | 89 | # Execute PassCmd lines and store them inside the "$TMP_MBSYNCRC". This isn't 90 | # particularly pretty but it does allow us to make the interval handling 91 | # un-attended. 92 | while read -u 3 line 93 | do 94 | if ( echo "$line" | grep -iv '^PassCmd' &>/dev/null ) 95 | then 96 | echo "$line" 97 | continue 98 | fi 99 | cmd="$(echo "$line" | sed -E 's|^PassCmd[[:space:]]+\+?(.*)$|\1|gi')" 100 | printf 'Pass "%q"\n' "$(eval sh -c "$cmd")" 101 | done 3<"$MBSYNCRC" >"$TMP_MBSYNCRC" 102 | 103 | # We have to generate a new script in order to be able to use setsid(1). This 104 | # script just runs "mbsync" in a loop. 105 | TMP_SCRIPT="$(mktemp --tmpdir mbsync-script.XXXXX)" 106 | cat >"$TMP_SCRIPT" < "$MBSYNCRC_LOCK" 114 | trap "{ rm -rf '$TMP_MBSYNCRC' '$MBSYNCRC_LOCK'; exit; }" SIGINT SIGTERM EXIT 115 | 116 | while true 117 | do 118 | mbsync -c '$TMP_MBSYNCRC' -a 119 | sleep '$INTERVAL' 120 | done 121 | EOS 122 | chmod 0700 "$TMP_SCRIPT" 123 | 124 | # Run our "mbsync" helper with our generated mbsyncrc file. 125 | setsid "$TMP_SCRIPT" &>/dev/null 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Make sure no other redshift instance is running. 19 | pgrep -x redshift && exit 20 | 21 | # Run redshift. 22 | exec redshift $* 23 | -------------------------------------------------------------------------------- /.local/bin/wg-enroll: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # wg-enroll: enroll a new wireguard client 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | function bail() { 21 | echo "ERROR:" "$@" >&2 22 | exit 2 23 | } 24 | 25 | function log() { 26 | echo "INFO:" "$@" >&2 27 | } 28 | 29 | function public_ip() { 30 | dig +short myip.opendns.com @resolver1.opendns.com 31 | } 32 | 33 | function generate_addresses() { 34 | local DEVICEID="${1:-0}" 35 | IPv4="$(printf "10.%d.%d.1/32" "$NETWORKID" "$DEVICEID")" 36 | IPv6="$(printf "fd42:dead:beef:%.2x%.2x::/64" "$NETWORKID" "$DEVICEID")" 37 | echo "$IPv4,$IPv6" 38 | } 39 | 40 | function usage() { 41 | bail "usage: wg-enroll [-C ]\n" \ 42 | " [-F ]\n" \ 43 | " [-i ]\n" \ 44 | " [-n ]\n" \ 45 | " [-o ]\n" \ 46 | " [-P ]" 47 | } 48 | 49 | local NETWORKID=0 50 | local CONFIG_ROOT="/etc/wireguard" 51 | local CONFIG_NAME="wg-$(hostname -s)" 52 | local SERVER_ENDPOINT="$(hostname -f || public_ip)" 53 | local OUTPUT="text" 54 | 55 | local CLIENT_SECKEY="" 56 | local CLIENT_PUBKEY="" 57 | 58 | while getopts "C:F:i:n:o:P:h" opt; do 59 | case "$opt" in 60 | C) 61 | CONFIG_ROOT="$OPTARG" 62 | ;; 63 | F) 64 | SERVER_ENDPOINT="$OPTARG" 65 | ;; 66 | i) 67 | CONFIG_NAME="$OPTARG" 68 | ;; 69 | n) 70 | NETWORKID="$OPTARG" 71 | ;; 72 | o) 73 | OUTPUT="$OPTARG" 74 | ;; 75 | P) 76 | CLIENT_PUBKEY="$OPTARG" 77 | ;; 78 | h) 79 | usage 80 | ;; 81 | \:) 82 | echo "missing argument: -$OPTARG" >&2 83 | usage 84 | ;; 85 | \?) 86 | echo "invalid option: -$OPTARG" >&2 87 | usage 88 | ;; 89 | esac 90 | done 91 | local NETWORKID_HEX="$(printf '%.2x' "$NETWORKID")" 92 | 93 | function qrencode_cat() { 94 | qrencode -t ansiutf8 95 | } 96 | 97 | local formatter= 98 | case "$OUTPUT" in 99 | qr) 100 | formatter=qrencode_cat 101 | ;; 102 | text) 103 | formatter=cat 104 | ;; 105 | *) 106 | bail "Unknown formatter $OUTPUT" 107 | ;; 108 | esac 109 | 110 | local CONFIG="$CONFIG_ROOT/$CONFIG_NAME.conf" 111 | 112 | # If there is no config already there, we need to quickly set it up. 113 | if ! [ -f "$CONFIG" ] 114 | then 115 | # NOTE: This is kind of ugly to get the default interface. Should also be 116 | # configurable. 117 | HOST_NIC="$(route -n | awk '$1 == "0.0.0.0" { print $8 }')" 118 | log "Generating $CONFIG header (host_nic=$HOST_NIC)." 119 | 120 | # We first make sure that the file is created with the right mode -- 121 | # without a window for someone to read the config underneath us. 122 | ( umask 377 ; touch "$CONFIG" ; chmod 0400 "$CONFIG" ) 123 | 124 | # Now generate our server config header. 125 | cat >"$CONFIG" <<-EOF 126 | # This file was auto-generated by wg-enroll on $(date -u). 127 | # If you edit it by hand, consider contributing to wg-enroll 128 | # at . 129 | 130 | [Interface] 131 | Address = $(generate_addresses) 132 | ListenPort = 51820 133 | PrivateKey = $(wg genkey) 134 | # IPv4 135 | PostUp = iptables -A FORWARD -i %i -j ACCEPT 136 | PostUp = iptables -A FORWARD -o %i -j ACCEPT 137 | PostUp = iptables -t nat -A POSTROUTING -o $HOST_NIC -j MASQUERADE 138 | PostDown = iptables -D FORWARD -i %i -j ACCEPT 139 | PostDown = iptables -D FORWARD -o %i -j ACCEPT 140 | PostDown = iptables -t nat -D POSTROUTING -o $HOST_NIC -j MASQUERADE 141 | # IPv6 142 | PostUp = ip6tables -A FORWARD -i %i -j ACCEPT 143 | PostUp = ip6tables -A FORWARD -o %i -j ACCEPT 144 | PostUp = ip6tables -t nat -A POSTROUTING -o $HOST_NIC -j MASQUERADE 145 | PostDown = ip6tables -D FORWARD -i %i -j ACCEPT 146 | PostDown = ip6tables -D FORWARD -o %i -j ACCEPT 147 | PostDown = ip6tables -t nat -D POSTROUTING -o $HOST_NIC -j MASQUERADE 148 | EOF 149 | fi 150 | 151 | # Only generate a key if it's not provided. Generating keys for users is quite 152 | # dodgy already, but is required in order to make the setup require no 153 | # round-trips or manual editing. 154 | if [ -z "$CLIENT_PUBKEY" ] 155 | then 156 | log "No public key given (-P), generating new private key for client." 157 | CLIENT_SECKEY="$(wg genkey)" 158 | CLIENT_PUBKEY="$(wg pubkey <<<"$CLIENT_SECKEY")" 159 | fi 160 | local PRESHAREDKEY="$(wg genpsk)" 161 | 162 | [[ -n "$CLIENT_PUBKEY" ]] || bail "Failed to generate public key using $CLIENT_SECKEY." 163 | 164 | # TODO: Parse TOML properly... 165 | local NEW_DEVICEID="$(($(grep "\[Peer\]" "$CONFIG" | wc -l) + 1))" 166 | local SERVER_PUBKEY="$(grep "PrivateKey = " "$CONFIG" | sed -E 's/^[^=]*= (.*)$/\1/' | wg pubkey)" 167 | 168 | # Add to configuration. 169 | log "Updating $CONFIG for client (10.$NETWORKID.$NEW_DEVICEID.1)." 170 | ( 171 | cat "$CONFIG" - </etc/sysctl.d/90-wireguard-forward.conf </dev/null || bail "Failed to load new sysctl values." 210 | 211 | # Update the configuration of the interface. 212 | log "Restarting host-side wireguard interface with new $CONFIG." 213 | systemctl enable "wg-quick@$CONFIG_NAME" || bail "Failed to enable-on-reboot wg-quick@$CONFIG_NAME" 214 | systemctl restart "wg-quick@$CONFIG_NAME" || bail "Failed to restart wg-quick@$CONFIG_NAME" 215 | -------------------------------------------------------------------------------- /.local/bin/wyt: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | v="$1" 21 | f="/tmp/watchv$v.webm" 22 | 23 | [ -f "$f" ] || yt-dlp -f "best[height<720]" -o "$f" "https://youtube.com/watch?v=$v" 24 | mpv "$f" 25 | -------------------------------------------------------------------------------- /.local/bin/zsh-raw: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | export TMUX="fake" 19 | exec zsh 20 | -------------------------------------------------------------------------------- /.mbsyncrc-personal: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | MaildirStore personal-local 18 | Subfolders Verbatim 19 | Path "~/mail/personal/" 20 | Inbox "~/mail/personal/inbox" 21 | Trash "trash" 22 | 23 | IMAPAccount mailbox 24 | Host imap.mailbox.org 25 | Port 993 26 | User "cyphar@cyphar.com" 27 | PassCmd +"keepassxc-helper '/Shared/Email/Mailbox'" 28 | TLSType IMAPS 29 | TLSVersions +1.2 +1.3 30 | 31 | IMAPStore mailbox-remote 32 | Account mailbox 33 | 34 | Channel personal-inbox 35 | Far :mailbox-remote: 36 | Near :personal-local: 37 | Sync All 38 | Expunge Both 39 | Create Both 40 | CopyArrivalDate yes 41 | 42 | Channel personal-sent 43 | Far :mailbox-remote:Sent 44 | Near :personal-local:sent 45 | Sync All 46 | Expunge Both 47 | Create Both 48 | CopyArrivalDate yes 49 | 50 | Channel personal-archives 51 | Far :mailbox-remote: 52 | Near :personal-local: 53 | Pattern Archives/* 54 | Sync All 55 | Expunge Both 56 | Create Both 57 | CopyArrivalDate yes 58 | 59 | Group personal 60 | Channels personal-inbox personal-sent 61 | -------------------------------------------------------------------------------- /.mbsyncrc-suse: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | MaildirStore suse-local 18 | SubFolders Verbatim 19 | Path "~/mail/suse/" 20 | Inbox "~/mail/suse/inbox" 21 | Trash "Trash" 22 | 23 | IMAPAccount susede 24 | Host imap.suse.de 25 | Port 993 26 | UserCmd +"keepassxc-helper -a UserName '/Shared/Email/SUSE'" 27 | PassCmd +"keepassxc-helper '/Shared/Email/SUSE'" 28 | TLSType IMAPS 29 | TLSVersions +1.2 +1.3 30 | 31 | IMAPStore susede-remote 32 | Account susede 33 | 34 | Channel suse 35 | Far :susede-remote: 36 | Near :suse-local: 37 | Pattern * !Spam 38 | Sync All 39 | Expunge Both 40 | Create Both 41 | CopyArrivalDate yes 42 | -------------------------------------------------------------------------------- /.mutt/mailcap: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Dump a formatted version of HTML emails into the mutt pager. For extra 18 | # paranoia points, apply as many restrictions as possible. 19 | text/html; lynx -assume_charset=%{charset} -display_charset=utf-8 -collapse_br_tags -cookies=off -restrictions=all -dump %s; nametemplate=%s.html; copiousoutput; 20 | 21 | # zathura is missing a bunch of features (such as dealing with PDF fields) but 22 | # for minimal viewing it's pretty nice. 23 | application/pdf; zathura %s; 24 | -------------------------------------------------------------------------------- /.mutt/muttrc: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # muttrc -- this is the "common" subset of my mutt configurations between all 18 | # of my mailboxes. Individual mailboxes are configured in ~/.mutt/muttrc-$box 19 | # and then I have an alias like Xmutt='mutt -F ~/.mutt/muttrc-XYZ'. 20 | 21 | set realname="Aleksa Sarai" 22 | set signature="$HOME/.mutt/signature" 23 | set my_date_format="%F" 24 | set my_datetime_format="$my_date_format at %H:%M:%S%z" 25 | set attribution="On %{$my_date_format}, %n <%A> wrote:" 26 | set forward_format="Fwd: %s" 27 | set editor="nvim -c 'set tw=72 ft=mail spell spelllang=en'" 28 | set edit_headers 29 | set mime_forward 30 | 31 | # Set up folders. 32 | set mbox_type=Maildir 33 | set my_mailroot="$HOME/mail" 34 | set folder="$my_mailroot/$my_profile" 35 | 36 | # Notmuch. 37 | set nm_default_uri="notmuch://$my_mailroot" 38 | 39 | # Don't ever do email operations over cleartext. Note that ssl_force_tls *does* 40 | # also force STARTTLS, and will cause connection attempts to fail if it cannot 41 | # establish a STARTTLS (or any other STARTTLS) connection. The documentation 42 | # doesn't mention this, but I've verified that OPT_SSL_FORCE_TLS is implemented 43 | # this way (in NeoMutt at least). 44 | set ssl_force_tls 45 | set ssl_starttls 46 | 47 | # Disable bad crypto. Anything pre-TLSv1 is broken. 48 | ifdef ssl_use_sslv2 'set nossl_use_sslv2' # No longer included in 1.10.0. 49 | set nossl_use_sslv3 50 | 51 | # PGP-related options. 52 | set crypt_use_gpgme 53 | set crypt_verify_sig 54 | set crypt_autosign 55 | set postpone_encrypt 56 | set pgp_auto_decode 57 | set pgp_self_encrypt 58 | set nosmime_is_default 59 | 60 | # Show threads. 61 | set sort=threads 62 | # Sort by the *sent* date. 63 | set sort_aux=last-date 64 | 65 | # Don't wrap text, and don't put the "+" marker for lines wrapped due to 66 | # terminal width (which breaks long links). 67 | set wrap=0 68 | unset markers 69 | 70 | # Formatting of menus. 71 | set date_format=$my_date_format 72 | set compose_format=" [$my_profile] > Compose %> < %l < " 73 | set pager_format=" [$my_profile] > %.20n > %s %> [%Z] < %P %c < " 74 | set index_format="%Z %{$my_date_format} %-20.20n (%?l?%4l&%4c?) %s" 75 | set status_chars="-*%A" 76 | set status_format=" %r$my_profile%r > %f >%?u? %u(%n+%o)?%?d? -%d?%?p? ^%p?%?t? *%t? > %> < %s/%S < %P %?M?%M/?%m < " 77 | 78 | # Header formatting in mail viewer. 79 | ignore * 80 | unignore date from subject to cc bcc 81 | unignore message-id: x-mailing-list: 82 | 83 | # Make Message-ID sane (to make it nicer when dealing with LKML messages). 84 | # Ideally $hostname needs to be set by the actual muttrc we use. We need to do 85 | # "source" here so we get a different Message-ID each time. 86 | send-hook . "source $HOME/.mutt/muttrc-fix-msgid" 87 | 88 | # Display HTML messages (using lynx). 89 | set mailcap_path="$HOME/.mutt/mailcap" 90 | alternative_order text/plain text/html 91 | auto_view text/html 92 | 93 | # Include my default colour scheme. Accents (status and indicator) will be 94 | # overridden by the individual muttrc-$box configurations. 95 | source $HOME/.mutt/muttrc-colours 96 | -------------------------------------------------------------------------------- /.mutt/muttrc-colours: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # muttrc-colours -- This theme is based loosely on my custom 18 | # solarized-dark-like vim theme (which is effectively taking the key foreground 19 | # colour themes and making a sanely contrasted version). 20 | 21 | # Uncolour everything. 22 | uncolor index * 23 | 24 | # Basic colours . 25 | color normal white default 26 | color error color160 default 27 | color tilde color235 default 28 | color message color37 default 29 | color markers color160 color254 30 | color attachment color220 default 31 | color search color61 default 32 | color tree color136 default # arrow in threads 33 | 34 | # The status line is based on the "wombat" airline theme that I use. Because 35 | # mutt doesn't support modal colouring natively we do it through hooks. The 36 | # airline-wombat theme has the following colour sets: 37 | # XYZ is mode info status changed 38 | # normal is {232:192} {192:238} {192:235} {113} 39 | # insert is {232:227} {227:238} {227:235} {221} 40 | # visual is {232:153} {153:238} {153:235} {111} 41 | # replace is {232:173} {173:238} {173:235} {203} 42 | color status color15 color235 43 | color indicator brightcolor15 default 44 | set arrow_cursor 45 | 46 | # Monocolor screen. 47 | mono bold bold 48 | mono underline underline 49 | mono indicator reverse 50 | mono error bold 51 | 52 | # Index colours. 53 | color index color160 default "~A" # all messages 54 | color index color166 default "~=" # duplicate messages 55 | color index color242 default "~R" # read messages 56 | color index color245 default "~R~p!~F" # read messages 57 | color index brightcolor214 default "!~R" # unread messages 58 | color index brightcolor220 default "!~R~p!~F" # unread messages to me 59 | color index color26 default "~Q~R" # messages replied to 60 | color index brightcolor39 default "~Q!~R" # unread messages replied to 61 | color index brightcolor45 default "~Q!~R~p!~F" # unread messages replied to me 62 | color index color88 default "~D~R" # deleted 63 | color index color124 default "~D!~R" # deleted 64 | color index brightcolor124 default "~D!~R~p!~F" # deleted 65 | #color index color241 default "~P" # messages from me 66 | #color index brightcolor37 default "~p!~F" # messages to me 67 | #color index color240 default "~R~p!~F" # messages to me 68 | #color index color160 default "~F" # flagged messages 69 | #color index color160 default "~F~p" # flagged messages to me 70 | #color index color160 default "~N~F" # new flagged messages 71 | #color index color160 default "~N~F~p" # new flagged messages to me 72 | #color index color160 default "~U~F~p" # new flagged messages to me 73 | 74 | color index brightcolor160 default "~v" # messages part of a collapsed thread 75 | color index color248 default "~v!~(!~R)" # collapsed thread with no unread 76 | color index color249 default "~v!~(!~R)~(~p!~F)" # collapsed thread with no unread to me 77 | color index brightcolor166 default "~v~(!~R)" # collapsed thread with some unread 78 | color index brightcolor172 default "~v~(!~R~p!~F)" # collapsed thread with some unread to me 79 | color index brightcolor202 default "!~R~v~(!~R)" # collapsed thread with unread parent 80 | color index brightcolor208 default "!~R~v~(!~R~p!~F)" # collapsed thread with unread parent to me 81 | color index brightcolor208 default "~v~(!~R~p!~F)" # collapsed thread with flagged 82 | color index brightcolor208 default "~v~(!~R~p!~F)" # collapsed thread with flagged 83 | 84 | # Message header colours. 85 | color hdrdefault color136 default 86 | color header brightcolor136 default "^(From|To):" 87 | color header brightcolor166 default "^(Subject):" 88 | 89 | # Message body colours. 90 | color normal color254 default 91 | color bold brightcolor15 default 92 | color underline color15 default 93 | color signature color242 default 94 | color quoted color217 default 95 | color quoted1 color210 default 96 | color quoted2 color198 default 97 | color quoted3 color161 default 98 | color quoted4 color125 default 99 | color quoted5 color89 default 100 | 101 | # Make attachment headers nicer to read. 102 | color attach_headers brightyellow default "^\\[--" 103 | color attach_headers brightyellow default "--\\]$" 104 | color attach_headers brightcolor220 default "Type: [a-z]+/[a-z0-9\-]+" 105 | color attach_headers brightcolor220 default "Size: [0-9\.]+[KMG]?" 106 | 107 | # Add some colouring for GPG output. We must use attach_headers to ensure we 108 | # match only GPGME output (though I'm not sure if this will match non-signature 109 | # output). 110 | color attach_headers brightgreen default "(Begin|End) signature information" 111 | color attach_headers green default "(The following data is signed|End of signed data)" 112 | color attach_headers brightgreen default "Good signature from.*" 113 | color attach_headers brightred default "Bad signature from.*" 114 | color attach_headers brightred default "BAD signature from.*" 115 | color attach_headers brightred default "Note: This key has expired!" 116 | color attach_headers brightmagenta default "Problem signature from.*" 117 | color attach_headers brightmagenta default "WARNING: This key is not certified with a trusted signature!" 118 | color attach_headers brightmagenta default " There is no indication that the signature belongs to the owner." 119 | color attach_headers brightmagenta default "can't handle these multiple signatures" 120 | color attach_headers brightmagenta default "signature verification suppressed" 121 | color attach_headers brightmagenta default "invalid node with packet of type" 122 | 123 | # Colouring of URLs and email addresses. Yes, these regular expressions are 124 | # completely insane but they seem to handle most things. 125 | color body color160 default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])" 126 | color body color160 default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]" 127 | 128 | # Highlighting of common ASCII email "formatting" such as *bold*, _underline_, 129 | # and /italic/. 130 | # *bold* 131 | color body brightcolor15 default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)" 132 | mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)" 133 | # _underline_ 134 | color body color15 default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)" 135 | mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)" 136 | # /italic/ 137 | color body color15 default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)" 138 | mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)" 139 | -------------------------------------------------------------------------------- /.mutt/muttrc-fix-msgid: -------------------------------------------------------------------------------- 1 | # NOTE: This file is source'd through send-hook in order to make sure you get a 2 | # different Message-ID each time. 3 | 4 | # According to the upstream issue tracker (neomutt/neomutt#1262), this 5 | # shouldn't be necessary but the substitution of $hostname doesn't work 6 | # otherwise so.... 7 | setenv hostname $hostname 8 | #ifdef message_id_format set message_id_format="`$HOME/.local/bin/generate-msgid $hostname`" 9 | my_hdr Message-ID: <`$HOME/.local/bin/mail-generate-msgid $hostname`> 10 | unsetenv hostname 11 | -------------------------------------------------------------------------------- /.mutt/muttrc-personal: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # muttrc-personal -- configuration for with alias pmutt. 18 | 19 | set my_profile="personal" 20 | set pgp_default_key="C9C370B246B09F6DBCFC744C34401015D1D2D386" 21 | source $HOME/.mutt/muttrc 22 | 23 | set hostname="cyphar.com" 24 | set my_email="cyphar@$hostname" 25 | set from=$my_email 26 | set my_login=$my_email 27 | 28 | # I have quite a few aliases. These are all (mostly) public so I'll just keep 29 | # them in this config. 30 | alternates '^cyphar@cyphar\.com$' \ 31 | '^cyphar@mailbox\.org$' \ 32 | '^cyphar@opensuse\.org$' \ 33 | '^cyphar@protonmail\.com$' \ 34 | '^(aleksa|cyphar)@member\.fsf\.org$' \ 35 | '^asar0822@uni\.sydney\.edu\.au' 36 | 37 | # Change the major colour scheme to blue to differentiate it. 38 | color status color51 color235 39 | color indicator brightcolor51 default 40 | 41 | # Configuration for inbox. 42 | set folder="$my_mailroot/$my_profile" 43 | set smtp_url="smtps://$my_login@smtp.mailbox.org:465" 44 | set spoolfile="+inbox" 45 | set trash="+trash" 46 | # TODO: These are probably broken... 47 | set record="+sent" 48 | set postponed="+drafts" 49 | 50 | # I store my password information in KeePassXC (with a small wrapper so I can 51 | # support different versions, as well as fix up some of the issues with 52 | # KeePassXC's CLI interface). 53 | set smtp_pass="`keepassxc-helper "/Shared/Email/Mailbox"`" 54 | -------------------------------------------------------------------------------- /.mutt/muttrc-suse: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # muttrc-suse -- configuration for with alias smutt. 18 | 19 | set my_profile="suse" 20 | set pgp_default_key="5F36C6C61B5460124A75F5A69E18AA267DDB8DB4" 21 | source $HOME/.mutt/muttrc 22 | 23 | set hostname="suse.de" 24 | set my_email="asarai@$hostname" 25 | set from=$my_email 26 | set my_login="`keepassxc-helper -a UserName '/Shared/Email/SUSE'`" 27 | 28 | # I have quite a few aliases. These are all (mostly) public so I'll just keep 29 | # them in this config. 30 | alternates '^asarai@suse\.com$' 31 | 32 | # Change the major colour scheme to blue to differentiate it. 33 | color status color46 color235 34 | color indicator brightcolor46 default 35 | 36 | # Configuration for inbox. 37 | set folder="$my_mailroot/$my_profile" 38 | set smtp_url="smtp://$my_login@imap.suse.de:587" 39 | set spoolfile="+inbox" 40 | set trash="+Trash" 41 | # TODO: These are probably broken... 42 | set record="!/Sent" 43 | set postponed="!/Drafts" 44 | 45 | # I store my password information in KeePassXC (with a small wrapper so I can 46 | # support different versions, as well as fix up some of the issues with 47 | # KeePassXC's CLI interface). 48 | set smtp_pass="`keepassxc-helper '/Shared/Email/SUSE'`" 49 | -------------------------------------------------------------------------------- /.mutt/signature: -------------------------------------------------------------------------------- 1 | Aleksa Sarai 2 | Senior Software Engineer (Containers) 3 | SUSE Linux GmbH 4 | https://www.cyphar.com/ 5 | -------------------------------------------------------------------------------- /.notmuch-config: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | [database] 18 | path=/home/cyphar/mail 19 | 20 | [user] 21 | name=Aleksa Sarai 22 | primary_email=cyphar@cyphar.com 23 | 24 | [new] 25 | tags=unread;inbox; 26 | ignore= 27 | 28 | [search] 29 | exclude_tags=deleted;spam; 30 | 31 | [maildir] 32 | synchronize_flags=true 33 | -------------------------------------------------------------------------------- /.profile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # profile -- executed by any POSIX shell on login 19 | 20 | # run the .zshrc in the user's home directory 21 | if [ -n "${ZSH_VERSION}" ]; then 22 | if [ -f "${HOME}/.zshrc" ]; then 23 | . "${HOME}/.zshrc" 24 | fi 25 | fi 26 | 27 | # enable ibus support 28 | export GTK_IM_MODULE=ibus 29 | export XMODIFIERS=@im=ibus 30 | export QT_IM_MODULE=ibus 31 | -------------------------------------------------------------------------------- /.pythonrc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Wrap start-up in a function, to make cleanup easier. 19 | def __atstart__(): 20 | import readline 21 | import rlcompleter 22 | 23 | # Steal the default completer for later wrapping. 24 | default_completer = rlcompleter.Completer(locals()) 25 | 26 | # A custom tab-completer, which allows for tabs to be used as indentation. 27 | def my_completer(text, state): 28 | if text.strip() == "" and state == 0: 29 | return text + "\t" 30 | else: 31 | return default_completer.complete(text, state) 32 | 33 | # Bind the tab-completion to the completer, using the appropriate library. 34 | readline.set_completer(my_completer) 35 | if "libedit" in readline.__doc__: 36 | readline.parse_and_bind("bind ^I rl_complete") 37 | else: 38 | readline.parse_and_bind("tab: complete") 39 | 40 | # XXX: This is currently broken. 41 | # Run startup, and delete the reference to it, so as not to pollute the REPL. 42 | #__atstart__() 43 | #del __atstart__ 44 | -------------------------------------------------------------------------------- /.ssh/config: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Don't store raw hostnames in ~/.ssh/known_hosts. 18 | HashKnownHosts yes 19 | 20 | # Avoid CVE-2016-0777 and CVE-2016-0778. 21 | UseRoaming no 22 | 23 | # Disable agent forwarding to avoid obvious attacks. 24 | ForwardAgent no 25 | 26 | # Use decent crypto -- these come from 27 | # with some of my own 28 | # small modifications (removing old ciphers). 29 | HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256 30 | KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 31 | MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com 32 | Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr 33 | -------------------------------------------------------------------------------- /.tmux.conf: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | # Add more useful pane splitting. 18 | unbind-key % 19 | unbind-key '"' 20 | bind-key | split-window -h 21 | bind-key - split-window -v 22 | 23 | # Use C-x as the prefix. 24 | unbind-key C-b 25 | set -g prefix C-x 26 | bind-key C-x send-prefix 27 | 28 | # REMEMBER ALL THE THINGS! 29 | set -g history-limit 100000 30 | 31 | # Set the terminal to the "correct" one. 32 | set -g default-terminal "screen-256color" 33 | 34 | # For neovim, reduce the escape time (because of a misfeature called "alt-binding"). 35 | set -g escape-time 0 36 | 37 | # Set status bar. 38 | set -g status on 39 | set -g status-keys emacs 40 | set -g status-bg black 41 | set -g status-fg yellow 42 | set -g status-left '#[fg=colour13][#H]#[fg=yellow,bg=black] |' 43 | set -g status-right '| #[fg=colour13]#(date +"%0H:%0M:%0S %0d-%b-%Y") [#(uptime | cut -d"," -f1 | cut -d" " -f3-)]#[fg=yellow,bg=black]' 44 | 45 | # Colours for current window. 46 | set -g window-status-current-style bold,fg=yellow,bg=black 47 | 48 | # Get notifications about activity in non-focused windows. 49 | setw -g monitor-activity on 50 | 51 | # Only resize when a smaller client looks at the terminal. 52 | setw -g aggressive-resize on 53 | 54 | # Sane indexing. 55 | set -g base-index 1 56 | bind-key 0 select-window -t 10 57 | -------------------------------------------------------------------------------- /.wgetrc: -------------------------------------------------------------------------------- 1 | # dotfiles: collection of my personal dotfiles 2 | # Copyright (C) 2012-2023 Aleksa Sarai 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | robots = off 18 | user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36" 19 | -------------------------------------------------------------------------------- /.zsh/alias: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Enable alias option completion. 19 | setopt completealiases 20 | 21 | # Some weird distros don't symlink vi -> vim (-> nvim). This is wrong. Also add 22 | # an alias for "v" just for my own sanity. 23 | alias v="vi" 24 | alias vi="vim" 25 | alias vim="nvim" 26 | 27 | # ls colours. 28 | alias ls="ls --color=auto" 29 | 30 | # ls shortcuts. 31 | alias sl="ls" 32 | alias ll="ls -alF" 33 | alias la="ls -A" 34 | alias l="ls -CF" 35 | 36 | # grep colours. 37 | alias grep="grep --color=auto" 38 | alias fgrep="fgrep --color=auto" 39 | alias egrep="egrep --color=auto" 40 | 41 | # Make valgrind ... work. 42 | alias valgrind="valgrind --leak-check=full --trace-children=yes" 43 | alias vgs="valgrind --read-ver-info=yes" 44 | alias vg="valgrind" 45 | 46 | # Make cross-compiling go easier. 47 | function goc() { 48 | # Get arch as $1. 49 | local __arch="$1" 50 | shift 51 | 52 | GOARCH="${__arch}" go $@ 53 | } 54 | 55 | # Aliases for all archs. 56 | alias go64="goc amd64" 57 | alias go32="goc 386" 58 | alias goarm="goc arm" 59 | 60 | # Make setting proxies simpler. 61 | function prox() { 62 | local __user=$(read -p "username: "; echo ${REPLY}) 63 | local __pass=$(read -sp "password: "; echo ${REPLY}) 64 | 65 | # Deal with no newlines after `read -p`. 66 | echo 67 | 68 | local __serv=${1-$(read -p "server: "; echo ${REPLY})} 69 | local __prot=${2-$(read -p "protocol: "; echo ${REPLY})} 70 | 71 | # Create proxy url. 72 | local __prox="${__prot}://${__user}:${__pass}@${__serv}" 73 | 74 | export HTTP_PROXY="${__prox}" 75 | export HTTPS_PROXY="${__prox}" 76 | export SOCKS_PROXY="${__prox}" 77 | export FTP_PROXY="${__prox}" 78 | export ALL_PROXY="${__prox}" 79 | 80 | export http_proxy="${__prox}" 81 | export https_proxy="${__prox}" 82 | export socks_proxy="${__prox}" 83 | export ftp_proxy="${__prox}" 84 | export all_proxy="${__prox}" 85 | } 86 | 87 | # Make deactivating proxies simpler. 88 | function unprox() { 89 | unset HTTP_PROXY HTTPS_PROXY SOCKS_PROXY FTP_PROXY ALL_PROXY 90 | unset http_proxy https_proxy socks_proxy ftp_proxy all_proxy 91 | } 92 | 93 | # Mess around with pico and nano. 94 | alias pico="nano" 95 | function nano() { 96 | echo "Seriously? Why don't you just use notepad.exe, MS Paint or Edlin?" 97 | } 98 | 99 | # Add `time` to `make`, so that we get automagical build script timing 100 | # information, even if you forget to add `time`. 101 | alias make="time make" 102 | 103 | # For OBS. 104 | alias iosc="osc -A https://api.suse.de" 105 | alias eosc="osc -A https://api.opensuse.org" 106 | 107 | # Nice relative jumps. 108 | alias ..="cd .." 109 | alias ..2="cd ../.." 110 | alias ..3="cd ../../.." 111 | alias ..4="cd ../../../.." 112 | alias ..5="cd ../../../../.." 113 | 114 | # Make changing directories easy. 115 | setopt autocd 116 | 117 | # Mutt mailboxes. 118 | function _mutt_wrapper() { 119 | box="$1" && shift 120 | mkdir -p "$HOME/mail/$box" 121 | mbsync-helper -c "$HOME/.mbsyncrc-$box" || : 122 | neomutt -F "$HOME/.mutt/muttrc-$box" "$@" 123 | kill -9 "$(cat "$HOME/.mbsyncrc-$box.lock")" 124 | } 125 | alias pmutt="_mutt_wrapper personal" 126 | alias smutt="_mutt_wrapper suse" 127 | 128 | # Save me from my own stupidity. 129 | function rm() { 130 | # We need to do some very dumb argument parsing to figure out which 131 | # arguments are paths. The key thing is that we want to scan for any 132 | # arguments that don't start with "-" *or* any argument after the first 133 | # "--". 134 | local original_args=("$@") 135 | local file_args=() 136 | while (( $# > 0 )) 137 | do 138 | case "$1" in 139 | --) 140 | # We hit a "--". Every subseqent argument must be treated as a 141 | # file argument. 142 | shift 143 | file_args+=("$@") 144 | break 145 | ;; 146 | -*) 147 | # Skip this argument. 148 | ;; 149 | *) 150 | file_args+=("$1") 151 | ;; 152 | esac 153 | shift 154 | done 155 | 156 | # A sample of paths we obviously would never want to remove. $HOME is here 157 | # because I managed to nuke my $HOME by typing "rm -rf ~" without thinking. 158 | local BAD_PATHS=( 159 | "/" "/etc" "/boot" 160 | "/bin" "/usr/bin" "/sbin" "/usr/sbin" 161 | "/usr/lib" "/usr/lib64" 162 | "$HOME" 163 | ) 164 | 165 | local file 166 | for file in "${file_args[@]}" 167 | do 168 | file="$(readlink -f -- "$file")" 169 | if printf "%s\0" "${BAD_PATHS[@]}" | grep -Fxqz -- "$file"; then 170 | echo "rm: refusing to delete $file" >&2 171 | echo "rm: think before you type!!" >&2 172 | return 1 173 | fi 174 | done 175 | 176 | command rm "${original_args[@]}" 177 | } 178 | -------------------------------------------------------------------------------- /.zsh/banner: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Output banner. 19 | if (figlet -v &>/dev/null); then 20 | figlet "<< $(uname -s) >>" 21 | fi 22 | 23 | # Print out the kernel data and date. 24 | echo "$(uname -o) ($(uname -sr)) $(date)" 25 | -------------------------------------------------------------------------------- /.zsh/input: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Enable interactive comments. 19 | setopt interactivecomments 20 | 21 | # Make sure that the terminal is in application mode when zle is active, since 22 | # only then values from $terminfo are valid 23 | if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then 24 | function zle-line-init() { 25 | echoti smkx 26 | } 27 | 28 | function zle-line-finish() { 29 | echoti rmkx 30 | } 31 | 32 | zle -N zle-line-init 33 | zle -N zle-line-finish 34 | fi 35 | 36 | # [home] - start of line 37 | if [[ "${terminfo[khome]}" != "" ]]; then 38 | bindkey "${terminfo[khome]}" beginning-of-line 39 | fi 40 | 41 | # [end] - end of line 42 | if [[ "${terminfo[kend]}" != "" ]]; then 43 | bindkey "${terminfo[kend]}" end-of-line 44 | fi 45 | 46 | # [s-tab] - move through the completion menu backwards 47 | if [[ "${terminfo[kcbt]}" != "" ]]; then 48 | bindkey "${terminfo[kcbt]}" reverse-menu-complete 49 | fi 50 | 51 | # [backspace] - delete backward 52 | bindkey "^?" backward-delete-char 53 | 54 | # [delete] - delete forward 55 | if [[ "${terminfo[kdch1]}" != "" ]]; then 56 | bindkey "${terminfo[kdch1]}" delete-char 57 | else 58 | # Fallbacks. 59 | bindkey "^[[3~" delete-char 60 | bindkey "^[3;5~" delete-char 61 | bindkey "\e[3~" delete-char 62 | fi 63 | 64 | # typing + [up-arrow] - fuzzy find history forward 65 | if [[ "${terminfo[kcuu1]}" != "" ]]; then 66 | bindkey "${terminfo[kcuu1]}" up-line-or-search 67 | fi 68 | 69 | # typing + [down-arrow] - fuzzy find history backward 70 | if [[ "${terminfo[kcud1]}" != "" ]]; then 71 | bindkey "${terminfo[kcud1]}" down-line-or-search 72 | fi 73 | -------------------------------------------------------------------------------- /.zsh/prompt: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Enable prompt substitution and colours. 19 | autoload -U colors; colors 20 | setopt promptsubst 21 | 22 | # Emacs mode. 23 | bindkey -e 24 | 25 | # Set up prompt. 26 | function __generate_prompt() { 27 | # Save old exit code first. 28 | local exit_code="$?" 29 | 30 | # Locals. 31 | local user_prompt 32 | local path_prompt 33 | local ret_prompt 34 | 35 | # User information. 36 | if [[ "${EUID}" == "0" ]]; then 37 | user_prompt="%{$fg_bold[red]%}%M%{$reset_color%}" 38 | else 39 | user_prompt="%{$fg_bold[green]%}%n%{$reset_color%}%{$fg[green]%}@%M%{$reset_color%}" 40 | fi 41 | 42 | # Git branch and ref information. 43 | # Everything is calculated inside this shell script (no calls to `git` are 44 | # made). This is because on large projects (like, say, the kernel) git can 45 | # take >1 minute to figure out what branch and ref HEAD is pointing to. The 46 | # filesystem is faster. However, we have to fall back in *one* case, when 47 | # we are sitting on a packed ref or a repo which was recently gc'd -- in 48 | # that case `git` is faster and easier. 49 | function __git_info() { 50 | function __find_git() { 51 | local current="$1" 52 | 53 | while true; do 54 | gitdir="${current}/.git" 55 | if [[ -e "$gitdir" ]]; then 56 | gitdir_type="$(LC_ALL=C stat -c "%F" "$gitdir")" 57 | case "$gitdir_type" in 58 | directory) 59 | # If we have a .git directory, and it contains 60 | # .git/index, it's probably the right one. 61 | if [[ -f "$gitdir/index" ]]; then 62 | echo "$gitdir" 63 | return 0 64 | fi 65 | ;; 66 | "regular file") 67 | # If .git is a regular file, then we should be in a 68 | # worktree -- meaning it should contain a string like 69 | # 70 | # gitdir: some/dir/.git/worktrees/foobar 71 | # 72 | # This directory contains a HEAD file that matches what 73 | # we need for our prompt generation, so we can return 74 | # that. 75 | if ( grep "^gitdir: " "$gitdir" &>/dev/null ); then 76 | echo "$current/$(sed -E "s|gitdir: (.*)|\1|" <"$gitdir")" 77 | return 0 78 | fi 79 | ;; 80 | *) 81 | echo "WARNING: .git directory is unhandled type $gitdir_type" 82 | ;; 83 | esac 84 | fi 85 | [[ "${current}" != "/" ]] || break 86 | current="$(dirname -- "${current}")" 87 | done 88 | return 1 89 | } 90 | 91 | # Get the current branch ref from '.git/HEAD' and '.git/refs/heads'. 92 | function __get_branch() { 93 | local gitdir="$1" 94 | 95 | if (grep -v "^ref: refs/heads/.*$" -- "${gitdir}/HEAD" &>/dev/null); then 96 | # Detached state -- no branch name. 97 | return 1 98 | fi 99 | 100 | # Get the ref path. 101 | local refbranch="$(cut -d' ' -f2 -- "${gitdir}/HEAD")" 102 | 103 | # Yield the actual branch name from the refbranch. 104 | echo "${refbranch#refs/heads/}" 105 | return 0 106 | } 107 | 108 | # Get short commit hash. 109 | function __get_short_ref() { 110 | local gitdir="$1" 111 | local refhash 112 | 113 | # Detached state -- ref is in 'ref'. 114 | if ! (__get_branch "${gitdir}" &>/dev/null); then 115 | refhash="$(< "${gitdir}/HEAD")" 116 | else 117 | # Get the ref path. 118 | local refbranch="$(cut -d' ' -f2 -- "${gitdir}/HEAD")" 119 | 120 | # Check that the refbranch exists. 121 | if ! [[ -f "${gitdir}/${refbranch}" ]]; then 122 | # If not, we might be on a commit in a packed ref. 123 | # Fallback to `git` in this case -- we can't do better. 124 | refhash="$(git rev-parse --verify HEAD)" 125 | 126 | # We don't have a commit. 127 | if [[ "$?" != 0 ]]; then 128 | return 1 129 | fi 130 | else 131 | # Get the commit hash from the ref path. 132 | refhash="$(< "${gitdir}/${refbranch}")" 133 | fi 134 | fi 135 | 136 | # Shorten the ref to 12 characters. 137 | # Why 12? Because that's what the kernel tells us is good. 138 | # In Linus we trust. 139 | echo "$refhash[1,12]" 140 | return 0 141 | } 142 | 143 | # Most shells (zsh included) like to be clever with symlinks. This breaks 144 | # things like symlinks into subdirectories of git repositories (because 145 | # `pwd` lies to you). Fix this by using the `pwd` command which isn't 146 | # magical. 147 | local real_pwd="$(command pwd)" 148 | 149 | if (__find_git "${real_pwd}" &>/dev/null); then 150 | # Get the closest git directory. 151 | local gitdir="$(__find_git "${real_pwd}")" 152 | 153 | # Figure out if in detached state. 154 | local refinfo 155 | if (__get_branch "${gitdir}" &>/dev/null); then 156 | refinfo="%{$fg_bold[magenta]%}$(__get_branch "${gitdir}")%{$reset_color%}" 157 | else 158 | refinfo="%{$fg_bold[red]%}{detached}%{$reset_color%}" 159 | fi 160 | 161 | # Figure out short ref. 162 | local refhash 163 | if (__get_short_ref "${gitdir}" &>/dev/null); then 164 | refhash="%{$fg[magenta]%}$(__get_short_ref "${gitdir}")%{$reset_color%}" 165 | else 166 | refhash="%{$fg[red]%}000000000000%{$reset_color%}" 167 | fi 168 | 169 | echo " git:(${refinfo}:${refhash})" 170 | fi 171 | } 172 | 173 | # Mercurial branch information. 174 | function __hg_info() { 175 | # Hot path: check that there isn't a parent .hg/ directory. 176 | # We don't implement parsing (I don't clone big hg project often enough 177 | # to care). 178 | function __find_hg() { 179 | local current="$1" 180 | 181 | # Search up the directory tree for '.git'. 182 | while [[ "${current}" != "/" ]]; do 183 | if [[ -d "${current}/.hg" ]]; then 184 | echo "${current}/.hg" 185 | return 0 186 | fi 187 | 188 | current="$(dirname -- "${current}")" 189 | done 190 | 191 | # Check for '/.hg'. 192 | if [[ -d "${current}/.hg" ]]; then 193 | echo "${current}/.hg" 194 | return 0 195 | fi 196 | 197 | return 1 198 | } 199 | 200 | # Most shells (zsh included) like to be clever with symlinks. This breaks 201 | # things like symlinks into subdirectories of git repositories (because 202 | # `pwd` lies to you). Fix this by using the `pwd` command which isn't 203 | # magical. 204 | local real_pwd="$(command pwd)" 205 | 206 | if (__find_hg "${real_pwd}" &>/dev/null && hg status &>/dev/null); then 207 | # TODO: Switch to reading ~/.hg directly to avoid Python overhead. 208 | local refbranch="$(hg branch)" 209 | local refhash="$(hg id | cut -d' ' -f1)" 210 | 211 | echo " hg:(%{$fg_bold[magenta]%}${refbranch}%{$reset_color%}:%{$fg[magenta]%}${refhash}%{$reset_color%})" 212 | fi 213 | } 214 | 215 | # Get the last part of the given path, with tilde replacement. 216 | function __nice_path() { 217 | local current_path="$1" 218 | 219 | if [[ "${current_path}" == "${HOME}" ]]; then 220 | current_path="~" 221 | else 222 | current_path="$(basename "${current_path}")" 223 | fi 224 | 225 | echo "${current_path}" 226 | } 227 | 228 | # Path information. 229 | path_prompt="%{$fg_bold[blue]%}$(__nice_path "$(pwd)")%{$reset_color%}$(__git_info)$(__hg_info)" 230 | 231 | # Return prompt based on exit code of last command. 232 | function __ret_prompt() { 233 | local exit_code="$1" 234 | local prompt="%#" 235 | 236 | if [[ "${exit_code}" != "0" ]]; then 237 | prompt="%{$fg_bold[red]%}${prompt}%{$reset_color%}" 238 | fi 239 | 240 | echo "${prompt} " 241 | } 242 | ret_prompt="$(__ret_prompt "${exit_code}")" 243 | 244 | # Get loadavg for last minute. 245 | function __loadavg() { 246 | [[ -f "/proc/loadavg" ]] && echo "$(cat /proc/loadavg 2>/dev/null | cut -d' ' -f1)" 247 | } 248 | 249 | # Get number of processes, if we can. 250 | function __nproc() { 251 | echo "$(nproc 2>/dev/null || echo '?')" 252 | } 253 | 254 | # Actually set up prompts. 255 | export PROMPT="$user_prompt %{$fg[cyan]%}::%{$reset_color%} $path_prompt $ret_prompt" 256 | export RPROMPT="[$(uname -o) $(__loadavg)($(__nproc))]" 257 | 258 | # Set up secondary prompts. 259 | export PROMPT2="%_> " 260 | export PROMPT3="?#> " 261 | export PROMPT4="+> " 262 | } 263 | 264 | # Set up precmd hook to set up prompt. 265 | function precmd() { 266 | __generate_prompt 267 | } 268 | -------------------------------------------------------------------------------- /.zshenv: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Enable ibus support. 19 | export GTK_IM_MODULE=ibus 20 | export XMODIFIERS=@im=ibus 21 | export QT_IM_MODULE=ibus 22 | 23 | # Source rust-up cargo stuff. 24 | . "$HOME/.cargo/env" 25 | -------------------------------------------------------------------------------- /.zshrc: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | # Only set up if running interactively. 19 | [[ -t 0 ]] || exit 0 20 | 21 | if (tmux -V &>/dev/null); then 22 | # If the current shell is not running in tmux, start/attach to a tmux session. 23 | if (( $+TMUX == 0 )); then 24 | # The default name for the tmux session is `cyphar/zsh`. 25 | local __tmux_session="${TMUX_SESSION:-cyphar/zsh}" 26 | 27 | # Start the server in case it doesn't exist. 28 | tmux start-server 29 | 30 | # Create the session if it doesn't exist. 31 | if ! (tmux has-session -t "${__tmux_session}" &>/dev/null); then 32 | tmux new-session -t "${__tmux_session}" -d -c "$HOME" 33 | fi 34 | 35 | # Switch to tmux session. 36 | # You can set $TMUX to any value to stop this from happening. 37 | exec tmux attach-session -t "${__tmux_session}" 38 | fi 39 | fi 40 | 41 | # Load completion. 42 | autoload -U compinit 43 | compinit 44 | 45 | # Load all scripts in ~/.zsh. 46 | if [[ -d "${HOME}/.zsh" ]]; then 47 | for file in $(find "${HOME}/.zsh" -type f); do 48 | source "${file}" 49 | done 50 | fi 51 | 52 | # Export the standard stuff. 53 | export PATH="${PATH}:${HOME}/.local/bin" 54 | export EDITOR="nvim" 55 | export PAGER="less" 56 | export TERMINAL="alacritty" 57 | 58 | # Make go ... work. This is inspired by how runc0m handles things. 59 | export GOPATH="${HOME}/.local" 60 | export CDPATH=".:${GOPATH}/src" 61 | 62 | # Make python load `.pythonrc.py` 63 | export PYTHONSTARTUP="${HOME}/.pythonrc.py" 64 | 65 | # Made TERM work nicer. 66 | # This is also changed by .tmux.conf, but we might as well ensure it's correct here. 67 | export TERM="screen-256color" 68 | 69 | # Make the history usable. 70 | setopt histignoredups no_sharehistory 71 | 72 | # Set up keychain. 73 | if (keychain --version 2>/dev/null); then 74 | eval $(keychain --eval --agents ssh -Q --quiet --nogui "${HOME}/.ssh/id_ed25519") 75 | fi 76 | 77 | # Make sure "git commit" will actually show you pinentry... 78 | export GPG_TTY="$(tty)" 79 | 80 | # Use cargo environment if applicable. 81 | [ -e "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotfiles # 2 | These are my personal configuration files. Feel free to use them yourself if you 3 | wish. 4 | 5 | ## Download ## 6 | When cloning this repo, ensure that you clone it recursively (to ensure that 7 | submodules are also cloned): 8 | 9 | ``` 10 | $ git clone --recursive https://github.com/cyphar/dotfiles.git 11 | ``` 12 | 13 | ## Install ## 14 | Run the `install.py` script in the root of this project to install the 15 | configurations. It interactively asks you whether you'd like to install each 16 | configuration "set" (enter no input to use the default). 17 | 18 | `install.py` also has OS-specific hooks to preconfigure supported GNU/Linux 19 | distributions (by installing necessary packages, and other system 20 | configuration). At the moment, this is only supported on openSUSE Tumbleweed. 21 | If you'd like to figure out what packages are required please take a look at 22 | `dist/opensuse/50-packages.sh`. 23 | 24 | ## License ## 25 | 26 | Apart from files where specifically specified (e.g vim plugins), all files are 27 | licensed under the GNU GPLv3 or later. 28 | 29 | ``` 30 | dotfiles: collection of my personal dotfiles 31 | Copyright (C) 2012-2023 Aleksa Sarai 32 | 33 | This program is free software: you can redistribute it and/or modify 34 | it under the terms of the GNU General Public License as published by 35 | the Free Software Foundation, either version 3 of the License, or 36 | (at your option) any later version. 37 | 38 | This program is distributed in the hope that it will be useful, 39 | but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 41 | GNU General Public License for more details. 42 | 43 | You should have received a copy of the GNU General Public License 44 | along with this program. If not, see . 45 | ``` 46 | -------------------------------------------------------------------------------- /dist/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | # Everything is rooted at dist/. 21 | DIST_ROOT="$(readlink -f "$(dirname "$BASH_SOURCE")")" 22 | 23 | # Helper functions to make the messages a bit prettier. 24 | function info() { 25 | echo "[*]" "$@" >&2 26 | } 27 | function bail() { 28 | echo "[!]" "$@" >&2 29 | exit 1 30 | } 31 | 32 | # Get the current OS information. 33 | source /etc/os-release 34 | 35 | # Check that we support the distribution. 36 | [ -d "$DIST_ROOT/$ID" ] || bail "Unsupported distribution: $ID." 37 | 38 | # Export the information from os-release. 39 | export OS_NAME="$NAME" OS_ID="$ID" OS_ID_LIKE="$ID_LIKE" \ 40 | OS_VERSION_ID="$VERSION_ID" OS_PRETTY_NAME="$PRETTY_NAME" 41 | 42 | # Run all of the respective hooks. 43 | info "Installing for distribution $OS_ID ($OS_NAME)." 44 | for script in "$DIST_ROOT/$ID/"*.sh 45 | do 46 | info "Running $(basename "$script")." 47 | source "$script" 48 | done 49 | -------------------------------------------------------------------------------- /dist/opensuse-tumbleweed: -------------------------------------------------------------------------------- 1 | opensuse -------------------------------------------------------------------------------- /dist/opensuse/00-osrelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | # TODO: Support more than just tumbleweed. 21 | OPENSUSE_DISTRO="openSUSE_Tumbleweed" 22 | [[ "$OS_NAME" == "openSUSE Tumbleweed" ]] || bail "unsupported opensuse distro: $OS_NAME" 23 | -------------------------------------------------------------------------------- /dist/opensuse/50-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | # Remove the proprietary repos (if they're enabled). 21 | echo ">> zypper removerepo [proprietary]" 22 | sudo zypper removerepo repo-non-oss || true 23 | 24 | # Upgrade the priority of the built-in repos. 25 | echo ">> zypper modifyrepo [upgrade builtin priority]" 26 | sudo zypper mr -p 98 repo-debug repo-oss repo-source repo-update 27 | 28 | # Set of repos needed for a base system. 29 | echo ">> zypper addrepo [repos]" 30 | zypper repos packman-essentials &>/dev/null || sudo zypper addrepo -fp 97 "https://ftp.gwdg.de/pub/linux/misc/packman/suse/$OPENSUSE_DISTRO/Essentials" packman-essentials 31 | zypper repos obs-fs &>/dev/null || sudo zypper addrepo -f "obs://filesystems" obs-fs 32 | zypper repos obs-hardware &>/dev/null || sudo zypper addrepo -f "obs://hardware" obs-hardware 33 | zypper repos obs-vc &>/dev/null || sudo zypper addrepo -fp 97 "obs://Virtualization:containers" obs-vc 34 | sudo zypper --gpg-auto-import-keys ref 35 | 36 | # Set of packages we need for a base system. 37 | # TODO: Make it possible to specify whether it's a workstation or server. 38 | 39 | echo ">> zypper install [packages]" 40 | packages=( 41 | # Basic cli tools necessary. 42 | "neovim" "tmux" "zsh" "git" "gcc" "go" "keychain" "figlet" "gpg2" "python3" 43 | "mosh" "rsync" "ranger" "alsa-utils" "weechat" "make" "exfat-utils" 44 | "fuse-exfat" "xfsprogs" "autoconf" "automake" "libtool" "bpftrace" 45 | "moreutils" "qpdf" "python3" 46 | # Container-related packages. 47 | "skopeo" "umoci" "runc" "docker" "lxc" "lxd" 48 | # Basic graphics stack and environment. 49 | "i3" "i3lock" "i3status" "dmenu" "feh" "ImageMagick" "xorg-x11-server" 50 | "xf86-video-intel" "xf86-input-keyboard" "xf86-input-mouse" "picom" 51 | "xf86-input-libinput" "lightdm" "lightdm-gtk-greeter" "cozette-fonts" 52 | "xbacklight" "xclip" "scrot" 53 | # Graphical programs. 54 | "keepassxc" "firefox" "vlc" "mpv" "alacritty" "redshift" "libreoffice" 55 | "zathura" "evince" "element-desktop" 56 | # To make my phone work... 57 | "android-tools" 58 | # Networking. 59 | "wireguard-tools" "net-tools-deprecated" "NetworkManager-applet" 60 | # Good-to-haves. 61 | "torbrowser-launcher" "tor" "sshfs" 62 | # Mutt and related packages. 63 | "neomutt" "zenity" "isync" "secret-tool" "notmuch" "cyrus-sasl-plain" 64 | "lynx" 65 | # openSUSE 66 | "osc" 67 | # Japanese input and packages. 68 | "qolibri" ibus{,-gtk{,3},-mozc{,-candidate-window}} 69 | ) 70 | sudo zypper install "${packages[@]}" 71 | 72 | # Install rust with rustup. I don't like "curl | sh" either, and they don't 73 | # seem to have any signature verification either. Hopefully they fix this soon 74 | # . 75 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 76 | "$HOME/.cargo/bin/rustup" toolchain install nightly 77 | 78 | # Install diceware, patatt and b4 for kernel development. 79 | sudo python3 -m ensurepip 80 | sudo pip3 install diceware patatt b4 81 | -------------------------------------------------------------------------------- /dist/opensuse/51-user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | # Set our shell to be zsh. 21 | sudo usermod -s/bin/zsh "$USER" 22 | 23 | # Set up our ~/.local/src gopath. 24 | if [[ -e "$HOME/.local/src" && ! -L "$HOME/.local/src" ]] 25 | then 26 | echo "Skipping ~/.local/src setup (already exists)." 27 | else 28 | ln -sfT "../src" "$HOME/.local/src" 29 | fi 30 | 31 | # Add ourselves to the docker group, if it exists (we no longer install Docker 32 | # by default). 33 | sudo usermod -a -G docker "$USER" || : 34 | -------------------------------------------------------------------------------- /dist/opensuse/52-graphics.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | # Enable graphics. 21 | sudo systemctl enable display-manager 22 | sudo systemctl set-default graphical 23 | 24 | # Set lightdm as the default displaymanager. 25 | sudo sed -i 's|^DISPLAYMANAGER=.*|DISPLAYMANAGER="lightdm"|g' /etc/sysconfig/displaymanager 26 | 27 | # Set up our wallpaper. By default we swap from the openSUSE one, but to avoid 28 | # copyright problems I don't include any given wallpaper here. 29 | sudo mkdir -p /usr/share/wallpapers 30 | sudo sed -i 's|^#?background=.*|background=/usr/share/wallpapers/default.jpg|g' /etc/lightdm/lightdm-gtk-greeter.conf 31 | -------------------------------------------------------------------------------- /dist/opensuse/53-wireguard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | echo ">> set up wireguard" 21 | echo "wireguard" | sudo tee /etc/modules-load.d/99-wireguard.conf >/dev/null 22 | -------------------------------------------------------------------------------- /dist/opensuse/54-timedate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | echo ">> configure timezone and ntpd" 21 | sudo timedatectl set-timezone 'Australia/Sydney' 22 | sudo timedatectl set-local-rtc false 23 | sudo timedatectl set-ntp true 24 | -------------------------------------------------------------------------------- /dist/opensuse/55-autorandr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | echo ">> pip install autorandr" 21 | pip install autorandr 22 | 23 | echo ">> install autorandr udev wrapper script" 24 | cat >/usr/local/sbin/autorandr-udev.sh < 27 | # License: GPL-3.0-or-later 28 | 29 | set -Eeuo pipefail 30 | 31 | # Get the current user. 32 | logger -t autorandr-udev "username=." 33 | username="\$(w -hs | awk '\$3 != "-" { print \$1; exit; }')" 34 | display="\$(w -hs | awk -v username="\$username" '\$3 != "-" && \$1 == username { print \$3; exit; }')" 35 | if [ -z "\$display" ]; then 36 | logger -t autorandr-udev "Nobody seems to be logged in." 37 | return 1 38 | fi 39 | 40 | output="\$(sudo -u "\$username" DISPLAY="\$display" autorandr -c 2>&1)" 41 | if [ "\$?" -ne 0 ] 42 | then 43 | logger -t autorandr-udev "autorandr: \$output" 44 | return 1 45 | fi 46 | EOF 47 | chmod +x /usr/local/sbin/autorandr-udev.sh 48 | 49 | echo ">> configure udev-rules for autorandr" 50 | cat >/etc/udev/rules.d/95-autorandr.rules < 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | echo ">> disable dynamic netconfig-based dns (always use 1.1.1.1)" 21 | 22 | # Disable auto-configuring DNS with netconfig and always use CloudFlare DNS 23 | # plus the home DNS setup for dot.cyphar.com. 24 | sudo sed -i 's|^NETCONFIG_DNS_POLICY=.*|NETCONFIG_DNS_POLICY="STATIC_FALLBACK"|g' /etc/sysconfig/network/config 25 | sudo sed -i 's|^NETCONFIG_DNS_STATIC_SEARCHLIST=.*|NETCONFIG_DNS_STATIC_SEARCHLIST="dot.cyphar.com"|g' /etc/sysconfig/network/config 26 | sudo sed -i 's|^NETCONFIG_DNS_STATIC_SERVERS=.*|NETCONFIG_DNS_STATIC_SERVERS="1.1.1.1 1.0.0.1 10.42.0.1"|g' /etc/sysconfig/network/config 27 | 28 | sudo netconfig update -f 29 | -------------------------------------------------------------------------------- /dist/opensuse/57-fonts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | TMP_FONTDIR="$(mktemp -dt "cyphar-dotfiles-fonts.XXXXXXXX")" 21 | trap "rm -rf '$TMP_FONTDIR'" EXIT 22 | 23 | # Install Cozette. 24 | # TODO: Switch to using the latest version rather than a hard-coded one. 25 | FONT_URL="https://github.com/slavfox/Cozette/releases/download/v.1.23.2/CozetteFonts-v-1-23-2.zip" 26 | curl -L "$FONT_URL" -o "$TMP_FONTDIR/CozetteFonts.zip" 27 | ( 28 | cd "$TMP_FONTDIR" 29 | unzip CozetteFonts.zip 30 | install -m0644 -t "$HOME/.local/share/fonts" CozetteFonts/*.{ttf,otf,otb} 31 | ) 32 | fc-cache -fv 33 | 34 | # CJK fonts. 35 | fonts=( 36 | mplus-fonts 37 | monapo-fonts 38 | noto-sans-gothic-fonts 39 | noto-sans-{jp,tc,sc,kr}-fonts-full 40 | ipa-{{ex-,p}{gothic,mincho},uigothic,{,p}gothic-{bold,italic,bolditalic}}-fonts 41 | adobe-sourcehan{serif,sans}-{cn,jp,kr,tw}-fonts 42 | ) 43 | sudo zypper install -y "${fonts[@]}" 44 | -------------------------------------------------------------------------------- /dist/opensuse/60-sshkey.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | # Generate a new ed25519 key if one isn't already available. 21 | [[ -f "$HOME/.ssh/id_ed25519" ]] || ssh-keygen -t ed25519 22 | -------------------------------------------------------------------------------- /hooks/after/fonts: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | echo "[*] Rebuilding font cache." 19 | fc-cache -vf 20 | -------------------------------------------------------------------------------- /hooks/after/mpv: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | set -Eeuo pipefail 19 | 20 | echo "[*] Updating mpvacious." 21 | mkdir -p "$HOME/.config/mpv/scripts/" 22 | pushd "$HOME/.config/mpv/scripts/" 23 | MPVACIOUS_VERSION="$(curl -sSL https://api.github.com/repos/Ajatt-Tools/mpvacious/releases/latest | jq -rM .tag_name )" 24 | echo "[-] Installing mpvacious $MPVACIOUS_VERSION" 25 | [[ -d "mpvacious" ]] || git clone https://github.com/Ajatt-Tools/mpvacious.git 26 | pushd "mpvacious" 27 | git fetch origin 28 | git reset --hard HEAD 29 | git checkout "$MPVACIOUS_VERSION" 30 | popd 31 | 32 | echo "[*] Updating youtube-dl (yt-dlp)." 33 | if ! ( command yt-dlp --version &>/dev/null ); then 34 | YTDL_VERSION="$(curl -sSL https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest | jq -rM .tag_name )" 35 | echo "[-] Installing yt-dlp $YTDL_VERSION." 36 | pushd "$HOME/.local/bin" 37 | curl -SLo yt-dlp "https://github.com/yt-dlp/yt-dlp/releases/download/$YTDL_VERSION/yt-dlp" 38 | chmod +x yt-dlp 39 | popd 40 | else 41 | yt-dlp -U 42 | fi 43 | -------------------------------------------------------------------------------- /install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # dotfiles: collection of my personal dotfiles 3 | # Copyright (C) 2012-2023 Aleksa Sarai 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import os 19 | import sys 20 | import stat 21 | import shutil 22 | import argparse 23 | import subprocess 24 | 25 | # Default "yes" and "no" shortcuts. 26 | YES = "yes" 27 | NO = "no" 28 | 29 | # Lambdas for checking input. 30 | is_yes = lambda s: s.lower() in {YES, "y", "yes", "true"} 31 | is_no = lambda s: s.lower() in {NO, "n", "no", "false"} 32 | 33 | # Hook constants. 34 | HOOK_BEFORE = "before" 35 | HOOK_AFTER = "after" 36 | 37 | # Install targets. 38 | OPTIONS = { 39 | "alacritty": (YES, [".config/alacritty/"]), 40 | "bin": (YES, [".local/bin/"]), 41 | "dunst": (YES, [".config/dunst/"]), 42 | "fonts": (YES, [".config/fontconfig/"]), 43 | "git": (YES, [".gitconfig", ".config/git"]), 44 | "i3": (YES, [".config/i3/", ".config/i3status/"]), 45 | "keepassxc": (YES, [".config/keepassxc/"]), 46 | "mbsync": (YES, [".mbsyncrc-personal", ".mbsyncrc-suse"]), 47 | "mpv": (YES, [".config/mpv/"]), 48 | "mutt": (YES, [".mutt/"]), 49 | "neovim": (YES, [".config/nvim/"]), 50 | "notmuch": (YES, [".notmuch-config"]), 51 | "python": (YES, [".pythonrc.py"]), 52 | "redshift": (YES, [".config/redshift.conf"]), 53 | "ssh": (YES, [".ssh/config"]), 54 | "tmux": (YES, [".tmux.conf"]), 55 | "wget": (YES, [".wgetrc"]), 56 | "zsh": (YES, [".profile", ".zsh/", ".zshrc"]), 57 | } 58 | 59 | # Stdio helpers. 60 | 61 | def warn_user(*args, **kwargs): 62 | print("[!]", *args, **kwargs) 63 | 64 | def info_user(*args, **kwargs): 65 | print("[*]", *args, **kwargs) 66 | 67 | def ask_user(prompt, **kwargs): 68 | return input("[?] %s " % (prompt,), **kwargs) or "" 69 | 70 | 71 | # File helpers. 72 | 73 | def path_exists(path): 74 | try: 75 | os.stat(path) 76 | except FileNotFoundError: 77 | return False 78 | return True 79 | 80 | def path_sanitise(path): 81 | path = os.path.join(path, "") 82 | path = os.path.dirname(path) 83 | return path 84 | 85 | # Returns the last path component. 86 | def safe_basename(path): 87 | path = path_sanitise(path) 88 | path = os.path.basename(path) 89 | return path 90 | 91 | # Returns the path minus the last component. 92 | def safe_dirname(path): 93 | path = path_sanitise(path) 94 | path = os.path.dirname(path) 95 | return path 96 | 97 | # Makes the set of directories, ignoring permission issues. 98 | def makedirs(path, *args, **kwargs): 99 | if not path_exists(path): 100 | os.makedirs(path, *args, **kwargs) 101 | 102 | def path_copy(source, target, clobber=True): 103 | """ 104 | Copies source (regardless of inode type) to target. 105 | Where target is the directory the source will be copied to. 106 | source is the path of the thing to be copied. 107 | """ 108 | 109 | # Stat the source. 110 | st_src = os.stat(source) 111 | 112 | # Generate target path. 113 | basename = safe_basename(source) 114 | target_path = os.path.join(target, basename) 115 | 116 | # Check if we are about to clobber the destination. 117 | if path_exists(target_path) and not clobber: 118 | warn_user("Target path '%s' already exists! Skipping." % (target_path,)) 119 | 120 | # Directories are a magic case. 121 | if stat.S_ISDIR(st_src.st_mode): 122 | # Make an empty slot for the children. 123 | if not path_exists(target_path): 124 | os.mkdir(target_path) 125 | 126 | # Recursively copy all of the files. 127 | for child in os.listdir(source): 128 | child = os.path.join(source, child) 129 | path_copy(child, target_path) 130 | 131 | # Regular files (and symlinks). 132 | else: 133 | fsrc = open(source, "rb") 134 | fdst = open(target_path, "wb") 135 | 136 | shutil.copyfileobj(fsrc, fdst) 137 | shutil.copymode(source, target_path) 138 | 139 | 140 | # Main install script and helpers. 141 | 142 | def response_bool(response, default=True): 143 | if is_yes(response): 144 | return True 145 | elif is_no(response): 146 | return False 147 | elif not response: 148 | return default 149 | 150 | def run_script(script): 151 | # Ignore non-existant scripts. 152 | if not path_exists(script): 153 | return 0 154 | return subprocess.call([script]) 155 | 156 | def run_hook(config, ctx, hook): 157 | script = os.path.join(config.hook_dir, ctx, hook) 158 | ret = run_script(script) 159 | if ret != 0: 160 | warn_user("%s hook for '%s' returned with non-zero error code: %d" % (ctx.title(), hook, ret)) 161 | return ret 162 | 163 | def do_install(config, target, files): 164 | if run_hook(config, HOOK_BEFORE, target): 165 | return 1 166 | 167 | for _file in files: 168 | # Deal with leading directories in path. 169 | prefix = os.path.join(config.prefix, safe_dirname(_file)) 170 | makedirs(prefix, exist_ok=True) 171 | 172 | # Copy the file to its new prefix. 173 | path_copy(_file, prefix, clobber=config.clobber) 174 | 175 | return run_hook(config, HOOK_AFTER, target) 176 | 177 | def main(config): 178 | if config.list_groups: 179 | for group in OPTIONS: 180 | print(group) 181 | return 0 182 | 183 | chosen = config.groups 184 | if not chosen: 185 | # Ask user which targets they'd like. 186 | for option, value in OPTIONS.items(): 187 | # Unpack option. 188 | default, files = value 189 | 190 | # Ask if they wish to install the program. 191 | install = None 192 | while install is None: 193 | response = ask_user("Do you wish to install '%s' [%s]?" % (option, default)) 194 | install = response_bool(response, default=response_bool(default)) 195 | 196 | # Add to the chosen list if it works. 197 | if install: 198 | chosen.append(option) 199 | 200 | # Nothing chosen to be installed. 201 | if not chosen: 202 | return 0 203 | 204 | # Make sure that the prefix path is real. 205 | makedirs(config.prefix, exist_ok=True) 206 | 207 | # We want to return a non-zero error code in case of any error, but still 208 | # blindly blunder on installing orthogonal components. 209 | retval = 0 210 | 211 | # Actually install the buggers. 212 | for choice in chosen: 213 | # Print information to the user. 214 | info_user("Installing '%s'." % (choice,)) 215 | 216 | # Install the files. 217 | _, files = OPTIONS[choice] 218 | retval |= do_install(config, choice, files) 219 | 220 | if config.fragile and retval: 221 | warn_user("Cowardly refusing to continue installation, because '%s' failed." % (choice,)) 222 | return retval 223 | 224 | # Run setup scripts for the distribution. 225 | install_dist = None 226 | while install_dist is None: 227 | default = NO 228 | response = ask_user("Do you wish to run distribution-specific scripts [%s]?" % (default,)) 229 | install_dist = response_bool(response, default=response_bool(default)) 230 | if install_dist: 231 | info_user("Executing distribution scripts.") 232 | retval |= run_script("dist/install.sh") 233 | 234 | # All done! 235 | return retval 236 | 237 | if __name__ == "__main__": 238 | def __atstart__(): 239 | # Set up argument parser. 240 | parser = argparse.ArgumentParser() 241 | parser.add_argument("--prefix", dest="prefix", type=str, default=os.path.expanduser("~")) 242 | parser.add_argument("--hook-dir", dest="hook_dir", type=str, default="hooks") 243 | # Boolean setting for clobber. 244 | parser.add_argument("-nc", "--no-clobber", dest="clobber", action="store_const", const=False, default=True) 245 | parser.add_argument("-c", "--clobber", dest="clobber", action="store_const", const=True, default=True) 246 | # Boolean setting for fragile. 247 | parser.add_argument("-nf", "--no-fragile", dest="fragile", action="store_const", const=False, default=False) 248 | parser.add_argument("-f", "--fragile", dest="fragile", action="store_const", const=True, default=False) 249 | # Control which groups to install? 250 | parser.add_argument("--list-groups", dest="list_groups", action="store_const", const=True, default=False) 251 | parser.add_argument("groups", nargs='*', default=[], help="The set of groups to install.") 252 | 253 | # Get arguments. 254 | args = parser.parse_args() 255 | # Fix up options. 256 | args.prefix = os.path.expanduser(args.prefix) 257 | 258 | # Run main program. 259 | sys.exit(main(args)) 260 | __atstart__() 261 | --------------------------------------------------------------------------------