├── .gitignore ├── dot_zshenv ├── .chezmoiignore ├── dot_local ├── share │ ├── private_gnupg │ │ ├── private_dirmngr.conf │ │ └── private_executable_gpg-agent.conf.tmpl │ └── private_applications │ │ └── syncthing-ui.desktop └── bin │ └── scripts │ ├── git │ ├── executable_git-modified │ ├── executable_git-alias │ ├── executable_git-browse │ ├── executable_git-ignore │ ├── executable_git-sync │ └── executable_git-summary │ ├── executable_restore-tmux │ ├── cron │ ├── executable_checkup │ ├── executable_syncemail.tmpl │ └── checkup.md │ ├── executable_nvims │ ├── executable_scrkey │ ├── executable_tmux-sessionizer │ ├── executable_bakdir │ ├── executable_scrot │ ├── encrypted_executable_emailnotification.age │ ├── executable_ffmpeg.sh │ └── executable_irg ├── private_dot_config ├── wget │ └── wgetrc.tmpl ├── zsh │ ├── symlink_dot_zshenv.tmpl │ ├── functions │ ├── plugins │ │ ├── colored-man-pages.zsh │ │ └── menu.zsh │ ├── dot_zshrc │ └── prompt.zsh ├── nvim │ ├── after │ │ └── ftplugin │ │ │ ├── css.lua │ │ │ ├── markdown.lua │ │ │ ├── gitcommit.lua │ │ │ └── qf.lua │ ├── debug.lua │ ├── lua │ │ └── configs │ │ │ ├── treesitter.lua │ │ │ ├── format.lua │ │ │ ├── oil.lua │ │ │ ├── statusline.lua │ │ │ ├── leap.lua │ │ │ └── mini.lua │ ├── snippets │ │ └── global.json │ ├── lazy-lock.json │ ├── plugin │ │ ├── bigfile.lua │ │ ├── lsp.lua │ │ ├── coerce.lua │ │ ├── autocommands.lua │ │ └── options.lua │ └── init.lua ├── systemd │ └── user │ │ ├── check-updates.timer │ │ ├── mbsync.service │ │ ├── check-updates.service │ │ ├── mbsync.timer │ │ ├── encrypted_archive-gallerydl.timer.age │ │ ├── encrypted_emailnotification@.service.age │ │ ├── encrypted_syncphotos.service.age │ │ ├── encrypted_backups.service.age │ │ ├── encrypted_backups-forget.service.age │ │ ├── encrypted_archive-gallerydl.service.age │ │ ├── encrypted_syncphotos.timer.age │ │ ├── encrypted_backups-forget.timer.age │ │ └── encrypted_backups.timer.age ├── lazygit │ └── config.yml ├── helix │ └── config.toml ├── neofetch │ └── icons.txt ├── python │ └── config.py ├── yt-dlp │ └── config ├── mpv │ ├── script-opts │ │ ├── blacklist_extensions.conf │ │ ├── encode_slice.conf │ │ ├── crop.conf │ │ └── encode_webm.conf │ ├── input.conf │ └── scripts │ │ ├── blacklist-extensions.lua │ │ ├── misc.lua │ │ └── seek-to.lua ├── aerc │ ├── private_accounts.conf │ ├── stylesets │ │ ├── gruvbox-dark │ │ ├── catppuccin-mocha │ │ ├── catppuccin-frappe │ │ └── catppuccin-macchiato │ └── binds.conf ├── kitty │ ├── scrollback_pager.sh │ ├── symbols-map.conf │ └── kitty.conf ├── msmtp │ └── encrypted_private_config.age ├── bat │ └── config ├── gallery-dl │ └── config.json ├── git │ ├── config.tmpl │ └── gitmessage ├── wezterm │ └── wezterm.lua ├── readline │ └── inputrc ├── vis │ ├── visrc.lua │ ├── themes │ │ └── gruvbox.lua │ └── commentary.lua ├── MangoHud │ └── MangoHud.conf ├── alacritty │ └── alacritty.toml ├── ghostty │ └── config ├── mbsync │ └── encrypted_mbsyncrc.tmpl.age ├── npm │ └── npmrc ├── shell │ ├── aliasrc │ └── profile └── tmux │ └── tmux.conf ├── private_dot_ssh ├── id_ed25519.pub ├── encrypted_private_id_ed25519.age └── encrypted_private_known_hosts.age ├── .stylua.toml ├── keyd ├── SETUP.md ├── hold-ctrl-esc-on-tap.conf └── oneshot-ctrol-esc-on-double-tap.conf ├── .chezmoi.toml.tmpl ├── .luarc.jsonc ├── .chezmoiexternal.toml ├── .chezmoiscripts ├── run_once_before_00-get-keyfile.sh.tmpl └── run_once_before_01-decrypt-private-key.sh.tmpl ├── .nvim.lua ├── README.md └── dot_bashrc /.gitignore: -------------------------------------------------------------------------------- 1 | .k 2 | -------------------------------------------------------------------------------- /dot_zshenv: -------------------------------------------------------------------------------- 1 | export ZDOTDIR="$HOME"/.config/zsh 2 | -------------------------------------------------------------------------------- /.chezmoiignore: -------------------------------------------------------------------------------- 1 | README.md 2 | **/debug.lua 3 | .stylua.toml 4 | .k 5 | keyd/ 6 | -------------------------------------------------------------------------------- /dot_local/share/private_gnupg/private_dirmngr.conf: -------------------------------------------------------------------------------- 1 | keyserver hkps://keyserver.ubuntu.com 2 | -------------------------------------------------------------------------------- /private_dot_config/wget/wgetrc.tmpl: -------------------------------------------------------------------------------- 1 | hsts-file = /home/{{ .chezmoi.username }}/.cache/wget-hsts 2 | -------------------------------------------------------------------------------- /private_dot_config/zsh/symlink_dot_zshenv.tmpl: -------------------------------------------------------------------------------- 1 | {{ .chezmoi.homeDir }}/.config/shell/profile 2 | -------------------------------------------------------------------------------- /private_dot_ssh/id_ed25519.pub: -------------------------------------------------------------------------------- 1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINvoNNZpEngOyYsQsto32E+AX9h832RkiV2TivvJMtWQ rafa@rafaelmadriz.com 2 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/git/executable_git-modified: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Show all modified files within a git repo 3 | 4 | git ls-files --modified "$(git rev-parse --show-toplevel)" 5 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/ftplugin/css.lua: -------------------------------------------------------------------------------- 1 | -- Each word separated by "-" is recognized as a single word. 2 | -- Much better for CSS when changes values. 3 | vim.opt.iskeyword:remove "-" 4 | -------------------------------------------------------------------------------- /dot_local/share/private_gnupg/private_executable_gpg-agent.conf.tmpl: -------------------------------------------------------------------------------- 1 | default-cache-ttl 34560000 2 | max-cache-ttl 34560000 3 | 4 | keyserver hkps://keyserver.ubuntu.com 5 | pinentry-program /usr/bin/pinentry-tty 6 | -------------------------------------------------------------------------------- /.stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 120 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 4 5 | quote_style = "AutoPreferDouble" 6 | no_call_parentheses = true 7 | collapse_simple_statement = "FunctionOnly" 8 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/ftplugin/markdown.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.wrap = true 2 | vim.opt_local.spell = true 3 | vim.opt_local.linebreak = true 4 | vim.opt_local.textwidth = 90 5 | vim.opt_local.spelllang = { "en", "es" } 6 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/check-updates.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Run checkup script periodically 3 | 4 | [Timer] 5 | OnCalendar=*-*-* 12:00:00 6 | Persistent=true 7 | 8 | [Install] 9 | WantedBy=timers.target 10 | -------------------------------------------------------------------------------- /private_dot_config/lazygit/config.yml: -------------------------------------------------------------------------------- 1 | gui: 2 | nerdFontsVersion: "3" 3 | theme: 4 | selectedLineBgColor: 5 | - reverse 6 | git: 7 | pagers: 8 | - colorArg: always 9 | pager: delta --dark --paging=never 10 | -------------------------------------------------------------------------------- /keyd/SETUP.md: -------------------------------------------------------------------------------- 1 | ## Keyd 2 | 3 | 1. Install [keyd](https://github.com/rvaiya/keyd) 4 | 5 | 2. `sudo systemctl enable keyd` 6 | 7 | 3. Copy either `./hold-ctrl-esc-on-tap.conf` or 8 | `./oneshot-ctrol-esc-on-double-tap.conf` to `/etc/keyd/default.conf` 9 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_restore-tmux: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | # https://wiki.archlinux.org/title/tmux#Start_tmux_on_every_shell_login 4 | if [ -x "$(command -v tmux)" ] && [ -n "${DISPLAY}" ] && [ -z "${TMUX}" ]; then 5 | tmux new-session -A -s main >/dev/null 2>&1 6 | fi 7 | -------------------------------------------------------------------------------- /keyd/hold-ctrl-esc-on-tap.conf: -------------------------------------------------------------------------------- 1 | [ids] 2 | 3 | * 4 | 5 | [main] 6 | 7 | # remap capslock to control on hold, and esc on tap 8 | capslock = overload(control, esc) 9 | control = capslock 10 | 11 | shift = oneshot(shift) 12 | leftalt = oneshot(alt) 13 | rightalt = oneshot(altgr) 14 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/mbsync.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Mailbox synchronization service 3 | Wants=network-online.target 4 | After=network-online.target 5 | OnFailure=emailnotification@%n.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=%h/.local/bin/scripts/cron/syncemail 10 | -------------------------------------------------------------------------------- /private_dot_config/helix/config.toml: -------------------------------------------------------------------------------- 1 | theme = "vim_dark_high_contrast" 2 | 3 | [editor] 4 | line-number = "relative" 5 | cursorline = true 6 | 7 | [editor.cursor-shape] 8 | insert = "bar" 9 | normal = "block" 10 | 11 | [keys.insert] 12 | "C-c" = "normal_mode" 13 | 14 | [editor.file-picker] 15 | hidden = false 16 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/check-updates.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Check for package updates and notify user 3 | Wants=network-online.target 4 | After=network-online.target 5 | OnFailure=emailnotification@%n.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=%h/.local/bin/scripts/cron/checkup 10 | -------------------------------------------------------------------------------- /private_dot_config/neofetch/icons.txt: -------------------------------------------------------------------------------- 1 | time:  UE384 2 | time:  UF252 3 | shell:  UE60A 4 | shell:  UE795 5 | kernel:  UE712 6 | debian:  UF306 7 | arch:  UF303 8 | DE:  UF69E 9 | DE:  UE8AA 10 | packages:  UF8D6 11 | memory: ﴝ UFD1D 12 | disk: ◕ U25D5 13 | disk:  UE6C4 14 | cofee: ☕ U2615 15 | other:  UE614 16 | cpu:  Uf2db 17 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/mbsync.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Mailbox synchronization timer 3 | 4 | [Timer] 5 | # The timer will still start 2 minutes after the system boots up. 6 | OnBootSec=2m 7 | ; This triggers the mbsync.service 2 hours minutes after the service was last activated. 8 | OnUnitActiveSec=2h 9 | Unit=mbsync.service 10 | 11 | [Install] 12 | WantedBy=timers.target 13 | -------------------------------------------------------------------------------- /dot_local/share/private_applications/syncthing-ui.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Syncthing Web UI 3 | GenericName=File synchronization UI 4 | Comment=Opens Syncthing's Web UI in the default browser (Syncthing must already be started). 5 | Exec=/usr/bin/syncthing --browser-only 6 | Icon=syncthing 7 | Terminal=false 8 | Type=Application 9 | Keywords=synchronization;interface; 10 | Categories=Network;FileTransfer;P2P 11 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/ftplugin/gitcommit.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.list = false 2 | vim.opt_local.number = false 3 | vim.opt_local.relativenumber = false 4 | vim.opt_local.spell = true 5 | vim.opt_local.spelllang = "en_gb" 6 | vim.opt_local.textwidth = 72 7 | vim.opt_local.wrap = true 8 | vim.opt_local.linebreak = true 9 | vim.opt.foldmethod = "marker" 10 | vim.opt.foldmarker = "{{{,}}}" 11 | vim.opt.foldlevel = 0 12 | -------------------------------------------------------------------------------- /keyd/oneshot-ctrol-esc-on-double-tap.conf: -------------------------------------------------------------------------------- 1 | [ids] 2 | 3 | * 4 | 5 | [main] 6 | 7 | shift = oneshot(shift) 8 | leftalt = oneshot(alt) 9 | rightalt = oneshot(altgr) 10 | 11 | # CAPS as CTRL. 12 | # single tap to activate for the duration of next keypress, double tap for ESC. 13 | # Holding gives the expected behaviour of CTRL. 14 | control = capslock 15 | capslock = oneshot(control) 16 | 17 | [control] 18 | capslock = esc 19 | -------------------------------------------------------------------------------- /.chezmoi.toml.tmpl: -------------------------------------------------------------------------------- 1 | encryption = "age" 2 | 3 | [age] 4 | identity = "{{ .chezmoi.homeDir }}/.config/chezmoi/key.txt" 5 | recipient = "age16za5cd6p827u929wtrjeu40hyya0uu7tmdyrwntnt2l28pzdg5dsk076pw" 6 | 7 | [data] 8 | email = "rafa@rafaelmadriz.com" 9 | name = "Rafael Madriz" 10 | 11 | [diff] 12 | command = "delta" 13 | args = "--color-only" 14 | pager = "delta" 15 | 16 | [keepassxc] 17 | database = "{{ .chezmoi.homeDir }}/Documents/KeePass/pass.kdbx" 18 | -------------------------------------------------------------------------------- /private_dot_config/python/config.py: -------------------------------------------------------------------------------- 1 | import atexit 2 | import os 3 | import readline 4 | 5 | data_dir = os.environ["XDG_CACHE_HOME"] 6 | histfile = os.path.join(data_dir, "python_history") 7 | try: 8 | readline.read_history_file(histfile) 9 | # default history len is -1 (infinite), which may grow unruly 10 | readline.set_history_length(1000) 11 | except FileNotFoundError: 12 | pass 13 | 14 | atexit.register(readline.write_history_file, histfile) 15 | -------------------------------------------------------------------------------- /private_dot_config/yt-dlp/config: -------------------------------------------------------------------------------- 1 | # filename template 2 | --output "%(title)s.%(ext)s" 3 | 4 | # prevent downloading live chat as a subtitle track 5 | --compat-options no-live-chat 6 | 7 | # prevent listing unavailable videos for YouTube playlists 8 | --compat-options no-youtube-unavailable-videos 9 | 10 | --sponsorblock-mark all 11 | --embed-metadata 12 | --sub-langs all 13 | --embed-subs 14 | # --embed-thumbnail 15 | --convert-thumbnails jpg 16 | --embed-chapters 17 | -------------------------------------------------------------------------------- /private_dot_config/mpv/script-opts/blacklist_extensions.conf: -------------------------------------------------------------------------------- 1 | # only one of blacklist, whitelist should be defined at a time 2 | 3 | # only allow video and image formats 4 | whitelist=mkv,webm,png,jpg,mp4,avi,jpeg 5 | 6 | # alternatively, blacklist formats commonly found near videos 7 | #blacklist=srt,ass,mks,mka 8 | 9 | remove_files_without_extension=yes 10 | 11 | # if the script should be applied only at the beginning, or anytime the playlist changes 12 | oneshot=yes 13 | -------------------------------------------------------------------------------- /private_dot_config/mpv/script-opts/encode_slice.conf: -------------------------------------------------------------------------------- 1 | # profile to slice the current video without reencoding it 2 | # watch out that the extract will be snapped to keyframes; this is unavoidable when copying streams 3 | # see encode_webm.conf for a detailed explanations of all the options 4 | 5 | only_active_tracks=yes 6 | preserve_filters=no 7 | append_filter= 8 | codec=-c copy 9 | output_format=$f_$n.$x 10 | output_directory= 11 | detached=yes 12 | ffmpeg_command=ffmpeg 13 | print=yes 14 | -------------------------------------------------------------------------------- /.luarc.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", 3 | "diagnostics.globals": ["vim"], 4 | "runtime.version": "LuaJIT", 5 | "workspace.checkThirdParty": false, 6 | "workspace.library": [ 7 | "lua", 8 | "$VIMRUNTIME/lua", 9 | "${3rd}/busted/library", 10 | "${3rd}/luv/library" 11 | ], 12 | "completion.callSnippet": "Disable", 13 | "completion.keywordSnippet": "Disable" 14 | } 15 | -------------------------------------------------------------------------------- /private_dot_config/aerc/private_accounts.conf: -------------------------------------------------------------------------------- 1 | [fastmail] 2 | source = maildir://~/.local/share/maildir/fastmail 3 | outgoing = /usr/sbin/sendmail 4 | from = Rafael Madriz 5 | copy-to = Sent 6 | folders-sort = Inbox,Sent,Secondary,Money,Money/Transfers,Job,Archive,Gmail,Hotmail,Social,Others,Masked 7 | 8 | # [gmail] 9 | # source = maildir://~/.local/share/maildir/gmail 10 | # outgoing = /usr/sbin/sendmail 11 | # from = Rafael Madriz 12 | # copy-to = Sent 13 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/cron/executable_checkup: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | notify="notify-send --icon=system-software-install --app-name=Checkup --expire-time 3000 $1 $2" 4 | 5 | $notify "Repository sync" "Checking for packages updates." 6 | 7 | sudo pacman -Syyuw --noconfirm || $notify "Repository sync" "Error downloading updates." 8 | 9 | if pacman -Qu | grep -v "\[ignored\]" 10 | then 11 | $notify "Repository Sync" "Updates available." 12 | else 13 | $notify "Repository Sync" "Sync complete. No new packages for update." 14 | fi 15 | -------------------------------------------------------------------------------- /.chezmoiexternal.toml: -------------------------------------------------------------------------------- 1 | [".config/alacritty"] 2 | type = "archive" 3 | url = "https://github.com/alacritty/alacritty-theme/archive/refs/heads/master.zip" 4 | stripComponents = 1 5 | refreshPeriod = "672h" 6 | 7 | [".config/ghostty/shaders"] 8 | type = "git-repo" 9 | url = "https://github.com/hackr-sh/ghostty-shaders.git" 10 | refreshPeriod = "672h" 11 | 12 | [".config/bash/fzf-tab-completion"] 13 | type = "file" 14 | url = "https://raw.githubusercontent.com/lincheney/fzf-tab-completion/refs/heads/master/bash/fzf-bash-completion.sh" 15 | refreshPeriod = "672h" 16 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_nvims: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # Neovim bootloader to change configs 4 | # From: https://www.youtube.com/watch?v=LkHjJlSgKZY 5 | 6 | choose_config() { 7 | all_configs="LazyVim default debugnvim" 8 | selected=$(printf "%s" "$all_configs" | tr ' ' '\n' | fzf --prompt="Neovim config " --height=~50% --layout=reverse --border) 9 | if [ -z "$selected" ]; then 10 | printf "%s\n" "Nothing selected" 11 | return 0 12 | elif [ "$selected" = "default" ]; then 13 | selected="" 14 | fi 15 | NVIM_APPNAME=$selected nvim "$@" 16 | } 17 | 18 | choose_config "$@" 19 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_archive-gallerydl.timer.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqUEJPQS8zajVjRVMxTGx3 3 | d0Nwb3M3em0yTEVtanhPVmVBTHZtcjhLcDJzCndzWnd0a014ZVZMVnoxQ3dINnZT 4 | cGtFYmcvWUpWQ3lMRkdHNXlCYmVWeDgKLS0tIHNtSFI5SS92TDdveE9DUEMyMHBB 5 | cDB1M0pmaVI2NDhmcVAwMzMvZDBJckEKwzhKvaTrrprfenxBhXN+QeF1N/IIBurq 6 | m0UWkYh51LR31Pz3ws3c/9YTGaBTjbOqskDVHvT2bUEu5HZ9FL/YKyElJ4RXU3A7 7 | /en1ZDqHLkHOzjohAWMExhqXoL8bhxY8abtQiKfM5qZQjzqZEXegE/7xZPHjvj0Z 8 | VCAWvuc+1kWabf9+kWZ+4lpKbmqQnBfgan97E7rPfAtc9tCslYvapbEdwIt0gYC7 9 | -----END AGE ENCRYPTED FILE----- 10 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_emailnotification@.service.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1dENRMkNPazRSRVdENFpI 3 | YjhEaXlFNHlNc3VGeStxVXVuRmVmZmFIZUdVClpNaE5FQUEyc2VzdDZRaGJreWZx 4 | SVlmTzNQRjBoS1N1cUt5SFh6aGV2cXMKLS0tIDlwUWF6Qll5VG1QdCtSSWtPTUNo 5 | VUs4QUlJN3d3WVB2VElBTWIrSkhBeWsKAsgIi6J4D200rh/756vLahxTPca3Nsh3 6 | aporyJMUsg4gJ+fW9+me5J1uqwfBP0nxszQoWkwxUXKGchYvFVQjC4wXOUkFy4YA 7 | 72Xy2c4bbHx0npHq8FnBHJ80sWR/SXSyKibizy6gVWFczWHOFW4HWw86Uc1Dv+lk 8 | frlXXL0Lt76p+GflFv2veJFLeH/HxwEzj+OVSCNEchhKUDrNzdg1ZgmHNDxHd7xK 9 | pcwr5/1d8Pc= 10 | -----END AGE ENCRYPTED FILE----- 11 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_syncphotos.service.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAreHRNV2dybEhDdjBwMVJ1 3 | b0xwVDEvQ0hWOEZyZGNlS2xoazBGYTVJQlVNClFLS1pGanROMWozMURXamFJcnZt 4 | aVZ2akZKNXpBdWFhNzNVRmJieXdXQVEKLS0tICt6MVhEUXlrTGVLM05HR1hEczJ6 5 | d25vZUk3K0NpUG5wZmhzRlZUVFZJbUUKBv9tWeKWEwtgSu7frGuV3nPzdC7P5kXV 6 | JyQ8/iwFpEzJdcfTC4d8Troqx1JfQfzpPHCnxKsqCRdOKvmAFYlnLyNsWQO/Y7+T 7 | SCHLbobFPMeUf7Ekv9NwlM0507RCpVh5BFziBcICOr8l3ET3wyreD4ws7EXKCa7y 8 | zhV7PIez8es5SNd8DT+GYcad/QOilPAnXHJQjnQ/WKHO8YcslubHwvUtWRABr6kk 9 | hIunTkZG25Cdz0i3W5chtHEi 10 | -----END AGE ENCRYPTED FILE----- 11 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/git/executable_git-alias: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # 3 | # From git-extras 4 | # source: https://github.com/tj/git-extras/blob/master/bin/git-alias 5 | 6 | usage() { 7 | cat < # show aliases matching pattern 10 | or: git alias # alias a command 11 | HERE 12 | } 13 | 14 | case $# in 15 | 0) git config --get-regexp 'alias.*' | sed 's/^alias\.//' | sed 's/[ ]/ = /' | sort ;; 16 | 1) git alias | grep -e "$1" ;; 17 | 2) git config --global alias."$1" "$2" ;; 18 | *) echo >&2 "error: too many arguments." && usage && exit 1 ;; 19 | esac 20 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/ftplugin/qf.lua: -------------------------------------------------------------------------------- 1 | -- source: https://github.com/famiu/dot-nvim/blob/master/ftplugin/qf.lua 2 | -- author: @famiu 3 | local function RemoveQuickFixEntry() 4 | local line = vim.api.nvim_win_get_cursor(0)[1] 5 | local qflist = vim.fn.getqflist() 6 | 7 | -- Remove line from qflist. 8 | table.remove(qflist, line) 9 | vim.fn.setqflist(qflist, "r") 10 | 11 | -- Restore cursor position. 12 | local max_lines = vim.api.nvim_buf_line_count(0) 13 | vim.api.nvim_win_set_cursor(0, { math.min(line, max_lines), 0 }) 14 | end 15 | 16 | -- Allow easily removing quickfix items. 17 | vim.keymap.set("n", "dd", RemoveQuickFixEntry, { buffer = 0, silent = true }) 18 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_scrkey: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # 3 | # Show pressed keys on screen 4 | # Doesn't work on wayland, showmethekey can 5 | # be an alternative 6 | 7 | err() { 8 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 9 | } 10 | 11 | cleanup() { 12 | echo "Cleaning up and exiting..." 13 | pkill screenkey 14 | exit 0 15 | } 16 | 17 | trap cleanup INT 18 | 19 | if command -v screenkey >/dev/null 2>&1; then 20 | while true; do 21 | pkill screenkey 22 | screenkey -s large --scr 1 -p bottom --geometry 300x300+980+710 --timeout 1.5 & 23 | sleep 15 24 | echo "Restarting" 25 | done 26 | else 27 | err "screenkey must be executable" 28 | exit 1 29 | fi 30 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_backups.service.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCWjA1ZW1YMnpRV0ZWNER6 3 | ZGRXcS82Qk92UVpyUXlQM2svbnpNMGd3WlFRCnBUSTJIalJxdDB5UEpGSEw0MzNz 4 | K0hhRXNEUE50V2ZTbEZZMk5oc3RRa3MKLS0tIDhLOC9nQnVLSDFZRjNtS0w5cDJp 5 | L2ZHNytWQk1vNFhIRFkzd3pSWit5VmMKAeabITlLpHIzYJcNEBYkOJ/oWg1E0EBQ 6 | VRxbbpiDM+ax3O1XREuutcc8y5DKDT/2zT2JOdRi2IyzVqcMP0AxSjt3K2JEm4jV 7 | lbGibrz2ZA90lkEhki0IwRg8jG5TlPWTe/i59Rc6O6950y/9HMenSBkSOtZcrA7i 8 | Gp7AvOK9Up6x7huuMjPF+oe6nw4MFsE3Tp1rE/9pBImJ5bOCSSkPixs8oLQhvz+w 9 | nro70bS2hPhIJH8IOpZYuUWTop0nsnV73UXDph+kxZf/os2GmNKknQWccs/N57VT 10 | UpIR66kGBJ9W2nVR3jy7bUvYakQUj1fCgE0AFLZwtQ== 11 | -----END AGE ENCRYPTED FILE----- 12 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_backups-forget.service.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtTTA5Z05FSGpXUWVoY0Nh 3 | ei9XNHlrakh4anlaWFRGbXFWSldpd3dCYUJZClY3aUpuMW92MlZHcjl0eFlTUzJB 4 | Uzh4YlZVT2ZOa1J2dFpNMGdscWNaTVkKLS0tIEVWRitlMHdRMDhFU1ZUMWdJeThu 5 | dkJmMC96Z3VxaXFSNGxHTHNoeE5pWmcKjd6QPegkMXUeaVEBhJmiALlnC749tkLP 6 | +dME3nigJi57y0ABPXLX+cTHdck0e0jnDjAqok3au5dwlHNwFJc6ikRTpsYOJqeR 7 | 8e3f78dgNwjA0YAZToFYY1lN3oLXdTp0g7A3Y55sYFhSZBBV3BQhSmGo8CaTLNHl 8 | HuCYDCAgn43vrT/S4tOqP/vAnBQ34ti/B+DwoT8ZDycxoZhJ2zChp1TDfWeG2Njd 9 | Y8UBg5VzYz9/OH3yLWNWR9kPFSTOSeOTrXcz9/07Varoqva0G2+ROeP6DGhF+PbI 10 | BvaBKJhJ2pZ4QchfvsErLt6ogVTt8WrYqI1ebpXigqCbiQ== 11 | -----END AGE ENCRYPTED FILE----- 12 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_tmux-sessionizer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | if [ $# -eq 1 ]; then 4 | selected=$1 5 | else 6 | selected=$( 7 | ( 8 | find ~/code -mindepth 1 -maxdepth 1 -type d 9 | printf "%s\n" "$ZK_NOTEBOOK_DIR" "$DOTFILES" 10 | ) | fzf --preview 'tree -L 2 -C {} | head -50' 11 | ) 12 | fi 13 | 14 | if [ -z "$selected" ]; then 15 | exit 0 16 | fi 17 | 18 | selected_name=$(basename "$selected" | tr . _) 19 | tmux_running=$(pgrep tmux) 20 | 21 | if [ -z "$TMUX" ] && [ -z "$tmux_running" ]; then 22 | tmux new-session -s "$selected_name" -c "$selected" 23 | exit 0 24 | fi 25 | 26 | if ! tmux has-session -t="$selected_name" 2>/dev/null; then 27 | tmux new-session -ds "$selected_name" -c "$selected" 28 | fi 29 | 30 | tmux switch-client -t "$selected_name" 31 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_archive-gallerydl.service.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtOUJIMHZ2MWdaaG1DL0ZD 3 | QTEzZ2JaTDJyNVQzb3prWXVNS0dqMFRUV0VjCm9MajY2M1BJRnNQMlVzQXljek1D 4 | OVVVMjl4alVneElqYXY5Ynh4c3UrMzQKLS0tIHVKNExRQWJCMDFDTjJ4VG1SUGRZ 5 | RkVEVlEvYnRhM2N2QzdZVFVEMzhJdEUKTCGSyqfwVrlHSHvRZyI0nppN2DOZryUh 6 | yNFHVgbm/K3sqoXVZ9t2ku8BxHnZKcEfbc7+o2qY3PNTdqvZBaN34J62SjcRy6cN 7 | lg0m98QGeWB2HqU3dm6pm3lZHx4ncfYPqyRlO3x7mCt4cI/DdRdVFuewNjQcgYtj 8 | WS2/X9Wu+Z1VA3vAQAU9vU30+4y85u+b57geFFIHTAJKxPyxqm6s07LjymK3P3xB 9 | RPxZQNDQVIqWFywEvcOoWfrmO5MsrRN2atElaUp4PoUm2I9KqKeSzJMFV8cRUXCD 10 | d/x4EojcvCjQJ8ihLdKOc8x9Odjq2hjptMEftZlK6cCjjd4yVkjtq5pxOJwKZBBm 11 | WJCUmB1wIhfF5ZX7fJ4rphfHuD3jgpI+HDk= 12 | -----END AGE ENCRYPTED FILE----- 13 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_syncphotos.timer.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByTXptaU0yNkZOaGEzbkRs 3 | SVJIYmQ5aGQ1THhxTzh2REVhYzZ3ZHNMMnhBCk8yT1hCSlZXcnorODdpcTF1RXl6 4 | ZFQrMjl3YXZXWTdsc3FkeS9rVXNTRTAKLS0tIEZYZWtUam9NTmhqd3l3TlhkWnI4 5 | N2w1KzJuTlg4aGN6YU8xUUkvZkFrR00K4vljqtKfDnhvt4yauaXl8E+qCg+fbi+J 6 | MpRtUl414bR6+QI6dnOcU6Agx0McAOc8RZubMZWaLY9/J2fi+WnxmTlR3DU97aqp 7 | VAWD65evYX2l4YI12yOK9F7HFn31uW7FkfxUom6KR3N8q/fsy7kPzK959lFNgrIh 8 | naqj2kgsFis/TQRJHqI8SJSN/PepKxeSAq0POuTLwtBHFRPFx8lWXw6H94P03bo3 9 | SBesGk6wsOTta4NFvu/ar7lFI4T8BlnhsYFPxbVRPd51r6M7TIoikOCzFOqbPu5q 10 | X1KR95f8EVf6sZ4XryxNsZA45wB7l7ydEho3ObtdrcBxPPaLwDtiOIErn77TChjS 11 | ZWys/B3cqAxSqONMBOn0l/VilSEEaPYfQvcFyjM6CIqipkqnI4CdNt7OEcW+ZjGb 12 | gFf0FPnVIjykkgoP 13 | -----END AGE ENCRYPTED FILE----- 14 | -------------------------------------------------------------------------------- /private_dot_config/aerc/stylesets/gruvbox-dark: -------------------------------------------------------------------------------- 1 | ## 2 | # gruvbox light styleset 3 | # 4 | # Based on https://github.com/morhetz/gruvbox 5 | 6 | *.default=true 7 | *.selected.bg="#a89984" 8 | *.selected.fg="#282828" 9 | *.selected.bold=true 10 | 11 | title.bold=true 12 | title.bg="#a89984" 13 | title.fg="#282828" 14 | header.bold=true 15 | 16 | *error.bold=true 17 | error.fg="#cc241d" 18 | warning.fg="#d79921" 19 | success.fg="#98971a" 20 | 21 | border.bg="#7c6f64" 22 | stack.bg="#7c6f64" 23 | spinner.fg="#282828" 24 | 25 | statusline_default.bg="#7c6f64" 26 | statusline_error.fg="#cc241d" 27 | statusline_error.reverse=true 28 | 29 | msglist_unread.bold=true 30 | msglist_unread.fg="#427b58" 31 | 32 | completion_pill.reverse=true 33 | 34 | tab.bg="#7c6f64" 35 | tab.selected.bg="#a89984" 36 | 37 | selector_focused.reverse=true 38 | selector_chooser.bold=true 39 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_backups-forget.timer.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLdnlYdWVQdFVMYUdXS1d2 3 | SUYxWDY4RTBBR0VkK2U1QVJ1cmd6NDNXdUhZClVJWGtpbVZqelFSMi9BbC9HbU9z 4 | UTQxdkZ5dTd6RDNCTHZEWjRxY09tc2sKLS0tIElLVWZuNFlVUEVWOEJpSWYyK1NC 5 | MnNOYWttb3hCMTFDMlZ2UmZqcWc2OTAKx0eXl/XcgzOBjO18FdFAS6rz9C8IPVB4 6 | lYs+xRbU0v662XalQ9+jLSK5PMbSEptFT0QnxDR4KVJ9iR8iSEMMv6qoqVlM6o3s 7 | vo5R7irz1k1+pVNL1iVesoGfNZDl8TJq4SpKH9pGEYz4MJXeHPPVbdKa1E/vxrXs 8 | +6dY93XoTsItUvwmrfBwA4pq6EEsT4F63ea9P/M6phJH2CGJ/LQU01r1rixRprom 9 | nl+OuybEtYqDPiO+E6pyusXwGRJagJj0XVkkE8JkTdVp8fAtJjMMh6K45a3MqVRl 10 | RYwve90nob2ANLwlpB/T8E1cy4xoYPJ3OzlY8b+JUf4f5tx33NLe5J0sMHyJ+V7C 11 | SGDEtBIACQr8soZeoqNlVKfuSbZeVeoUg7R85hkOfrjDh7xBRohqOFq9RQCXjfqq 12 | sKXsJPSaAfmFM3oSh07HqyZqTjbgnGvnMLoxLCZ8lxpndQM= 13 | -----END AGE ENCRYPTED FILE----- 14 | -------------------------------------------------------------------------------- /private_dot_config/systemd/user/encrypted_backups.timer.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTY1RqUlY2Rnk0a2F1dEJZ 3 | d0t5OUlZMHhwOXhlRDlBOG9nTjZPeC9HTHhBCjNhVHpKU0FYLzZBLzFwTFRrQ0Nh 4 | UmY5OFdVV2IyR0JqWFhFMkNVUGQvcFkKLS0tIGNWTXVvTVRQOGd2SDNQMU42c1la 5 | Tm1rNndMempNOFdrT2s0VW83SU9FZGsKgh67sx+SrM2BD/rDKTFsEYjcpQ5rYzAm 6 | t5uGsfKNzIDiAZuQNbw8stJs+H2UURuKMlqPgnKObxJqfxoHR89xGIi8iVErDVgV 7 | 3Qa58okTnNPqYIx5PEsM8aBR1pD+WuLtT3o7ZXcplFDP1oArUYw2T4oWYFh4Wrtw 8 | BJnQAf6WqCauM9UH5V8umQYo2fATPhwDdWMd42Q2ftdDJluvEf9fwY8Fl9Kt6a6H 9 | KH9AApjwfIH9PGWfG+cEg8FMG706hIfTlRLZfNNffhmFq9gTs/Qv2QRwPSXfbpv+ 10 | KR0WtawOs0R0JUDonmbumqlJ74S/8kI28nobM02tBXSRddXjcUsnZMCqsFPgfOUk 11 | v8/amtRfie2BA7CY2SmiRiPZoq93GPBbBZ1D1HgyCTl97PwrYiZ5bLXIEHMfQ8v4 12 | QhKaa3iSpf1/dzJOTS+/8nrBSBeqqR3P3sJ2/RhbM2iDEeC+DpDd0pw= 13 | -----END AGE ENCRYPTED FILE----- 14 | -------------------------------------------------------------------------------- /.chezmoiscripts/run_once_before_00-get-keyfile.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | DATABASE="{{ .chezmoi.homeDir }}/Documents/KeePass/pass.kdbx" 4 | KEY="{{ .chezmoi.sourceDir }}/.k" 5 | 6 | if ! command -v keepassxc-cli >/dev/null 2>&1; then 7 | echo "KeePassXC cli needs to be installed" 8 | exit 1 9 | fi 10 | 11 | if [ ! -f "$KEY" ]; then 12 | # Initialize the attempt counter 13 | attempt=1 14 | max_attempts=3 15 | 16 | while ! keepassxc-cli attachment-export "$DATABASE" "archlinux/chezmoi-age-key" "key.age" "$KEY" 17 | do 18 | if [ $attempt -ge $max_attempts ]; then 19 | echo "Command failed after $attempt attempts. Exiting." 20 | exit 1 21 | fi 22 | echo "Command failed. Retrying..." 23 | attempt=$((attempt+1)) 24 | sleep 1 # Optional: wait 1 second before retrying 25 | done 26 | fi 27 | -------------------------------------------------------------------------------- /private_dot_config/kitty/scrollback_pager.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # source: https://github.com/kovidgoyal/kitty/issues/719#issuecomment-952039731 3 | 4 | set -eu 5 | 6 | if [ "$#" -eq 3 ]; then 7 | INPUT_LINE_NUMBER=${1:-0} 8 | CURSOR_LINE=${2:-1} 9 | CURSOR_COLUMN=${3:-1} 10 | AUTOCMD_TERMCLOSE_CMD="call cursor(max([0,${INPUT_LINE_NUMBER}-1])+${CURSOR_LINE}, ${CURSOR_COLUMN})" 11 | else 12 | AUTOCMD_TERMCLOSE_CMD="normal G" 13 | fi 14 | 15 | exec nvim \ 16 | -u NONE \ 17 | -c "map q :qa!" \ 18 | -c "xmap / /\\%V" \ 19 | -c "set scrollback=100000 termguicolors laststatus=0 cursorline clipboard+=unnamedplus" \ 20 | -c "autocmd TermEnter * stopinsert" \ 21 | -c "autocmd TermClose * ${AUTOCMD_TERMCLOSE_CMD}" \ 22 | -c 'terminal sed &2 9 | } 10 | 11 | if [ -z "$1" ]; then 12 | err "You need specify a source" 13 | exit 1 14 | fi 15 | 16 | if [ -z "$2" ]; then 17 | err "You need specify a destination" 18 | exit 1 19 | fi 20 | 21 | # `-h`: human readable 22 | # `-v`: verbose 23 | # `-r`: recurse into directories 24 | # `-z`: compress 25 | # `-P`: --partial (keep partially transferred files) + 26 | # --progress (show progress during transfer) 27 | # `-t`: preserve modification times 28 | if command -v rsync >/dev/null 2>&1; then 29 | rsync -h -v -r -z -P -t --exclude={'.stfolder*','.thumbnails'} "$1" "$2" 30 | else 31 | err "rsync is required but is not installed. Aborting" 32 | exit 1 33 | fi 34 | -------------------------------------------------------------------------------- /private_dot_config/mpv/input.conf: -------------------------------------------------------------------------------- 1 | # crop.lua 2 | # ========== 3 | # start cropping 4 | c script-message-to crop start-crop hard 5 | alt+c script-message-to crop start-crop soft 6 | # delogo mode can be used like so 7 | l script-message-to crop start-crop delogo 8 | # remove the crop 9 | d vf del -1 10 | 11 | # or use the ready-made "toggle" binding 12 | C script-message-to crop toggle-crop hard 13 | 14 | # encode.lua 15 | # ============ 16 | # use default profile (makes vp8 webms) 17 | # e script-message-to encode set-timestamp 18 | 19 | # use custom webm profile, the argument name must correspond to an existing .conf file (see script-opts/) 20 | # alt+e script-message-to encode set-timestamp encode_webm 21 | 22 | # use custom profile 23 | E script-message-to encode set-timestamp encode_slice 24 | 25 | # blur-edges.lua 26 | # ================ 27 | b script-message-to blur_edges toggle-blur 28 | 29 | # seek-to.lua 30 | # ============= 31 | t script-message-to seek_to toggle-seeker 32 | -------------------------------------------------------------------------------- /private_dot_ssh/encrypted_private_id_ed25519.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxdTZVeTNseVhBM0FqdHZK 3 | TjlyejVWNmVweE10TVRmY0ZWZGp4RzlUWG53Cis3T2xuU05VRmdLSUNzdFFyLzM4 4 | UUpCTGxlRFk5Q0UvVzhkWFFGNk5WMFkKLS0tIFRBbEwvMnJUM3JmRzZCL0xXZ0gw 5 | YlhnTUJQQlpCSDF3QXgrTFJrN3BrRVUK4aX99/9WOTXPTpL0Hwdk01kizORT0Yk8 6 | OqAd1r0LiFn9jSkeZ2rgXxMzw03phf84W2TC6ygcOmtpDgJP0/1OlozvbIGixZQm 7 | TlkiIVlxpBctMbtC9xV5skxZ4F7NZBMa0uzbE6NYGIVaQREJTc/d5PEq1WrlzZ7v 8 | bQwwZY1av0APb7Nmo5gXHSTfvYCAXS3XXAMmKm25bCv1VqgbmFIa+EqdlsuZDCCu 9 | GBF+T2WRQVf3qnXUIah4TSkhnrSWHhwguFT0I7+xmLtUjSUU616nNAMyJpWh6/KF 10 | ETTQwMfpcFd5vjJDehzgRz6ssCmLsTGS5GfAjJRBKD37dFaoyTIroWiNPAFOTOXg 11 | B9tBx6BuOhalT1KY1DA+o7J80Ot2rGbrN6m7Pl8hpQYiwO1zmrVpcz11MPWVX+tR 12 | 12fOyfHiADWTZsoe8iUXRbQj/Ql3rC3skSjHRB9AuBd4UqdFYwEIeFVzpiQlUYib 13 | Kk8ITgIMSMhJWhkDxul1zuhKsMi6q1m1ZtdD6EA1qx0m6/g+HGnQ4rsA7pQCMn99 14 | SnJNJhxru+yFgqptQP9Z4nnw2t5TiaZFSH5kiQs3CZyrWaM= 15 | -----END AGE ENCRYPTED FILE----- 16 | -------------------------------------------------------------------------------- /private_dot_config/msmtp/encrypted_private_config.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMaHdxL1RJT2hVeE9kd1Jy 3 | Sm12bkx1SFJhc21HWFJlSTNHdUJwZ1hkc0RnCjdEWmZTaFZFQ2VYOHRtblFCN0VV 4 | TytEV0JrRjBMcHp2K3hWMEgzbEVhSTQKLS0tIGYzREE2RTRXYjhBQk52U1ErVEhm 5 | aUxtd25UWGhvZDNnSzBtYjgxOFBxaWcKsr2UFGSuEZH0IIivvZZkpDHJ4QC/xfaN 6 | bqTlnQKeGFzzN+3Y6HGU1B1bZ4TDc1akaTFQvgbAdnd+0BFKjG9yOjj/PxAixSAz 7 | WxQZm0FX8EXqsq+MoofYRNDZKcc6fAVWHz3emrD11JzMMx5+J4jTLgVtQ53BGCd+ 8 | DyX1E7M/2SvrU5Ob+mBg4R2T6k/5HOzpyajE0z+DiR34rrAWAMlcL6f/I34W0Qtb 9 | 3GSfBNvmkRUn0mNOYor6usNqHohnHobFjyumQZ9oLHFuwhBp0vGJVD4M6SkebMuO 10 | Of3GeHA9KAWjnXusYVOj3350kPScuxYdbrycynNI+Nc2WsnQZnwASxnQ/+wj+17a 11 | riirYOWsAMKoZgp3xx1+FQEUUnTh+1hRahDyfqR2HTZPqgarU6q2hwuSi7i17S9c 12 | 3ppkUglFN14IujzzMwANz6cKyWfGrgRKTffXgpR2QcewKFFhHpWIH46EGXbKIrZn 13 | W6txcYGqqB2tSsLR1l94JyRmsB2sjoiF++aDX6HOoPKBX/ABUVLxD3jI3DuICj9d 14 | 0w75MOvJNcvH+EfdPmdWYrLcIMhaXt5sx6EOM99cCRZoqqBOcg3v4yZNM1bC9JfO 15 | Gdq3FccHYIB32cEIh4Vci5XMKkk= 16 | -----END AGE ENCRYPTED FILE----- 17 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_scrot: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | # 3 | # Take screenshots with maim, Only works on X11 4 | # For command line screenshots tools for wayland 5 | # look at grim or flameshot[2] 6 | # [2]: https://github.com/flameshot-org/flameshot 7 | 8 | err() { 9 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 10 | } 11 | 12 | main() { 13 | if [ $# -gt 0 ]; then 14 | case $1 in 15 | --select | -s) 16 | maim --select ~/Pictures/scrot/"$(date '+%s').png" 17 | exit 0 18 | ;; 19 | --copy | -c) 20 | maim | xclip -selection clipboard -t image/png 21 | exit 0 22 | ;; 23 | --select-and-copy | -C) 24 | maim --select | xclip -selection clipboard -t image/png 25 | exit 0 26 | ;; 27 | esac 28 | else 29 | maim ~/Pictures/scrot/"$(date '+%s').png" 30 | fi 31 | } 32 | 33 | if command -v maim xclip >/dev/null 2>&1; then 34 | main "$@" 35 | else 36 | err "maim and xclip must be executable" 37 | exit 1 38 | fi 39 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/cron/executable_syncemail.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | MAILDIR="{{ .chezmoi.homeDir }}/.local/share/maildir" 4 | 5 | [ ! -d "$MAILDIR" ] && mkdir -p "$MAILDIR"/fastmail/TrashArchive 6 | 7 | # --recursive: recurse into directories 8 | # --links: copy symlinks as symlinks 9 | # -p: preserve permissions 10 | # --times: preserve modification times 11 | # --group: preserve group 12 | # --owner: preserve owner 13 | # --progress: show progress during transfer 14 | # --ignore-existing: ignore files that already exist on receiving side 15 | # --human-readable: output numbers in a human-readable format 16 | rsync --verbose --recursive --links -p --times --group --owner --progress --ignore-existing --human-readable "$MAILDIR"/fastmail/Trash/* "$MAILDIR"/fastmail/TrashArchive || exit 1 17 | rsync --verbose --recursive --links -p --times --group --owner --progress --ignore-existing --human-readable "$MAILDIR"/fastmail/Spam/* "$MAILDIR"/fastmail/TrashArchive || exit 1 18 | 19 | # Sync mailboxes 20 | mbsync --config "{{ .chezmoi.homeDir }}/.config/mbsync/mbsyncrc" --verbose fastmail 21 | -------------------------------------------------------------------------------- /private_dot_config/mpv/script-opts/crop.conf: -------------------------------------------------------------------------------- 1 | # default mode to be used if not specified in the script-message 2 | # can be hard, soft or delogo 3 | # in hard mode, a crop filter is applied to the video 4 | # in soft mode, video-zoom, video-pan-x and video-pan-y are modified to simulate the cropping 5 | # in delogo mode, the delogo filter is applied to the selected are 6 | # hard mode interacts nicely with encode.lua, soft mode does not 7 | mode=hard 8 | 9 | draw_crosshair=yes 10 | draw_text=yes 11 | draw_shade=yes 12 | draw_frame=yes 13 | frame_border_width=2 14 | frame_border_color=EEEEEE 15 | # hexadecimal: 00 is opaque, FF is transparent 16 | shade_opacity=77 17 | mouse_support=yes 18 | 19 | # movement is defined in pixels in the window 20 | # which explains the mismatch with the text (in video space) 21 | coarse_movement=30 22 | left_coarse=LEFT 23 | right_coarse=RIGHT 24 | up_coarse=UP 25 | down_coarse=DOWN 26 | fine_movement=1 27 | left_fine=ALT+LEFT 28 | right_fine=ALT+RIGHT 29 | up_fine=ALT+UP 30 | down_fine=ALT+DOWN 31 | 32 | # these two options accept comma separated list of keys 33 | accept=ENTER,MOUSE_BTN0 34 | cancel=ESC 35 | -------------------------------------------------------------------------------- /private_dot_config/aerc/stylesets/catppuccin-mocha: -------------------------------------------------------------------------------- 1 | *.default=true 2 | *.normal=true 3 | 4 | default.fg=#cdd6f4 5 | 6 | error.fg=#f38ba8 7 | warning.fg=#fab387 8 | success.fg=#a6e3a1 9 | 10 | tab.fg=#6c7086 11 | tab.bg=#181825 12 | tab.selected.fg=#cdd6f4 13 | tab.selected.bg=#1e1e2e 14 | tab.selected.bold=true 15 | 16 | border.fg=#11111b 17 | border.bold=true 18 | 19 | msglist_unread.bold=true 20 | msglist_flagged.fg=#f9e2af 21 | msglist_flagged.bold=true 22 | msglist_result.fg=#89b4fa 23 | msglist_result.bold=true 24 | msglist_*.selected.bold=true 25 | msglist_*.selected.bg=#313244 26 | 27 | dirlist_*.selected.bold=true 28 | dirlist_*.selected.bg=#313244 29 | 30 | statusline_default.fg=#9399b2 31 | statusline_default.bg=#313244 32 | statusline_error.bold=true 33 | statusline_success.bold=true 34 | 35 | completion_default.selected.bg=#313244 36 | 37 | [viewer] 38 | url.fg=#89b4fa 39 | url.underline=true 40 | header.bold=true 41 | signature.dim=true 42 | diff_meta.bold=true 43 | diff_chunk.fg=#89b4fa 44 | diff_chunk_func.fg=#89b4fa 45 | diff_chunk_func.bold=true 46 | diff_add.fg=#a6e3a1 47 | diff_del.fg=#f38ba8 48 | quote_*.fg=#6c7086 49 | quote_1.fg=#9399b2 50 | -------------------------------------------------------------------------------- /private_dot_config/aerc/stylesets/catppuccin-frappe: -------------------------------------------------------------------------------- 1 | *.default=true 2 | *.normal=true 3 | 4 | default.fg=#c6d0f5 5 | 6 | error.fg=#e78284 7 | warning.fg=#ef9f76 8 | success.fg=#a6d189 9 | 10 | tab.fg=#737994 11 | tab.bg=#292c3c 12 | tab.selected.fg=#c6d0f5 13 | tab.selected.bg=#303446 14 | tab.selected.bold=true 15 | 16 | border.fg=#232634 17 | border.bold=true 18 | 19 | msglist_unread.bold=true 20 | msglist_flagged.fg=#e5c890 21 | msglist_flagged.bold=true 22 | msglist_result.fg=#8caaee 23 | msglist_result.bold=true 24 | msglist_*.selected.bold=true 25 | msglist_*.selected.bg=#414559 26 | 27 | dirlist_*.selected.bold=true 28 | dirlist_*.selected.bg=#414559 29 | 30 | statusline_default.fg=#949cbb 31 | statusline_default.bg=#414559 32 | statusline_error.bold=true 33 | statusline_success.bold=true 34 | 35 | completion_default.selected.bg=#414559 36 | 37 | [viewer] 38 | url.fg=#8caaee 39 | url.underline=true 40 | header.bold=true 41 | signature.dim=true 42 | diff_meta.bold=true 43 | diff_chunk.fg=#8caaee 44 | diff_chunk_func.fg=#8caaee 45 | diff_chunk_func.bold=true 46 | diff_add.fg=#a6d189 47 | diff_del.fg=#e78284 48 | quote_*.fg=#737994 49 | quote_1.fg=#949cbb 50 | -------------------------------------------------------------------------------- /private_dot_config/aerc/stylesets/catppuccin-macchiato: -------------------------------------------------------------------------------- 1 | *.default=true 2 | *.normal=true 3 | 4 | default.fg=#cad3f5 5 | 6 | error.fg=#ed8796 7 | warning.fg=#f5a97f 8 | success.fg=#a6da95 9 | 10 | tab.fg=#6e738d 11 | tab.bg=#1e2030 12 | tab.selected.fg=#cad3f5 13 | tab.selected.bg=#24273a 14 | tab.selected.bold=true 15 | 16 | border.fg=#181926 17 | border.bold=true 18 | 19 | msglist_unread.bold=true 20 | msglist_flagged.fg=#eed49f 21 | msglist_flagged.bold=true 22 | msglist_result.fg=#8aadf4 23 | msglist_result.bold=true 24 | msglist_*.selected.bold=true 25 | msglist_*.selected.bg=#363a4f 26 | 27 | dirlist_*.selected.bold=true 28 | dirlist_*.selected.bg=#363a4f 29 | 30 | statusline_default.fg=#939ab7 31 | statusline_default.bg=#363a4f 32 | statusline_error.bold=true 33 | statusline_success.bold=true 34 | 35 | completion_default.selected.bg=#363a4f 36 | 37 | [viewer] 38 | url.fg=#8aadf4 39 | url.underline=true 40 | header.bold=true 41 | signature.dim=true 42 | diff_meta.bold=true 43 | diff_chunk.fg=#8aadf4 44 | diff_chunk_func.fg=#8aadf4 45 | diff_chunk_func.bold=true 46 | diff_add.fg=#a6da95 47 | diff_del.fg=#ed8796 48 | quote_*.fg=#6e738d 49 | quote_1.fg=#939ab7 50 | -------------------------------------------------------------------------------- /private_dot_config/bat/config: -------------------------------------------------------------------------------- 1 | # This is `bat`s configuration file. Each line either contains a comment or 2 | # a command-line option that you want to pass to `bat` by default. You can 3 | # run `bat --help` to get a list of all possible configuration options. 4 | 5 | # Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes` 6 | # for a list of all available themes 7 | --theme="Coldark-Dark" 8 | 9 | # Enable this to use italic text on the terminal. This is not supported on all 10 | # terminal emulators (like tmux, by default): 11 | #--italic-text=always 12 | 13 | # Uncomment the following line to disable automatic paging: 14 | #--paging=never 15 | 16 | # Uncomment the following line if you are using less version >= 551 and want to 17 | # enable mouse scrolling support in `bat` when running inside tmux. This might 18 | # disable text selection, unless you press shift. 19 | #--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse" 20 | 21 | # Syntax mappings: map a certain filename pattern to a language. 22 | # Example 1: use the C++ syntax for .ino files 23 | # Example 2: Use ".gitignore"-style highlighting for ".ignore" files 24 | #--map-syntax "*.ino:C++" 25 | #--map-syntax ".ignore:Git Ignore" 26 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/encrypted_executable_emailnotification.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3YU1taUxtdXNHem9BdHAw 3 | QjArVXFTMysxZ21qdFBmMGZqV3lKLzhqcUVJCitRczM2MXo5WDFrSlNLS1RkVmV4 4 | V2IrM3drS0hXYXg4YUsvcGwyWVdSQ2MKLS0tIHJ1YndRNENBbjI2MmlzY2ZmM2Js 5 | aUFRRFFjT295WE01YnBXYXlnTHVCUzgKylK2dK2+NpUB0u8Im85H2sDHk/ZAuUu3 6 | KYQwR7+qd65xjFl2cYAonj+Ar70dKwiJzU1KOk8g2aGF+X62HMO4roN4qfbJYwey 7 | DGBjiS7hbmxAfu96J43e+HsA+WPd4Cbpf0mRjSI0KQdDnOn0mbSpBeSQndV+U+0E 8 | UuN2zv4aReN/wjajxuJ3RZcKgdtJTw+crGdljZgVRkXGRv4i3ccEFLIlTqiHJ+7s 9 | l65u1wmxE4Qij6Q6CFAVz7jhdoO3ejjHP/5UrSj8PGkG4tPuf7fGz3elM7XiUQwe 10 | bTm4Tq8mZuVN8WiCjh0TWpldUCBp7wOKJHrmYuFGC/SrlEhJl8nmS7o0gmYptlEp 11 | GlPTqM33P6Otg/M8ie1jUCot8jdIFpH4+MXaA/sY1Kw7y0u8l48oX/UDlOlmYJNx 12 | KQW5VslYT1/EVL1c9ZDN/+cOsVqo3KUCgmEPo3sMb5xssZuH7/p9LisGPp66CwIA 13 | BZaxginvf46qIpiJayff2vE1wdFVVTRAi879zXsrjmg8WnEAtTDbp8bbQa7txOZq 14 | 1APMv8j+KGXY7BLZzg1Y/0EaFW6OXB6w37zG0s4Y1uxBaOxGX/v1rIyPH2mw24aM 15 | SAe8vEqgv6f4o3uPv4uBMyfzzhFxD/NaolZ4EpZCPdmRxrQHTyfJwefXi4qaSBgr 16 | IQPaAQU8SlN1E4gvPgQavQeZs05e8otsS+CkgeMV3bJ6dWyi0oQOQVDVvU97Umjw 17 | NblZqMmPXgsrFvtRWNrq2VJTQGvcSYa6Ef5jivSlRhI9CMMZtOgvn7o5nLIPNtCE 18 | sANmjo4uE4duqZipJhvChljwaDe50WBDRjBsczoZU4z4615fR63VFdx7bdIr 19 | -----END AGE ENCRYPTED FILE----- 20 | -------------------------------------------------------------------------------- /private_dot_config/gallery-dl/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extractor": { 3 | "base-directory": "~/Pictures/random/gallery-dl", 4 | "archive": "~/Pictures/random/gallery-dl/db/archive.sqlite3" 5 | }, 6 | "postprocessors": [ 7 | { 8 | "name": "exec", 9 | "async": false, 10 | "archive": "~/Pictures/random/gallery-dl/db/optimization-png.sqlite3", 11 | "archive-prefix": "{category}, ", 12 | "archive-format": "{id}.{extension!l}", 13 | "archive-pragma": ["journal_mode=WAL", "synchronous=NORMAL"], 14 | "command": "oxipng -o max --strip safe --force --preserve {}", 15 | "event": "after", 16 | "filter": "extension == 'png'", 17 | "mtime": true, 18 | "blacklist": null 19 | }, 20 | { 21 | "name": "exec", 22 | "async": false, 23 | "archive": "~/Pictures/random/gallery-dl/db/optimization-jpg.sqlite3", 24 | "archive-prefix": "{category}, ", 25 | "archive-format": "{id}.{extension!l}", 26 | "archive-pragma": ["journal_mode=WAL", "synchronous=NORMAL"], 27 | "command": "exiftran -ai {} && jpegtran -copy none -perfect -optimize -outfile {} {}", 28 | "event": "after", 29 | "filter": "extension == 'jpg'", 30 | "mtime": true, 31 | "blacklist": null 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /private_dot_config/git/config.tmpl: -------------------------------------------------------------------------------- 1 | [user] 2 | email = {{ .email }} 3 | name = {{ .name }} 4 | 5 | [commit] 6 | template = ~/.config/git/gitmessage 7 | gpgsign = false 8 | verbose = true 9 | 10 | [core] 11 | editor = nvim 12 | 13 | [alias] 14 | lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit 15 | dlg = log -p --cc --graph --decorate 16 | wtf = log --pretty=format:"%C(auto,yellow)%h%C(auto)%d%C(auto,reset)\\ by\\ %C(auto,blue)%an%C(auto,reset),\\ %C(auto,cyan)%ar%C(auto,reset)%n\\ %s%n" --stat 17 | ls = ls-files 18 | sw = switch 19 | co = checkout 20 | tree = log --all --graph --decorate --oneline --simplify-by-decoration 21 | fixup = commit --amend --no-edit --allow-empty 22 | root = rev-parse --show-toplevel 23 | 24 | [merge] 25 | conflictstyle = diff3 26 | 27 | {{- if lookPath "delta" }} 28 | [interactive] 29 | diffFilter = delta --color-only 30 | [add.interactive] 31 | useBuiltin = false 32 | 33 | [delta] 34 | navigate = true 35 | line-numbers = true 36 | hyperlinks = true 37 | ; side-by-side = true 38 | 39 | [core] 40 | pager = delta 41 | {{- end }} 42 | 43 | [color] 44 | ui = auto 45 | 46 | [init] 47 | defaultBranch = main 48 | -------------------------------------------------------------------------------- /private_dot_config/wezterm/wezterm.lua: -------------------------------------------------------------------------------- 1 | local wezterm = require "wezterm" 2 | 3 | local config = {} 4 | 5 | if wezterm.config_builder then config = wezterm.config_builder() end 6 | 7 | config.keys = { 8 | { 9 | key = "E", 10 | mods = "CTRL", 11 | action = wezterm.action.QuickSelectArgs { 12 | label = "open url", 13 | patterns = { 14 | "https?://\\S+", 15 | }, 16 | action = wezterm.action_callback(function(window, pane) 17 | local url = window:get_selection_text_for_pane(pane) 18 | wezterm.log_info("opening: " .. url) 19 | wezterm.open_with(url) 20 | end), 21 | }, 22 | }, 23 | } 24 | 25 | config.enable_tab_bar = false 26 | config.window_padding = { 27 | left = 0, 28 | right = 0, 29 | top = 0, 30 | bottom = 0, 31 | } 32 | config.color_scheme = "tokyonight" 33 | -- window buttons like close, maximize, etc. 34 | config.window_decorations = "INTEGRATED_BUTTONS|RESIZE" 35 | 36 | config.font = wezterm.font_with_fallback { 37 | -- "JetBrains Mono", 38 | "Cascadia Code", 39 | -- "Fira Code", 40 | -- "Hack", 41 | -- "Source Code Pro", 42 | "Noto Color Emoji", 43 | { family = "Symbols Nerd Font Mono", scale = 0.75 }, -- Set scale otherwise some icons look to big 44 | } 45 | 46 | return config 47 | -------------------------------------------------------------------------------- /private_dot_config/zsh/functions: -------------------------------------------------------------------------------- 1 | #!/bin/env zsh 2 | 3 | # Function to source files if they exist 4 | function zsh_add_file() { 5 | [ -f "$ZDOTDIR/$1" ] && source "$ZDOTDIR/$1" 6 | } 7 | 8 | # Who needs oh-my-zsh ? 9 | function zsh_add_plugin() { 10 | PLUGIN_NAME=$(echo $1 | cut -d "/" -f 2) 11 | if [ -d "$ZDOTDIR/plugins/$PLUGIN_NAME" ]; then 12 | zsh_add_file "plugins/$PLUGIN_NAME/$PLUGIN_NAME.plugin.zsh" || 13 | zsh_add_file "plugins/$PLUGIN_NAME/$PLUGIN_NAME.zsh" 14 | else 15 | git clone "https://github.com/$1.git" "$ZDOTDIR/plugins/$PLUGIN_NAME" 16 | fi 17 | } 18 | 19 | # add title to terminal to display state,currently executing command, current directory... 20 | autoload -Uz add-zsh-hook 21 | function xterm_title_precmd () { 22 | print -Pn -- '\e]2;%n@%m %~\a' 23 | [[ "$TERM" == 'screen'* ]] && print -Pn -- '\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-}\e\\' 24 | } 25 | 26 | function xterm_title_preexec () { 27 | print -Pn -- '\e]2;%n@%m %~ %# ' && print -n -- "${(q)1}\a" 28 | [[ "$TERM" == 'screen'* ]] && { print -Pn -- '\e_\005{g}%n\005{-}@\005{m}%m\005{-} \005{B}%~\005{-} %# ' && print -n -- "${(q)1}\e\\"; } 29 | } 30 | 31 | if [[ "$TERM" == (alacritty*|gnome*|konsole*|putty*|rxvt*|screen*|tmux*|xterm*) ]]; then 32 | add-zsh-hook -Uz precmd xterm_title_precmd 33 | add-zsh-hook -Uz preexec xterm_title_preexec 34 | fi 35 | -------------------------------------------------------------------------------- /.nvim.lua: -------------------------------------------------------------------------------- 1 | -- to run this file as a local nvim config see `help trust` 2 | 3 | if (vim.fn.exists "$TMUX" == 1) and (vim.fn.executable "chezmoi" > 0) then 4 | vim.api.nvim_create_user_command("ChezmoiApply", function(arg) 5 | local function command(file) 6 | vim.system({ "tmux", "display-popup", "-E", "chezmoi", "apply", file or nil }, { text = true }) 7 | end 8 | 9 | local filename = vim.fn.expand "%" 10 | if vim.fn.fnamemodify(filename, ":."):match "^%." then 11 | -- only execute command without filename 12 | -- ignore files starting with `.` 13 | command() 14 | return 15 | end 16 | 17 | if arg.bang then 18 | local chezmoi_file = vim.fn.systemlist({ "chezmoi", "target-path", filename })[1] 19 | command(chezmoi_file) 20 | else 21 | command() 22 | end 23 | end, { bang = true }) 24 | 25 | vim.api.nvim_create_autocmd("BufWritePost", { 26 | group = vim.api.nvim_create_augroup("chezmoi-nvim-lua", { clear = true }), 27 | callback = function(info) 28 | if vim.fn.fnamemodify(info.file, ":."):match "^%." then 29 | -- ignore files starting with `.` 30 | return 31 | end 32 | 33 | vim.cmd.ChezmoiApply { bang = true } 34 | end, 35 | }) 36 | end 37 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/configs/treesitter.lua: -------------------------------------------------------------------------------- 1 | local ts = require "nvim-treesitter" 2 | 3 | local parsers = { 4 | "bash", 5 | "c", 6 | "comment", 7 | "cpp", 8 | "css", 9 | "go", 10 | "html", 11 | "javascript", 12 | "json", 13 | "lua", 14 | "luadoc", 15 | "luap", 16 | "markdown", 17 | "markdown_inline", 18 | "python", 19 | "query", 20 | "regex", 21 | "rust", 22 | "tsx", 23 | "typescript", 24 | "vim", 25 | "vimdoc", 26 | "yaml", 27 | "zig", 28 | "http", 29 | } 30 | 31 | local function get_parsers_to_install() 32 | local installed = ts.get_installed() 33 | local not_installed = {} 34 | 35 | for _, parser in pairs(parsers) do 36 | if not vim.tbl_contains(installed, parser) then 37 | table.insert(not_installed, parser) 38 | end 39 | end 40 | 41 | return not_installed 42 | end 43 | 44 | ts.install(get_parsers_to_install()) 45 | 46 | vim.api.nvim_create_autocmd("FileType", { 47 | pattern = ts.get_installed(), 48 | callback = function(ev) 49 | -- syntax highlighting, provided by Neovim 50 | vim.treesitter.start() 51 | -- indentation, provided by nvim-treesitter 52 | vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" 53 | -- treesitter based folding 54 | vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" 55 | end, 56 | }) 57 | -------------------------------------------------------------------------------- /private_dot_config/zsh/plugins/colored-man-pages.zsh: -------------------------------------------------------------------------------- 1 | # Requires colors autoload. 2 | # See termcap(5). 3 | 4 | # Set up once, and then reuse. This way it supports user overrides after the 5 | # plugin is loaded. 6 | typeset -AHg less_termcap 7 | 8 | # bold & blinking mode 9 | less_termcap[mb]="${fg_bold[red]}" 10 | less_termcap[md]="${fg_bold[red]}" 11 | less_termcap[me]="${reset_color}" 12 | # standout mode 13 | less_termcap[so]="${fg_bold[yellow]}${bg[blue]}" 14 | less_termcap[se]="${reset_color}" 15 | # underlining 16 | less_termcap[us]="${fg_bold[green]}" 17 | less_termcap[ue]="${reset_color}" 18 | 19 | # Absolute path to this file's directory. 20 | typeset __colored_man_pages_dir="${0:A:h}" 21 | 22 | function colored() { 23 | local -a environment 24 | 25 | # Convert associative array to plain array of NAME=VALUE items. 26 | local k v 27 | for k v in "${(@kv)less_termcap}"; do 28 | environment+=( "LESS_TERMCAP_${k}=${v}" ) 29 | done 30 | 31 | # Prefer `less` whenever available, since we specifically configured 32 | # environment for it. 33 | environment+=( PAGER="${commands[less]:-$PAGER}" ) 34 | 35 | # See ./nroff script. 36 | if [[ "$OSTYPE" = solaris* ]]; then 37 | environment+=( PATH="${__colored_man_pages_dir}:$PATH" ) 38 | fi 39 | 40 | command env $environment "$@" 41 | } 42 | 43 | # Colorize man and dman/debman (from debian-goodies) 44 | function man \ 45 | dman \ 46 | debman { 47 | colored $0 "$@" 48 | } 49 | -------------------------------------------------------------------------------- /private_dot_config/readline/inputrc: -------------------------------------------------------------------------------- 1 | set meta-flag on 2 | set input-meta on 3 | set output-meta on 4 | set convert-meta off 5 | set completion-ignore-case on 6 | set completion-prefix-display-length 2 7 | set show-all-if-ambiguous on 8 | set show-all-if-unmodified on 9 | 10 | # Arrow keys match what you've typed so far against your command history 11 | "\e[A": history-search-backward 12 | "\e[B": history-search-forward 13 | "\e[C": forward-char 14 | "\e[D": backward-char 15 | 16 | # Immediately add a trailing slash when autocompleting symlinks to directories 17 | set mark-symlinked-directories on 18 | 19 | # Do not autocomplete hidden files unless the pattern explicitly begins with a dot 20 | set match-hidden-files off 21 | 22 | # Show all autocomplete results at once 23 | set page-completions off 24 | 25 | # If there are more than 200 possible completions for a word, ask to show them all 26 | set completion-query-items 200 27 | 28 | # Show extra file information when completing, like `ls -F` does 29 | set visible-stats on 30 | 31 | # Be more intelligent when autocompleting by also looking at the text after 32 | # the cursor. For example, when the current line is "cd ~/src/mozil", and 33 | # the cursor is on the "z", pressing Tab will not autocomplete it to "cd 34 | # ~/src/mozillail", but to "cd ~/src/mozilla". (This is supported by the 35 | # Readline used by Bash 4.) 36 | set skip-completed-text on 37 | 38 | # Coloring for Bash 4 tab completions. 39 | set colored-stats on 40 | -------------------------------------------------------------------------------- /private_dot_config/vis/visrc.lua: -------------------------------------------------------------------------------- 1 | require("vis") 2 | require("commentary") 3 | 4 | vis.events.subscribe(vis.events.INIT, function() 5 | -- Your global configuration options 6 | vis:command("set autoindent on") 7 | vis:command("set escdelay 0") 8 | vis:command("set tabwidth 4") 9 | vis:command("set ignorecase") 10 | vis:command("set expandtab") 11 | vis:command("set theme gruvbox") 12 | end) 13 | 14 | vis.events.subscribe(vis.events.WIN_OPEN, function(win) 15 | -- Your per window configuration options 16 | vis:command("set number") 17 | vis:command("set relativenumbers") 18 | vis:command("set cursorline") 19 | end) 20 | 21 | -- not sure of what this does. 22 | -- vis:map(vis.modes.NORMAL, "", function() 23 | -- if vis.count then 24 | -- vis.count = nil 25 | -- else 26 | -- vis:feedkeys("") 27 | -- end 28 | -- end) 29 | 30 | vis:command_register("fzf", function(argv, force, cur_win, selection, range) 31 | local out = io.popen("fzf"):read() 32 | if out then 33 | if argv[1] then 34 | vis:command(string.format('e "%s"', out)) 35 | else 36 | vis:command(string.format('open "%s"', out)) 37 | end 38 | vis:feedkeys("") 39 | end 40 | end, "fuzzy file search") 41 | 42 | vis:command_register("sts", function(argv, force, win, selection, range) 43 | local lines = win.file.lines 44 | for index = 1, #lines do 45 | lines[index] = lines[index]:gsub("%s+$", "") 46 | end 47 | return true 48 | end, "Strip line trailing spaces") 49 | 50 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "diso": { 3 | "prefix": "diso", 4 | "body": [ 5 | "${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}T${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}" 6 | ], 7 | "description": "ISO date time stamp" 8 | }, 9 | "date": { 10 | "prefix": "date", 11 | "body": ["${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}"], 12 | "description": "Put the date in (Y-m-D) format" 13 | }, 14 | "dateDMY": { 15 | "prefix": "dateDMY", 16 | "body": ["${CURRENT_DATE}/${CURRENT_MONTH}/${CURRENT_YEAR}"], 17 | "description": "Put date in (DD/MM/YY) format" 18 | }, 19 | "dateMDY": { 20 | "prefix": "dateMDY", 21 | "body": ["${CURRENT_MONTH}/${CURRENT_DATE}/${CURRENT_YEAR}"], 22 | "description": "Put the date in (m/D/Y) format" 23 | }, 24 | "time": { 25 | "prefix": "time", 26 | "body": ["${CURRENT_HOUR}:${CURRENT_MINUTE}"], 27 | "description": "I give you back the time (H:M)" 28 | }, 29 | "timeHMS": { 30 | "prefix": "timeHMS", 31 | "body": ["${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}"], 32 | "description": "I give you back the time (H:M:S)" 33 | }, 34 | "datetime": { 35 | "prefix": "datetime", 36 | "body": [ 37 | "${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}" 38 | ], 39 | "description": "I give you back the time and date (Y-m-d H:M)" 40 | }, 41 | "uuid": { 42 | "prefix": "uuid", 43 | "body": "${UUID}", 44 | "description": "A Version 4 UUID" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /private_dot_config/MangoHud/MangoHud.conf: -------------------------------------------------------------------------------- 1 | # ################### File Generated by GOverlay ################### 2 | # fps_limit=60 3 | # toggle_fps_limit=F2 4 | # 5 | # 6 | # legacy_layout=false 7 | # gpu_stats 8 | # gpu_temp 9 | # gpu_load_change 10 | # gpu_load_value=50,90 11 | # gpu_load_color=FFFFFF,FFAA7F,CC0000 12 | # gpu_text=GPU 13 | # cpu_stats 14 | # cpu_temp 15 | # cpu_load_change 16 | # core_load_change 17 | # cpu_load_value=50,90 18 | # cpu_load_color=FFFFFF,FFAA7F,CC0000 19 | # cpu_color=2E97CB 20 | # cpu_text=CPU 21 | # io_color=A491D3 22 | # vram 23 | # vram_color=AD64C1 24 | # ram 25 | # ram_color=C26693 26 | # fps 27 | # engine_color=EB5B5B 28 | # gpu_color=2E9762 29 | # wine_color=EB5B5B 30 | # frame_timing=1 31 | # frametime_color=00FF00 32 | # media_player_color=FFFFFF 33 | # table_columns=3 34 | # background_alpha=0.4 35 | # font_size=19 36 | # 37 | # background_color=020202 38 | # position=top-left 39 | # text_color=FFFFFF 40 | # round_corners=0 41 | # toggle_hud=F1 42 | # toggle_logging=Shift_L+F2 43 | # upload_log=F5 44 | # output_folder=/home/rafael 45 | # media_player_name=spotify 46 | #GOVERLAY_THEME=mangohuddefault 47 | 48 | fps_limit=75 49 | toggle_fps_limit=F2 50 | toggle_hud=F1 51 | toggle_logging=Shift_L+F2 52 | upload_log=F5 53 | background_alpha=0 54 | font_size=17 55 | control=mangohud 56 | fsr_steam_sharpness=5 57 | nis_steam_sharpness=10 58 | legacy_layout=0 59 | horizontal 60 | gpu_stats 61 | gpu_temp 62 | cpu_stats 63 | cpu_temp 64 | ram 65 | fps 66 | frametime=0 67 | hud_no_margin 68 | table_columns=14 69 | frame_timing=1 70 | gamemode 71 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/configs/format.lua: -------------------------------------------------------------------------------- 1 | vim.api.nvim_create_user_command("Format", function(args) 2 | local range = nil 3 | if args.count ~= -1 then 4 | local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1] 5 | range = { 6 | start = { args.line1, 0 }, 7 | ["end"] = { args.line2, end_line:len() }, 8 | } 9 | end 10 | require("conform").format { async = true, lsp_fallback = true, range = range } 11 | end, { range = true }) 12 | 13 | require("conform").setup { 14 | format_on_save = nil, 15 | formatters_by_ft = { 16 | -- Conform will run multiple formatters sequentially 17 | -- python = { "isort", "black" }, 18 | c = { "clang-format" }, 19 | css = { "prettier" }, 20 | go = { "goimports" }, 21 | html = { "prettier" }, 22 | -- Use a sub-list to run only the first available formatter 23 | javascript = { "prettierd", "prettier" }, 24 | javascriptreact = { "prettier" }, 25 | json = { "prettier" }, 26 | lua = { "stylua" }, 27 | markdown = { "prettier" }, 28 | rust = { "rustfmt" }, 29 | sh = { "shfmt" }, 30 | toml = { "taplo" }, 31 | typescript = { "prettier" }, 32 | typescriptreact = { "prettier" }, 33 | zig = { "zigfmt" }, 34 | }, 35 | } 36 | vim.keymap.set({ "n", "v" }, "=", "Format", { desc = "Format buffer" }) 37 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lazy-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "catppuccin": { "branch": "main", "commit": "193e123cdbc4dd3e86db883d55349e9587f0ded6" }, 3 | "chezmoi.vim": { "branch": "main", "commit": "73b30df35c6b645ebd2e6a440eea8463ef3c3f47" }, 4 | "conform.nvim": { "branch": "master", "commit": "ffe26e8df8115c9665d24231f8a49fadb2d611ce" }, 5 | "fzf-lua": { "branch": "main", "commit": "bd69cbae60eeb4589fbd285cb112265530fe1a5e" }, 6 | "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, 7 | "leap.nvim": { "branch": "main", "commit": "af1dedf49efe203b98c65970a6bb652af256b882" }, 8 | "mason.nvim": { "branch": "main", "commit": "57e5a8addb8c71fb063ee4acda466c7cf6ad2800" }, 9 | "mini.nvim": { "branch": "main", "commit": "9087880da9ed1e5b06a28b75b4424fd8218bd189" }, 10 | "nvim-lspconfig": { "branch": "master", "commit": "0044d0987ef7e624d04141d0f90d0481fd3c3663" }, 11 | "nvim-treesitter": { "branch": "main", "commit": "2979e048b356cfd32dc419d5803dc356b9832adf" }, 12 | "nvim-treesitter-endwise": { "branch": "master", "commit": "a61a9de7965324d4019fb1637b66bfacdcb01f51" }, 13 | "nvim-treesitter-textobjects": { "branch": "main", "commit": "76deedf0f1cec4496ef8d49b6d1f020f6d0c6ec9" }, 14 | "nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" }, 15 | "oil.nvim": { "branch": "master", "commit": "cbcb3f997f6f261c577b943ec94e4ef55108dd95" }, 16 | "ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" }, 17 | "undotree": { "branch": "master", "commit": "0f1c9816975b5d7f87d5003a19c53c6fd2ff6f7f" }, 18 | "zk-nvim": { "branch": "main", "commit": "8df80d0dc2d66e53b08740361a600746a6e4edcf" } 19 | } 20 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_ffmpeg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # audio 4 | A="$(pactl list sources | grep 'analog.*monitor' | awk '{print $2}')" 5 | # screen size 6 | S="$(xdpyinfo | grep dimensions | awk '{print $2}')" 7 | # file name 8 | N="$(date +"%m-%d-%Y_%I:%M%p").mov" 9 | 10 | # Desktop audio + screen recording 11 | ffmpeg \ 12 | -s "$S" -r 25 -f x11grab -i :0.0+0,0 \ 13 | -ac 2 ~/"$N" 14 | 15 | # ffmpeg can output high quality GIF. Before you start it is always recommended to use a recent version: download or compile. 16 | 17 | # ffmpeg -ss 30 -t 3 -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif 18 | 19 | # This example will skip the first 30 seconds (-ss 30) of the input and create a 3 second output (-t 3). 20 | # fps filter sets the frame rate. A rate of 10 frames per second is used in the example. 21 | # scale filter will resize the output to 320 pixels wide and automatically determine the height while preserving the aspect ratio. The lanczos scaling algorithm is used in this example. 22 | # palettegen and paletteuse filters will generate and use a custom palette generated from your input. These filters have many options, so refer to the links for a list of all available options and values. Also see the Advanced options section below. 23 | # split filter will allow everything to be done in one command and avoids having to create a temporary PNG file of the palette. 24 | # Control looping with -loop output option but the values are confusing. A value of 0 is infinite looping, -1 is no looping, and 1 will loop once meaning it will play twice. So a value of 10 will cause the GIF to play 11 times. 25 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/executable_irg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # source: https://github.com/junegunn/fzf/blob/master/ADVANCED.md#switching-between-ripgrep-mode-and-fzf-mode-using-a-single-key-binding 4 | # another alternative I saw: https://github.com/potamides/dotfiles/blob/master/.bashrc#L190-L212 5 | # Switch between Ripgrep mode and fzf filtering mode (CTRL-G) 6 | 7 | rm -f /tmp/rg-fzf-{r,f} 8 | RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case --hidden --glob \"!**/.git/**\" " 9 | 10 | # source: https://junegunn.github.io/fzf/tips/ripgrep-integration/#wrap-up 11 | OPENER='if [[ $FZF_SELECT_COUNT -eq 0 ]]; then 12 | $EDITOR {1} +{2} # No selection. Open the current line in Vim. 13 | else 14 | $EDITOR +cw -q {+f} # Build quickfix list for the selected items. 15 | fi' 16 | 17 | INITIAL_QUERY="${*:-}" 18 | : | fzf --ansi --disabled --query "$INITIAL_QUERY" \ 19 | --bind "start:reload:$RG_PREFIX {q}" \ 20 | --bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \ 21 | --bind 'ctrl-g:transform:[[ ! $FZF_PROMPT =~ ripgrep ]] && 22 | echo "rebind(change)+change-prompt(1. ripgrep> )+disable-search+transform-query:echo \{q} > /tmp/rg-fzf-f; cat /tmp/rg-fzf-r" || 23 | echo "unbind(change)+change-prompt(2. fzf> )+enable-search+transform-query:echo \{q} > /tmp/rg-fzf-r; cat /tmp/rg-fzf-f"' \ 24 | --color "hl:-1:underline,hl+:-1:underline:reverse" \ 25 | --prompt '1. ripgrep> ' \ 26 | --delimiter : \ 27 | --header 'CTRL-G: Switch between ripgrep/fzf' \ 28 | --preview 'bat --color=always {1} --highlight-line {2}' \ 29 | --preview-window 'up,50%,border-bottom,+{2}+3/3,~3' \ 30 | --bind "enter:become:$OPENER" 31 | -------------------------------------------------------------------------------- /private_dot_config/alacritty/alacritty.toml: -------------------------------------------------------------------------------- 1 | general.import = ["~/.config/alacritty/themes/vesper.toml"] 2 | 3 | [font] 4 | size = 12 5 | 6 | [font.normal] 7 | # family = "0xProto" 8 | family = "CommitMono" 9 | # family = "Cascadia Mono" 10 | # family = "JetBrains Mono" 11 | # family = "Fira Code" 12 | # family = "Hack" 13 | # family = "Source Code Pro" 14 | # family = "Maple Mono" 15 | style = "Regular" 16 | 17 | [font.bold] 18 | style = "Bold" 19 | 20 | [font.italic] 21 | style = "Italic" 22 | # style = "Bold Italic" 23 | # family = "VictorMono Nerd Font" 24 | 25 | [font.bold_italic] 26 | style = "Bold Italic" 27 | 28 | [window] 29 | # opacity = 0.9 30 | startup_mode = "Maximized" 31 | 32 | [terminal.shell] 33 | program = "restore-tmux" 34 | 35 | [mouse] 36 | hide_when_typing = true 37 | 38 | # https://github.com/alacritty/alacritty/issues/6156#issuecomment-1924172603 39 | [env] 40 | TERM = "xterm-256color" 41 | 42 | [[hints.enabled]] 43 | command = "xdg-open" # On Linux/BSD 44 | # command = "open" # On macOS 45 | # command = { program = "cmd", args = [ "/c", "start", "" ] } # On Windows 46 | hyperlinks = true 47 | post_processing = true 48 | persist = false 49 | mouse.enabled = true 50 | binding = { key = "U", mods = "Control|Shift" } 51 | regex = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\u0000-\u001F\u007F-\u009F<>\"\\s{-}\\^⟨⟩`]+" 52 | 53 | [[hints.enabled]] 54 | regex = "[a-f0-9]{40}|[a-f0-9]{7,8}" 55 | binding = { key = "H", mods = "Control|Shift" } 56 | action = "Copy" 57 | 58 | [[hints.enabled]] 59 | regex = ''''(/?[^/ \t\"']*[a-zA-Z0-9][^/ \t\"':]*/([^/ \t\"']+/?)*)\ 60 | |(/[^/ \t\"']*[a-zA-Z0-9][^/ \t\"']*)''' 61 | action = "Copy" 62 | hyperlinks = true 63 | binding = { key = "E", mods = "Control|Shift" } 64 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/cron/checkup.md: -------------------------------------------------------------------------------- 1 | # Checkup 2 | 3 | Since we are using `notify-send`, adding `checkup` to the cronjob of root user 4 | is not recommended, graphical notifications rely on access to the user's session 5 | D-Bus and display ($DISPLAY) environment. Root does not naturally inherit these 6 | variables, causing errors like "Broken pipe." and also you run into a bunch of 7 | others problems and security risks if you try to run GUI's with root access. 8 | 9 | So in order for the script to work properly, execute it as your user, but it 10 | needs to run pacman,paru,etc as sudo without password requirement. 11 | 12 | Archlinux installation script creates the wheel group, users in that group 13 | can run any command, although it depends of the distro, some distros may do 14 | `admin` for example. Run `sudo visudo` and un-comment: 15 | 16 | ``` 17 | # %wheel ALL=(ALL:ALL) NOPASSWD: ALL 18 | ``` 19 | 20 | Then of course add your user to the wheel group `usermod -aG wheel youruser` 21 | (most likely it is part of that group if you choose to have your user as an 22 | admin during installation) 23 | 24 | However, `sudo visudo` and changing that line might don't do anything if you 25 | have, `/etc/sudoers.d/00_youruser`, rules in that file take precedence over 26 | `/etc/sudoers`, which is what `sudo visudo` modifies. And also I don't want to 27 | be able to run any command without password, in case I'm doing something 28 | potentially dangerous, being prompt for a password is like a reminder to be 29 | careful with what you do, I just want to run pacman and an AUR helper without 30 | password. For that: 31 | 32 | ``` 33 | youruser ALL=(ALL) ALL, NOPASSWD: /usr/bin/pacman, /usr/bin/paru 34 | ``` 35 | 36 | It can go in `/etc/sudoers`, but if you have `/etc/sudoers.d/00_youruser` then 37 | put it there. 38 | -------------------------------------------------------------------------------- /private_dot_config/kitty/symbols-map.conf: -------------------------------------------------------------------------------- 1 | # sources: 2 | # https://erwin.co/kitty-and-nerd-fonts/ 3 | # https://www.youtube.com/watch?v=mQdB_kHyZn8 4 | # 5 | # Link to download nerds fonts symbols only: 6 | # https://github.com/ryanoasis/nerd-fonts/releases/download/v2.3.3/NerdFontsSymbolsOnly.zip 7 | 8 | ########################################################### 9 | # Symbols Nerd Font complete symbol_map 10 | # easily troubleshoot missing/incorrect characters with: 11 | # kitty --debug-font-fallback 12 | ########################################################### 13 | 14 | # "Nerd Fonts - Pomicons" 15 | symbol_map U+E000-U+E00D Symbols Nerd Font 16 | 17 | # "Nerd Fonts - Powerline" 18 | symbol_map U+e0a0-U+e0a2,U+e0b0-U+e0b3 Symbols Nerd Font 19 | 20 | # "Nerd Fonts - Powerline Extra" 21 | symbol_map U+e0a3-U+e0a3,U+e0b4-U+e0c8,U+e0cc-U+e0d2,U+e0d4-U+e0d4 Symbols Nerd Font 22 | 23 | # "Nerd Fonts - Symbols original" 24 | symbol_map U+e5fa-U+e62b Symbols Nerd Font 25 | 26 | # "Nerd Fonts - Devicons" 27 | symbol_map U+e700-U+e7c5 Symbols Nerd Font 28 | 29 | # "Nerd Fonts - Font awesome" 30 | symbol_map U+f000-U+f2e0 Symbols Nerd Font 31 | 32 | # "Nerd Fonts - Font awesome extension" 33 | symbol_map U+e200-U+e2a9 Symbols Nerd Font 34 | 35 | # "Nerd Fonts - Octicons" 36 | symbol_map U+f400-U+f4a8,U+2665-U+2665,U+26A1-U+26A1,U+f27c-U+f27c Symbols Nerd Font 37 | 38 | # "Nerd Fonts - Font Linux" 39 | symbol_map U+F300-U+F313 Symbols Nerd Font 40 | 41 | # Nerd Fonts - Font Power Symbols" 42 | symbol_map U+23fb-U+23fe,U+2b58-U+2b58 Symbols Nerd Font 43 | 44 | # "Nerd Fonts - Material Design Icons" 45 | symbol_map U+f500-U+fd46 Symbols Nerd Font 46 | 47 | # "Nerd Fonts - Weather Icons" 48 | symbol_map U+e300-U+e3eb Symbols Nerd Font 49 | 50 | # Misc Code Point Fixes 51 | symbol_map U+21B5,U+25B8,U+2605,U+2630,U+2632,U+2714,U+E0A3,U+E615,U+E62B Symbols Nerd Font 52 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/configs/oil.lua: -------------------------------------------------------------------------------- 1 | local oil = require "oil" 2 | 3 | oil.setup { 4 | default_file_explorer = true, 5 | delete_to_trash = true, 6 | columns = { 7 | "icon", 8 | -- "permissions", 9 | "size", 10 | "mtime", 11 | }, 12 | view_options = { 13 | show_hidden = true, 14 | }, 15 | keymaps = { 16 | [""] = false, 17 | ["yp"] = { 18 | -- source: https://www.reddit.com/r/neovim/comments/1czp9zr/comment/l5hv900/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button 19 | desc = "Copy filepath to system clipboard", 20 | callback = function() 21 | require("oil.actions").copy_entry_path.callback() 22 | local copied = vim.fn.getreg(vim.v.register) 23 | vim.fn.setreg("+", copied) 24 | vim.notify("Copied to system clipboard:\n" .. copied, vim.log.levels.INFO, {}) 25 | end, 26 | }, 27 | ["g:"] = { 28 | -- source: https://github.com/stevearc/oil.nvim/pull/318 29 | desc = "Run shell command on file under cursor", 30 | callback = function() 31 | vim.ui.input({ prompt = "command: ", completion = "shellcmd" }, function(input) 32 | if input == "" or input == nil then 33 | return 34 | end 35 | local file_path = oil.get_current_dir() .. oil.get_cursor_entry().name 36 | if file_path == "" or file_path == nil then 37 | return 38 | end 39 | vim.api.nvim_command(":! " .. input .. ' "' .. file_path .. '"') 40 | end) 41 | end, 42 | }, 43 | }, 44 | } 45 | vim.keymap.set("n", "e", ":Oil", { desc = "file explorer" }) 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > There's no place like ~/ 2 | 3 | ## Dependencies 4 | 5 | - [keyd](https://github.com/rvaiya/keyd) >= 2 6 | - [neovim](https://github.com/neovim/neovim) >= 0.10.0 7 | - [fzf](https://github.com/junegunn/fzf) >= 0.48.0 8 | - [alacritty](https://github.com/alacritty/alacritty) >= 0.13.0 9 | - [tmux](https://github.com/tmux/tmux) >= 3.4 10 | - [zsh](https://wiki.archlinux.org/title/zsh) 11 | - [chezmoi](https://www.chezmoi.io/) 12 | - [zk](https://github.com/zk-org/zk) 13 | - [ripgrep](https://github.com/BurntSushi/ripgrep) 14 | - [bat](https://github.com/sharkdp/bat) 15 | - [fd](https://github.com/sharkdp/fd) 16 | - [lazygit](https://github.com/jesseduffield/lazygit) 17 | - [delta](https://github.com/dandavison/delta) 18 | 19 | ## Others 20 | 21 | - [age](https://github.com/FiloSottile/age) 22 | - [jq](https://stedolan.github.io/jq/) 23 | - [fq](https://github.com/wader/fq) 24 | - [obsidian](https://obsidian.md/) 25 | - [pipe-rename](https://github.com/marcusbuffett/pipe-rename) 26 | - [fastfetch](https://github.com/fastfetch-cli/fastfetch) 27 | - [jujutsu](https://github.com/martinvonz/jj) 28 | - [rsync](https://rsync.samba.org/) 29 | - [sd](https://github.com/chmln/sd) 30 | - [syncthing](https://syncthing.net/) 31 | - [tldr](https://github.com/tldr-pages/tldr-python-client) 32 | - [vis](https://github.com/martanne/vis#vis-a-vim-like-text-editor) 33 | - [yazi](https://github.com/sxyazi/yazi) 34 | - [yt-dlp](https://github.com/yt-dlp/yt-dlp) 35 | - [zellij](https://zellij.dev) 36 | - [localsend](https://localsend.org/) 37 | - [tokei](https://github.com/XAMPPRocky/tokei) 38 | - [czkawka](https://github.com/qarmin/czkawka) 39 | 40 | ## Fonts 41 | 42 | - [JetBrains Mono](https://jetbrains.com/lp/mono) 43 | - [Cascadia Code](https://github.com/microsoft/cascadia-code) 44 | - [Fira Code](https://github.com/tonsky/FiraCode) 45 | - [Hack](https://sourcefoundry.org/hack) 46 | - [Lato](https://www.latofonts.com/) 47 | - [Ubuntu](https://design.ubuntu.com/font/) 48 | -------------------------------------------------------------------------------- /private_dot_config/mpv/script-opts/encode_webm.conf: -------------------------------------------------------------------------------- 1 | # if yes, only encode the currently active tracks 2 | # for example, mute the player / hide the subtitles if you don't want audio / subs to be part of the extract 3 | only_active_tracks=no 4 | 5 | # whether to preserve some of the applied filters (crop, rotate, flip and mirror) into the extract 6 | # this is pretty useful in combination with crop.lua 7 | # note that you cannot copy video streams and apply filters at the same time 8 | preserve_filters=yes 9 | 10 | # apply another filter after the ones from the previous option if any 11 | # can be used to limit the resolution of the output, for example with 12 | # append_filter=scale=2*trunc(iw/max(1\,sqrt((iw*ih)/(960*540)))/2):-2 13 | append_filter= 14 | 15 | # additional parameters passed to ffmpeg 16 | codec=-an -sn -c:v libvpx -crf 10 -b:v 1000k 17 | 18 | # format of the output filename 19 | # Does basic interpolation on the following variables: $f, $x, $t, $s, $e, $d, $p, $n which respectively represent 20 | # input filename, input extension, title, start timestamp, end timestamp, duration, profile name and an incrementing number in case of conflicts 21 | # if the extension is not among the recognized ones, it will default to mkv 22 | output_format=$f_$n.webm 23 | 24 | # the directory in which to create the extract 25 | # empty means the same directory as the input file 26 | # relative paths are relative to mpv's working directory, absolute ones work like you would expect 27 | output_directory= 28 | 29 | # if yes, the ffmpeg process will run detached from mpv and we won't know if it succeeded or not 30 | # if no, we know the result of calling ffmpeg, but we can only encode one extract at a time and mpv will block on exit 31 | detached=yes 32 | 33 | # executable to run when encoding (or its full path if not in PATH) 34 | # for example, this can be used with a wrapper script that calls ffmpeg and triggers a notification when finished 35 | # note that the executable gets the ffmpeg arguments as-is, and is expected to call ffmpeg itself 36 | ffmpeg_command=ffmpeg 37 | 38 | # if yes, print the ffmpeg call before executing it 39 | print=yes 40 | -------------------------------------------------------------------------------- /dot_bashrc: -------------------------------------------------------------------------------- 1 | # Increase history size 2 | export HISTSIZE=50000 3 | export HISTFILESIZE=1000000 4 | 5 | # Change location of history file 6 | if [ ! -d "${XDG_DATA_HOME:-$HOME/.local/share}"/bash ]; then 7 | mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}"/bash 8 | fi 9 | export HISTFILE="${XDG_DATA_HOME:-$HOME/.local/share}"/bash/history 10 | 11 | # Save command with current directory appended as a comment 12 | export PROMPT_COMMAND=' 13 | history -a; # Append the command to the history file 14 | history -r; # Read the updated history file 15 | ' 16 | # Options 17 | # ignoredups: Stop logging of consecutive identical commands 18 | # ignorespace: avoid saving commands that start with a space 19 | export HISTCONTROL="ignoredups:ignorespace" 20 | export HISTTIMEFORMAT="%F %T " # History timestamps 21 | shopt -s histappend # append to the history file, don't overwrite it 22 | shopt -s checkwinsize # checks the window size after each command and, if necessary, updates the values of LINES and COLUMNS 23 | 24 | if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc" ]; then 25 | source "${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc" 26 | fi 27 | 28 | # Use fzf-tab-completion: https://github.com/lincheney/fzf-tab-completion 29 | # Install bash-completion via package manager (e.g., apt, yum, pacman) 30 | # bash-completion: https://github.com/scop/bash-completion/ 31 | if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}"/bash/fzf-tab-completion ]; then 32 | source "${XDG_CONFIG_HOME:-$HOME/.config}/bash/fzf-tab-completion" 33 | bind -x '"\t": fzf_bash_completion' 34 | export FZF_COMPLETION_AUTO_COMMON_PREFIX=true 35 | export FZF_COMPLETION_AUTO_COMMON_PREFIX_PART=true 36 | fi 37 | 38 | if [ -x "$(command -v fzf)" ]; then 39 | eval "$(fzf --bash)" 40 | fi 41 | 42 | # Allows you to see repository status in your prompt. 43 | if [ -f /usr/share/git/git-prompt.sh ]; then 44 | source /usr/share/git/git-prompt.sh 45 | fi 46 | 47 | # Generated with: https://bash-prompt-generator.org/ 48 | PROMPT_COMMAND='PS1_CMD1=$(command -v __git_ps1 >/dev/null 2>&1 && __git_ps1 " (%s)")'; PS1='\n\[\e[38;5;69m\]\u\[\e[0m\]@\[\e[38;5;195m\]\h\[\e[0m\] \[\e[1m\]\w\[\e[0;38;5;225;3m\]${PS1_CMD1}\[\e[0m\] \[\e[2m\]\t\[\e[0m\] [\[\e[38;5;167;2m\]$?\[\e[0m\]]\n\$ ' 49 | -------------------------------------------------------------------------------- /private_dot_config/mpv/scripts/blacklist-extensions.lua: -------------------------------------------------------------------------------- 1 | opts = { 2 | blacklist="", 3 | whitelist="", 4 | remove_files_without_extension = false, 5 | oneshot = true, 6 | } 7 | (require 'mp.options').read_options(opts) 8 | local msg = require 'mp.msg' 9 | 10 | function split(input) 11 | local ret = {} 12 | for str in string.gmatch(input, "([^,]+)") do 13 | ret[#ret + 1] = str 14 | end 15 | return ret 16 | end 17 | 18 | opts.blacklist = split(opts.blacklist) 19 | opts.whitelist = split(opts.whitelist) 20 | 21 | local exclude 22 | if #opts.whitelist > 0 then 23 | exclude = function(extension) 24 | for _, ext in pairs(opts.whitelist) do 25 | if extension == ext then 26 | return false 27 | end 28 | end 29 | return true 30 | end 31 | elseif #opts.blacklist > 0 then 32 | exclude = function(extension) 33 | for _, ext in pairs(opts.blacklist) do 34 | if extension == ext then 35 | return true 36 | end 37 | end 38 | return false 39 | end 40 | else 41 | return 42 | end 43 | 44 | function should_remove(filename) 45 | if string.find(filename, "://") then 46 | return false 47 | end 48 | local extension = string.match(filename, "%.([^./]+)$") 49 | if not extension and opts.remove_file_without_extension then 50 | return true 51 | end 52 | if extension and exclude(string.lower(extension)) then 53 | return true 54 | end 55 | return false 56 | end 57 | 58 | function process(playlist_count) 59 | if playlist_count < 2 then return end 60 | if opts.oneshot then 61 | mp.unobserve_property(observe) 62 | end 63 | local playlist = mp.get_property_native("playlist") 64 | local removed = 0 65 | for i = #playlist, 1, -1 do 66 | if should_remove(playlist[i].filename) then 67 | mp.commandv("playlist-remove", i-1) 68 | removed = removed + 1 69 | end 70 | end 71 | if removed == #playlist then 72 | msg.warn("Removed eveything from the playlist") 73 | end 74 | end 75 | 76 | function observe(k,v) process(v) end 77 | 78 | mp.observe_property("playlist-count", "number", observe) 79 | -------------------------------------------------------------------------------- /private_dot_config/git/gitmessage: -------------------------------------------------------------------------------- 1 | 2 | # ([optional scope]): 3 | # 4 | # [optional body] 5 | # 6 | # [optional footer(s)] 7 | 8 | # {{{ Type 9 | # type 10 | # build: Changes that affect the build system or external dependencies 11 | # chore: Other changes that don't modify src or test files 12 | # ci: Changes to our CI configuration files and scripts 13 | # deprecate: Deprecates existing functionality, but does not remove it from the product. Giving time before removing it 14 | # docs: Documentation only changes 15 | # feat: A new feature 16 | # fix: A bug fix 17 | # perf: A code change that improves performance 18 | # refactor: A code change that neither fixes a bug nor adds a feature 19 | # revert: Reverts a previous commit 20 | # security: Improves the security of the product or resolves a security issue that has been reported 21 | # style: Changes that do not affect the meaning of the code 22 | # test: Adding missing or correcting existing tests 23 | # }}} 24 | 25 | # {{{ Optional scope 26 | # optional scope 27 | # init: Initialize commit 28 | # security: Security to invite users to upgrade in case of vulnerabilities 29 | # deps: Dependencies upgrading or downgrading 30 | # config: Configuration changes 31 | # i18n: Internationalization and localization 32 | # ... 33 | # }}} 34 | 35 | # {{{ Description 36 | # description: short summary 37 | # - Do not end with a period 38 | # - Not cased 39 | # - Start writing in lower case 40 | # - 50 chars or less 41 | # - Use the imperative mood 42 | # }}} 43 | 44 | # {{{ Optional body 45 | # optional body: Explain why this change is being made. 46 | # - Wrap it to about 72 characters or so 47 | # - Can use multiple lines with "-" for bullet points 48 | # - Explain what and why vs. how 49 | # }}} 50 | 51 | # {{{ Optional footers 52 | # optional footer(s): Provide links or keys to any relevant tickets 53 | # - Wrap it to about 72 characters or so 54 | # Linking a pull request to an issue using a keyword 55 | # - close #ISSUE-NUMBER 56 | # - fix #ISSUE-NUMBER 57 | # - resolve #ISSUE-NUMBER 58 | # }}} 59 | 60 | # {{{ Misc 61 | # Examples 62 | # https://www.conventionalcommits.org/en/v1.0.0-beta.2/#examples 63 | # Full specification 64 | # https://www.conventionalcommits.org/en/v1.0.0-beta.2/#specification 65 | # }}} 66 | -------------------------------------------------------------------------------- /private_dot_config/nvim/plugin/bigfile.lua: -------------------------------------------------------------------------------- 1 | -- Taken from snacks' bigfile but with some modifcations to make simplier 2 | -- https://github.com/folke/snacks.nvim/blob/main/lua/snacks/bigfile.lua 3 | vim.filetype.add { 4 | pattern = { 5 | [".*"] = { 6 | function(path, buf) 7 | if not path or not buf or vim.bo[buf].filetype == "bigfile" then 8 | return 9 | end 10 | if path ~= vim.fs.normalize(vim.api.nvim_buf_get_name(buf)) then 11 | return 12 | end 13 | local size = vim.fn.getfsize(path) 14 | if size <= 0 then 15 | return 16 | end 17 | local size_limit = 1.5 * 1024 * 1024 -- 1.5MB 18 | if size > size_limit then 19 | return "bigfile" 20 | end 21 | local lines = vim.api.nvim_buf_line_count(buf) 22 | local line_length = 1000 -- average line length (useful for minified files) 23 | return (size - lines) / lines > line_length and "bigfile" or nil 24 | end, 25 | }, 26 | }, 27 | } 28 | 29 | vim.api.nvim_create_autocmd({ "FileType" }, { 30 | group = vim.api.nvim_create_augroup("Bigfile", { clear = true }), 31 | pattern = "bigfile", 32 | callback = function(ev) 33 | vim.api.nvim_buf_call(ev.buf, function() 34 | if vim.fn.exists ":NoMatchParen" ~= 0 then 35 | vim.cmd [[NoMatchParen]] 36 | end 37 | vim.opt_local.foldmethod = "manual" 38 | vim.opt_local.undolevels = 50 39 | vim.opt_local.statuscolumn = "" 40 | vim.opt_local.relativenumber = false 41 | vim.opt_local.conceallevel = 0 42 | vim.b.minianimate_disable = true 43 | vim.b.minihipatterns_disable = true 44 | 45 | vim.schedule(function() 46 | -- NOTE: We don't need to explicitly disable treesitter because the filetype is being 47 | -- set to "bigfile" in the filetype.add function above. Which automatically disables 48 | -- treesitter because there are no parsers for files of type "bigfile" 49 | if vim.api.nvim_buf_is_valid(ev.buf) then 50 | vim.bo[ev.buf].syntax = vim.filetype.match { buf = ev.buf } or "" 51 | end 52 | end) 53 | end) 54 | end, 55 | }) 56 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/git/executable_git-browse: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # From git-extras 4 | # source: https://github.com/tj/git-extras/blob/main/bin/git-browse 5 | # homepage: https://github.com/tj/git-extras 6 | 7 | remote=${1:-""} 8 | branch="" 9 | filename=${2:-""} 10 | line1=${3:-""} 11 | line2=${4:-""} 12 | 13 | # get remote name 14 | if [[ $remote == "" ]]; then 15 | branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)" 16 | remote=$(git config branch."${branch}".remote || echo "origin") 17 | fi 18 | 19 | if [[ $remote == "" ]]; then 20 | echo "Remote not found" 21 | exit 1 22 | fi 23 | 24 | remote_url=$(git remote get-url "$remote") || exit $? 25 | 26 | if [[ $remote_url = git@* ]]; then 27 | url=$(echo "$remote_url" | sed -E -e 's/:/\//' -e 's/\.git$//' -e 's/.*@(.*)/http:\/\/\1/') 28 | elif [[ $remote_url = http* ]]; then 29 | url=${remote_url%.git} 30 | fi 31 | 32 | # construct urls 33 | commit_hash=$(git rev-parse HEAD 2>/dev/null) 34 | commit_or_branch=${commit_hash:-${branch}} 35 | 36 | if [[ $remote_url =~ gitlab ]]; then 37 | # construct gitlab urls 38 | # https://gitlab.com///-/blob//#L- 39 | if [[ -n ${filename} ]]; then 40 | url="${url}/-/blob/${commit_or_branch}/${filename}" 41 | if [[ -n "${line1}" ]]; then 42 | url="${url}#L${line1}" 43 | if [[ -n "${line2}" ]]; then 44 | url="${url}-${line2}" 45 | fi 46 | fi 47 | fi 48 | elif [[ $remote_url =~ github ]]; then 49 | # construct github urls 50 | # https://github.com///blob//#L-L 51 | if [[ -n "${filename}" ]]; then 52 | url="${url}/blob/${commit_or_branch}/${filename}" 53 | if [[ -n "${line1}" ]]; then 54 | url="${url}#L${line1}" 55 | if [[ -n "${line2}" ]]; then 56 | url="${url}-L${line2}" 57 | fi 58 | fi 59 | fi 60 | elif [[ $remote_url =~ bitbucket ]]; then 61 | # construct bitbucket urls 62 | # https://bitbucket.org///src//#lines-: 63 | if [[ -n ${filename} ]]; then 64 | url=${url}/src/${commit_or_branch}/${filename} 65 | if [[ -n "${line1}" ]]; then 66 | url="${url}#lines-${line1}" 67 | if [[ -n "${line2}" ]]; then 68 | url="${url}:${line2}" 69 | fi 70 | fi 71 | fi 72 | fi 73 | 74 | # open url 75 | case "$OSTYPE" in 76 | darwin*) 77 | # MacOS 78 | open "$url" 79 | ;; 80 | msys) 81 | # Git-Bash on Windows 82 | start "$url" 83 | ;; 84 | linux*) 85 | # Handle WSL on Windows 86 | if uname -a | grep -i -q Microsoft && command -v powershell.exe; then 87 | powershell.exe -NoProfile start "$url" 88 | else 89 | xdg-open "$url" 90 | fi 91 | ;; 92 | *) 93 | # fall back to xdg-open for BSDs, etc. 94 | xdg-open "$url" 95 | ;; 96 | esac 97 | -------------------------------------------------------------------------------- /private_dot_config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | # Fonts 2 | include ./symbols-map.conf 3 | 4 | font_family JetBrains Mono 5 | # font_family Cascadia Code 6 | # font_family Fira Code 7 | # font_family Hack 8 | # font_family Source Code Pro 9 | 10 | font_size 11.5 11 | # options: never, always, cursor 12 | disable_ligatures always 13 | 14 | # ========================================================= 15 | # Settings 16 | enabled_layouts tall, stack, horizontal 17 | update_check_interval 0 18 | enable_audio_bell no 19 | allow_remote_control yes 20 | strip_trailing_spaces smart 21 | mouse_hide_wait 3.0 22 | open_url_with default 23 | copy_on_select yes 24 | sync_to_monitor yes 25 | inactive_text_alpha 0.9 26 | linux_display_server auto 27 | scrollback_pager ~/.config/kitty/scrollback_pager.sh 'INPUT_LINE_NUMBER' 'CURSOR_LINE' 'CURSOR_COLUMN' 28 | 29 | # UI 30 | tab_bar_style powerline 31 | tab_powerline_style slanted 32 | tab_title_template "({layout_name[:3].upper()}) {index}:{fmt.bold}{fmt.italic}{tab.active_oldest_exe}" 33 | 34 | # ========================================================= 35 | # Maps 36 | kitty_mod ctrl+shift 37 | 38 | # Some useful default keymaps I always forget: 39 | # Insert selected path 40 | map ctrl+shift+p>f kitten hints --type path --program - 41 | # Insert selected line 42 | map ctrl+shift+p>l kitten hints --type line --program - 43 | # Insert selected word 44 | map ctrl+shift+p>w kitten hints --type word --program - 45 | # Insert selected hash 46 | map ctrl+shift+p>h kitten hints --type hash --program - 47 | # Insert selected url 48 | map ctrl+shift+p>u kitten hints --type url --program - 49 | # Reload config 50 | map ctrl+shift+f5 load_config_file 51 | 52 | # Tabs 53 | map kitty_mod+t new_tab_with_cwd 54 | map kitty_mod+g new_tab_with_cwd lazygit 55 | map kitty_mod+o show_last_command_output 56 | map kitty_mod+1 goto_tab 1 57 | map kitty_mod+2 goto_tab 2 58 | map kitty_mod+3 goto_tab 3 59 | map kitty_mod+4 goto_tab 4 60 | map kitty_mod+] next_tab 61 | map kitty_mod+[ previous_tab 62 | 63 | # windows 64 | map kitty_mod+enter new_window_with_cwd 65 | map kitty_mod+r start_resizing_window 66 | map kitty_mod+w close_window 67 | map kitty_mod+] next_window 68 | map kitty_mod+[ previous_window 69 | # map kitty_mod+l move_window_forward 70 | # map kitty_mod+h move_window_backward 71 | 72 | # layouts 73 | map ctrl+alt+t goto_layout tall 74 | map ctrl+alt+s goto_layout stack 75 | map ctrl+alt+h goto_layout horizontal 76 | 77 | # ========================================================= 78 | 79 | # Theme 80 | background_opacity 1 81 | 82 | 83 | # BEGIN_KITTY_THEME 84 | # Gruvbox Material Dark Medium 85 | include current-theme.conf 86 | # END_KITTY_THEME 87 | -------------------------------------------------------------------------------- /private_dot_config/ghostty/config: -------------------------------------------------------------------------------- 1 | theme = light:Dayfox,dark:Catppuccin Mocha 2 | # font-family = "CommitMono" 3 | font-family = "0xProto" 4 | # font-family = "Cascadia Mono" 5 | # font-family = "JetBrains Mono" 6 | # font-family = "Fira Code" 7 | # font-family = "Hack" 8 | # font-family = "Source Code Pro" 9 | # font-family = "Maple Mono" 10 | 11 | mouse-hide-while-typing = true 12 | maximize = true 13 | 14 | command = /usr/bin/env zsh --login -c "if [ -x "$(command -v tmux)" ] && [ -n "${DISPLAY}" ] && [ -z "${TMUX}" ]; then tmux new-session -A -s main >/dev/null 2>&1; fi" 15 | 16 | # don't confirm when closing window/terminal 17 | confirm-close-surface = false 18 | 19 | # disable all ligatures 20 | font-feature = -liga 21 | font-feature = -calt 22 | font-feature = -dlig 23 | 24 | # keep Ghostty running all the time so that new window creation will always be fast 25 | # Better if used with systemd: systemctl enable --user app-com.mitchellh.ghostty.service 26 | # https://ghostty.org/docs/linux/systemd 27 | quit-after-last-window-closed = false 28 | 29 | shell-integration = zsh 30 | 31 | # only works on macos 32 | # keybind = global:ctrl+shift+]=toggle_quick_terminal 33 | 34 | # custom-shader = shaders/animated-gradient-shader.glsl 35 | # custom-shader = shaders/bettercrt.glsl 36 | # custom-shader = shaders/bloom.glsl 37 | # custom-shader = shaders/bloom1.glsl 38 | # custom-shader = shaders/bloom075.glsl 39 | # custom-shader = shaders/bloom060.glsl 40 | # custom-shader = shaders/bloom050.glsl 41 | # custom-shader = shaders/bloom025.glsl 42 | # custom-shader = shaders/bloom050.glsl 43 | # custom-shader = shaders/bloom060.glsl 44 | # custom-shader = shaders/bloom075.glsl 45 | # custom-shader = shaders/bloom1.glsl 46 | # custom-shader = shaders/crt.glsl 47 | # custom-shader = shaders/cubes.glsl 48 | # custom-shader = shaders/dither.glsl 49 | # custom-shader = shaders/drunkard.glsl 50 | # custom-shader = shaders/fireworks-rockets.glsl 51 | # custom-shader = shaders/fireworks.glsl 52 | # custom-shader = shaders/gears-and-belts.glsl 53 | # custom-shader = shaders/glitchy.glsl 54 | # custom-shader = shaders/glow-rgbsplit-twitchy.glsl 55 | # custom-shader = shaders/gradient-background.glsl 56 | # custom-shader = shaders/inside-the-matrix.glsl 57 | # custom-shader = shaders/just-snow.glsl 58 | # custom-shader = shaders/matrix-hallway.glsl 59 | # custom-shader = shaders/negative.glsl 60 | # custom-shader = shaders/retro-terminal.glsl 61 | # custom-shader = shaders/smoke-and-ghost.glsl 62 | # custom-shader = shaders/sparks-from-fire.glsl 63 | # custom-shader = shaders/spotlight.glsl 64 | # custom-shader = shaders/starfield-colors.glsl 65 | # custom-shader = shaders/starfield.glsl 66 | # custom-shader = shaders/tft.glsl 67 | # custom-shader = shaders/underwater.glsl 68 | # custom-shader = shaders/water.glsl 69 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/git/executable_git-ignore: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # From git-extras 4 | # source: https://github.com/tj/git-extras/blob/master/bin/git-ignore 5 | 6 | : ${GIT_DIR:=$(git rev-parse --git-dir)} 7 | 8 | function show_contents { 9 | local file="${2/#~/$HOME}" 10 | if [ -f "$file" ]; then 11 | echo "$1 gitignore: $2" && cat "$file" 12 | else 13 | echo "There is no $1 .gitignore yet" 14 | fi 15 | } 16 | 17 | function global_ignore() { 18 | git config --global core.excludesFile || \ 19 | ([ -n "$XDG_CONFIG_HOME" ] && echo "$XDG_CONFIG_HOME/git/ignore") || \ 20 | echo "$HOME/.config/git/ignore" 21 | } 22 | 23 | function show_global { 24 | show_contents Global "$(global_ignore)" 25 | } 26 | 27 | function add_global { 28 | local global_gitignore="$(global_ignore)" 29 | if [ -z "$global_gitignore" ]; then 30 | echo "Can't find global .gitignore." 31 | echo "" 32 | echo "Use 'git config --global --add core.excludesfile ~/.gitignore-global' to set the path to your global gitignore file to '~/.gitignore-global'." 33 | echo "" 34 | else 35 | add_patterns "$global_gitignore" "$@" 36 | fi 37 | } 38 | 39 | function show_local { 40 | cd "$(git root)" 41 | show_contents Local .gitignore 42 | } 43 | 44 | function add_local { 45 | cd "$(git root)" 46 | add_patterns .gitignore "$@" 47 | } 48 | 49 | function show_private { 50 | cd "$(git root)" 51 | show_contents Private "${GIT_DIR}/info/exclude" 52 | } 53 | 54 | function add_private { 55 | cd "$(git root)" 56 | test -d "${GIT_DIR}/info" || mkdir -p "${GIT_DIR}/info" 57 | add_patterns "${GIT_DIR}/info/exclude" "$@" 58 | } 59 | 60 | function add_patterns { 61 | echo "Adding pattern(s) to: $1" 62 | local file="${1/#~/$HOME}" 63 | dir_name=$(dirname "$file") 64 | if [ ! -d "$dir_name" ]; then 65 | mkdir -p "$dir_name" 66 | fi 67 | if [ -s "$file" ]; then 68 | # If the content of $file doesn't end with a newline, add one 69 | test "$(tail -c 1 "$file")" != "" && echo "" >> "$file" 70 | fi 71 | for pattern in "${@:2}"; do 72 | echo "... adding '$pattern'" 73 | (test -f "$file" && test "$pattern" && grep -q -F -x -- "$pattern" "$file") || echo "$pattern" >> "$file" 74 | done 75 | } 76 | 77 | if test $# -eq 0; then 78 | show_global 79 | echo "---------------------------------" 80 | show_local 81 | echo "---------------------------------" 82 | show_private 83 | else 84 | case "$1" in 85 | -l|--local) 86 | test $# -gt 1 && add_local "${@:2}" && echo 87 | show_local 88 | ;; 89 | -g|--global) 90 | test $# -gt 1 && add_global "${@:2}" && echo 91 | show_global 92 | ;; 93 | -p|--private) 94 | test $# -gt 1 && add_private "${@:2}" && echo 95 | show_private 96 | ;; 97 | *) 98 | add_local "$@" 99 | ;; 100 | esac 101 | fi 102 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/git/executable_git-sync: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # From git-extras 4 | # source: https://github.com/tj/git-extras/blob/master/bin/git-sync 5 | 6 | function _usage() { 7 | local command="git sync" 8 | cat < ] 11 | ${command} -h | --help 12 | ${command} -s | --soft 13 | ${command} -f | --force 14 | 15 | Sync local branch with /. 16 | When and are not specified on the command line, upstream of local branch will be used by default. 17 | All changes and untracked files and directories will be removed unless you add -s(--soft). 18 | 19 | Examples: 20 | Sync with upstream of local branch: 21 | ${command} 22 | 23 | Sync with origin/master: 24 | ${command} origin master 25 | 26 | Sync without cleaning untracked files: 27 | ${command} -s 28 | 29 | Sync without interaction: 30 | ${command} -f 31 | EOS 32 | } 33 | 34 | function main() { 35 | while [ "$1" != "" ]; do 36 | case $1 in 37 | -h | --help) 38 | _usage 39 | exit 40 | ;; 41 | -s | --soft) 42 | local soft="true" 43 | ;; 44 | -f | --force) 45 | local force="YES" 46 | ;; 47 | *) 48 | if [ "${remote}" = "" ]; then 49 | local remote="$1" 50 | elif [ "${branch}" = "" ]; then 51 | local branch="$1" 52 | else 53 | echo -e "Error: too many arguments.\n" 54 | _usage 55 | exit 1 56 | fi 57 | ;; 58 | esac 59 | shift 60 | done 61 | 62 | local remote_branch 63 | if [ -z "${remote}" ]; then 64 | if ! remote_branch="$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null)"; then 65 | echo "There is no upstream information of local branch." 66 | exit 1 67 | fi 68 | local branch="$(git rev-parse --abbrev-ref --symbolic-full-name @)" 69 | local remote=$(git config "branch.${branch}.remote") 70 | elif [ -z "${branch}" ]; then 71 | echo -e "Error: too few arguments.\n" 72 | _usage 73 | exit 1 74 | else 75 | remote_branch="${remote}/${branch}" 76 | fi 77 | 78 | if [ "${force}" != "YES" ]; then 79 | if [ "${soft}" = "true" ]; then 80 | echo -n "Are you sure you want to sync with '${remote_branch}'? [y/N]: " 81 | else 82 | echo -n "Are you sure you want to clean all changes & sync with '${remote_branch}'? [y/N]: " 83 | fi 84 | local force 85 | read -r force 86 | fi 87 | case "${force}" in 88 | "Y" | "y" | "yes" | "Yes" | "YES") 89 | if [ "${soft}" = "true" ]; then 90 | git fetch "${remote}" "${branch}" && git reset --hard "${remote_branch}" 91 | else 92 | git fetch "${remote}" "${branch}" && git reset --hard "${remote_branch}" && git clean -d -f -x 93 | fi 94 | ;; 95 | *) 96 | echo "Canceled." 97 | ;; 98 | esac 99 | } 100 | 101 | main "$@" 102 | -------------------------------------------------------------------------------- /private_dot_config/zsh/dot_zshrc: -------------------------------------------------------------------------------- 1 | HISTFILE="$XDG_DATA_HOME"/zsh/history 2 | HISTSIZE=100000 3 | SAVEHIST=100000 4 | autoload -Uz compinit 5 | compinit -d ~/.cache/zsh/zcompdump-$ZSH_VERSION 6 | 7 | # these directories are necessary for zsh. 8 | [[ ! -d ~/.cache/zsh ]] && mkdir -p ~/.cache/zsh 9 | [[ ! -d ~/.local/share/zsh ]] && mkdir -p ~/.local/share/zsh 10 | 11 | # 12 | # Options 13 | # 14 | setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format. 15 | setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits. 16 | setopt SHARE_HISTORY # Share history between all sessions. 17 | setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history. 18 | setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again. 19 | setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate. 20 | setopt HIST_FIND_NO_DUPS # Do not display a line previously found. 21 | setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space. 22 | setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file. 23 | setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry. 24 | setopt HIST_VERIFY # Don't execute immediately upon history expansion. 25 | setopt AUTO_PUSHD # Push the current directory visited on the stack. 26 | setopt PUSHD_IGNORE_DUPS # Do not store duplicates in the stack. 27 | setopt PUSHD_SILENT # Do not print the directory stack after pushd or popd. 28 | 29 | source "$ZDOTDIR/functions" 30 | # prompt 31 | zsh_add_file "prompt.zsh" 32 | # aliases 33 | [ -f $HOME/.config/shell/aliasrc ] && source $HOME/.config/shell/aliasrc 34 | 35 | # Plugins 36 | # TODO: Move this funcionality to chezmoiexternal 37 | zsh_add_plugin "Aloxaf/fzf-tab" 38 | zsh_add_plugin "zdharma-continuum/fast-syntax-highlighting" 39 | zsh_add_plugin "zsh-users/zsh-autosuggestions" 40 | zsh_add_plugin "zsh-users/zsh-history-substring-search" 41 | zsh_add_plugin "jeffreytse/zsh-vi-mode" 42 | 43 | export ZVM_VI_SURROUND_BINDKEY=classic 44 | # export ZVM_VI_INSERT_ESCAPE_BINDKEY=jk 45 | 46 | zvm_after_init() { 47 | bindkey '^[[A' history-substring-search-up 48 | bindkey '^[[B' history-substring-search-down 49 | 50 | # NOTE: initialization of fzf needs to go inside zvm_after_init() 51 | # solves https://github.com/jeffreytse/zsh-vi-mode/issues/90 52 | # https://github.com/jeffreytse/zsh-vi-mode/issues/24 53 | if [ -x "$(command -v fzf)" ]; then 54 | eval "$(fzf --zsh)" 55 | fi 56 | } 57 | 58 | PLUG_DIR=$ZDOTDIR/plugins 59 | [ -f $PLUG_DIR/menu.zsh ] && source $PLUG_DIR/menu.zsh 60 | [ -f $PLUG_DIR/colored-man-pages.zsh ] && source $PLUG_DIR/colored-man-pages.zsh 61 | 62 | # https://wiki.archlinux.org/title/tmux#Start_tmux_on_every_shell_login 63 | # if [ -x "$(command -v tmux)" ] && [ -n "${DISPLAY}" ] && [ -z "${TMUX}" ]; then 64 | # tmux new-session -A -s ${USER} >/dev/null 2>&1 65 | # fi 66 | -------------------------------------------------------------------------------- /private_dot_config/mpv/scripts/misc.lua: -------------------------------------------------------------------------------- 1 | function rotate(inc) 2 | if (360 + inc) % 90 ~= 0 then 3 | return 4 | end 5 | local vf_table = mp.get_property_native("vf") 6 | local previous_angle = 0 7 | local rotation_index = #vf_table + 1 8 | if #vf_table ~= 0 and vf_table[#vf_table]["name"] == "rotate" then 9 | rotation_index = #vf_table 10 | previous_angle = vf_table[#vf_table]["params"]["angle"] 11 | end 12 | local new_angle = (previous_angle + 360 + inc) % 360 13 | if new_angle == 0 then 14 | vf_table[rotation_index] = nil 15 | else 16 | vf_table[rotation_index] = { 17 | name = "rotate", 18 | params = { angle = tostring(new_angle) } 19 | } 20 | end 21 | mp.set_property_native("vf", vf_table) 22 | end 23 | 24 | function toggle(filter) 25 | local vf_table = mp.get_property_native("vf") 26 | if #vf_table ~= 0 and vf_table[#vf_table]["name"] == filter then 27 | vf_table[#vf_table] = nil 28 | else 29 | vf_table[#vf_table + 1] = { name = filter } 30 | end 31 | mp.set_property_native("vf", vf_table) 32 | end 33 | 34 | local filters_undo_stack = {} 35 | 36 | function remove_last_filter() 37 | local vf_table = mp.get_property_native("vf") 38 | if #vf_table == 0 then 39 | return 40 | end 41 | filters_undo_stack[#filters_undo_stack + 1] = vf_table[#vf_table] 42 | vf_table[#vf_table] = nil 43 | mp.set_property_native("vf", vf_table) 44 | end 45 | 46 | function undo_filter_removal() 47 | if #filters_undo_stack == 0 then 48 | return 49 | end 50 | local vf_table = mp.get_property_native("vf") 51 | vf_table[#vf_table + 1] = filters_undo_stack[#filters_undo_stack] 52 | filters_undo_stack[#filters_undo_stack] = nil 53 | mp.set_property_native("vf", vf_table) 54 | end 55 | 56 | function clear_filters() 57 | local vf_table = mp.get_property_native("vf") 58 | if #vf_table == 0 then 59 | return 60 | end 61 | for i = 1, #vf_table do 62 | filters_undo_stack[#filters_undo_stack + 1] = vf_table[#vf_table + 1 - i] 63 | end 64 | mp.set_property_native("vf", {}) 65 | end 66 | 67 | function ab_loop(operation, timestamp) 68 | if not mp.get_property("seekable") then return end 69 | if timestamp ~= "a" and timestamp ~= "b" then return end 70 | timestamp = "ab-loop-" .. timestamp 71 | if operation == "set" then 72 | mp.set_property_number(timestamp, mp.get_property_number("time-pos")) 73 | elseif operation == "jump" then 74 | local t = tonumber(mp.get_property(timestamp)) 75 | if t then mp.set_property_number("time-pos", t) end 76 | elseif operation == "clear" then 77 | mp.set_property(timestamp, "no") 78 | end 79 | end 80 | 81 | mp.add_key_binding(nil, "rotate", rotate) 82 | mp.add_key_binding(nil, "toggle-filter", toggle) 83 | mp.add_key_binding(nil, "clear-filters", clear_filters) 84 | mp.add_key_binding(nil, "remove-last-filter", remove_last_filter) 85 | mp.add_key_binding(nil, "undo-filter-removal", undo_filter_removal) 86 | mp.add_key_binding(nil, "ab-loop", ab_loop) 87 | 88 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/configs/statusline.lua: -------------------------------------------------------------------------------- 1 | local mini_statusline = require "mini.statusline" 2 | 3 | local groups = function() 4 | local mode, mode_hl = mini_statusline.section_mode { trunc_width = 120 } 5 | local git = mini_statusline.section_git { trunc_width = 40 } 6 | local diff = mini_statusline.section_diff { trunc_width = 75 } 7 | 8 | local create_hl = function(severity) 9 | vim.api.nvim_set_hl(0, "MiniStatuslineDiagnostic" .. severity, { 10 | bg = vim.api.nvim_get_hl(0, { name = "MiniStatuslineFilename" }).bg, 11 | fg = vim.api.nvim_get_hl(0, { name = "Diagnostic" .. severity }).fg, 12 | bold = true, 13 | }) 14 | end 15 | 16 | for _, severity in pairs { "Error", "Warn", "Info", "Hint" } do 17 | create_hl(severity) 18 | end 19 | 20 | local diag_signs = { 21 | ERROR = "%#MiniStatuslineDiagnosticError#E:", 22 | WARN = "%#MiniStatuslineDiagnosticWarn#W:", 23 | INFO = "%#MiniStatuslineDiagnosticInfo#I:", 24 | HINT = "%#MiniStatuslineDiagnosticHint#H:", 25 | } 26 | -- Compute colored diagnostics and reset color for later LSP section 27 | local diagnostics = mini_statusline.section_diagnostics { trunc_width = 75, signs = diag_signs, icon = "" } 28 | diagnostics = diagnostics .. "%#MiniStatuslineFilename#" 29 | 30 | local filename = mini_statusline.section_filename { trunc_width = 200 } 31 | local fileinfo = string.format("%s | %s", vim.opt.fileencoding:get(), vim.bo.fileformat) 32 | 33 | local buffer_lsp = function() 34 | local current_buffer = vim.api.nvim_get_current_buf() 35 | local lsp_clients = vim.lsp.get_clients({ bufnr = current_buffer }) 36 | if vim.tbl_isempty(lsp_clients) then return end 37 | local client_names = vim.tbl_map(function(client) 38 | return client.name 39 | end, lsp_clients) 40 | return "[" .. table.concat(client_names, ",") .. "]" 41 | end 42 | 43 | local location = function() 44 | local pos = vim.fn.getcurpos() 45 | local line, column = pos[2], pos[3] 46 | local height = vim.api.nvim_buf_line_count(0) 47 | 48 | local str = " " 49 | local padding = #tostring(height) - #tostring(line) 50 | if padding > 0 then 51 | str = str .. (" "):rep(padding) 52 | end 53 | 54 | str = str .. "ℓ " 55 | str = str .. line 56 | str = str .. " c " 57 | str = str .. column 58 | str = str .. " " 59 | 60 | if #tostring(column) < 2 then 61 | str = str .. " " 62 | end 63 | return str 64 | end 65 | 66 | local search = mini_statusline.section_searchcount { trunc_width = 75 } 67 | return mini_statusline.combine_groups { 68 | { hl = mode_hl, strings = { mode } }, 69 | { hl = "MiniStatuslineDevinfo", strings = { git, diff } }, 70 | "%<", -- Mark general truncate point 71 | { hl = "MiniStatuslineFilename", strings = { filename } }, 72 | "%=", -- End left alignment 73 | { hl = "MiniStatuslineFilename", strings = { diagnostics } }, 74 | { hl = "NonText", strings = { buffer_lsp() } }, 75 | { hl = "MiniStatuslineFileInfo", strings = { fileinfo } }, 76 | { hl = mode_hl, strings = { search, location() } }, 77 | } 78 | end 79 | 80 | mini_statusline.setup { 81 | content = { active = groups }, 82 | } 83 | -------------------------------------------------------------------------------- /private_dot_config/nvim/plugin/lsp.lua: -------------------------------------------------------------------------------- 1 | local lsp, diagnostic = vim.lsp, vim.diagnostic 2 | local aucmd, augroup = vim.api.nvim_create_autocmd, vim.api.nvim_create_augroup 3 | 4 | lsp.enable { 5 | "lua_ls", 6 | "taplo", 7 | "rust_analyzer", 8 | "bashls", 9 | -- "ccls", 10 | "html", 11 | "cssls", 12 | "pyright", 13 | "ts_ls", 14 | "css_variables", 15 | "gopls", 16 | "jsonls", 17 | "clangd", 18 | -- "vtsls", 19 | } 20 | 21 | diagnostic.config { 22 | severity_sort = true, 23 | underline = { 24 | severity = { diagnostic.severity.ERROR, diagnostic.severity.WARN }, 25 | }, 26 | float = { 27 | source = "if_many", 28 | }, 29 | jump = { 30 | float = true, 31 | }, 32 | } 33 | 34 | local setup_keymaps = function(bufnr) 35 | local map = vim.keymap.set 36 | -- map("n", "gd", lsp.buf.definition, { desc = "Go to definition", buffer = bufnr }) 37 | map("n", "", lsp.buf.signature_help, { desc = "Signature help", buffer = bufnr }) 38 | map("n", "grc", lsp.codelens.run, { desc = "Run code lens", buffer = bufnr }) 39 | map({ "v", "n" }, "lf", function() lsp.buf.format { async = true } end, { desc = "Format", buffer = bufnr }) 40 | map("n", "ll", diagnostic.open_float, { desc = "Line diagnostics", buffer = bufnr }) 41 | map( 42 | "n", 43 | "lh", 44 | function() lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) end, 45 | { desc = "Toggle inlay hints", buffer = bufnr } 46 | ) 47 | end 48 | 49 | ---@param client vim.lsp.Client 50 | ---@param bufnr number 51 | local setup_aucmds = function(client, bufnr) 52 | if client:supports_method(lsp.protocol.Methods.textDocument_codeLens) then 53 | aucmd({ "BufEnter", "InsertLeave", "BufWritePost" }, { 54 | desc = "Refresh code lens", 55 | group = augroup("LspCodeLens", { clear = true }), 56 | buffer = bufnr, 57 | callback = lsp.codelens.refresh, 58 | }) 59 | end 60 | 61 | if client:supports_method(lsp.protocol.Methods.textDocument_documentHighlight) then 62 | local under_cursor_highlights = augroup("LspDocHighlight", { clear = false }) 63 | aucmd({ "CursorHold", "CursorHoldI" }, { 64 | group = under_cursor_highlights, 65 | desc = "Highlight references under the cursor", 66 | buffer = bufnr, 67 | callback = lsp.buf.document_highlight, 68 | }) 69 | aucmd({ "CursorMoved" }, { 70 | group = under_cursor_highlights, 71 | desc = "Clear highlight references", 72 | buffer = bufnr, 73 | callback = lsp.buf.clear_references, 74 | }) 75 | end 76 | 77 | aucmd("DiagnosticChanged", { 78 | desc = "Update diagnostics loclist", 79 | group = augroup("UpdateDiagnosticLoc", { clear = true }), 80 | callback = function(args) 81 | diagnostic.setloclist { open = false } 82 | if #diagnostic.get(args.buf) == 0 then 83 | vim.cmd "silent! lclose" 84 | end 85 | end, 86 | }) 87 | end 88 | 89 | aucmd("LspAttach", { 90 | desc = "My LSP settings", 91 | group = augroup("UserLspConfig", {}), 92 | callback = function(args) 93 | ---@type vim.lsp.Client 94 | local client = assert(lsp.get_client_by_id(args.data.client_id)) 95 | setup_keymaps(args.buf) 96 | setup_aucmds(client, args.buf) 97 | end, 98 | }) 99 | -------------------------------------------------------------------------------- /private_dot_config/mbsync/encrypted_mbsyncrc.tmpl.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRNGNORkZuMndMd0I5ME1B 3 | REJRWmxFZ1VjM29tRjNGM252ZmUrK2xMcW5ZCjJNd1RYQTRsRjFkLzBsUDVsQm15 4 | dUNQWncwUlB0SDRBc0owbVBWTUo0em8KLS0tIGRmSGVVSGZzbGgzelFHeFhqYnNE 5 | c3dJR2wrcTF0WWFVcjFBUUtSV2RJTHMKodqXHfUohlY+qK7RhNDnK7bK7mjGHOGT 6 | goXGfyE/tvViSQ/OMjV7K2+jrsoPREjiPo6o4E1eTL0zqOZL9RzFyNsHV3lRLWwQ 7 | +vcWDIKcYqTQzPCE89bNthW0Nd3+8sm+9XL0InaVPrUS/npCDXdh5UPEuqeJVAzK 8 | s5UMJAz8dZ+9y3SZlk9YtYE/S/2P0uWsF3M4YTdFX4sD3NPiVPAJe1Xxto6JpGSU 9 | sid9D8fXYIBn5DG2/948rMeClShMSzyRNnQ3t/foPlx106onlVPre8qZ7dEKlRap 10 | jXcPETYU+5hh+HOCwH/r9APoP+R0plrXiquJArTc/2UlYYLIDRGgYzsxC21WfMk9 11 | 9N2lAxbbOwkH5MFYh0qJwVLDlo+FTJk93VQtBaf+Y3pQmw0tC9cpW0dvb5bqRL78 12 | 9nqlZPXW6wqaI+IaE8UPlSWQRQOr8qzscBkE/qJRRR5Rdo0W0KXyEwjrKamDV8fh 13 | zIe1NlLuOal8bgpsoOAVYIYs0UoEh7HjMm/rYxBAWhGCjblIuVNbmt2IOyrRzV2t 14 | hgTPjcpcXgEdXbnPE4mx7cTN4ByjCIh/TEDzsMaAyUvT3LyFvk2orJ+eJMba2ppd 15 | M3a853bD3SWJyBIiQsRNBvNWjy+7O0WVdWzRV2RhTkS8uJnoOWPis4n/k39vYmII 16 | Bi7gODljTG35prIYYynSma13B8tOtwNa53B+t+eoiK+cQ4P6bjpjexYqh+gndxAX 17 | ExhJW5EwLyGxE12G1rnWxA9AiMXv2ylNmiXtnm/gXMVGlN7gE0F7XLmGGWHEz3QC 18 | qoDLKYcYFdgecJVt9Iq1ITLc7o69hlVbjpzs1bnnA+a0B/nnCRTH4cnKnP6tUuSP 19 | sp8BnsWoTgEwZprccmd58Vzwn9SiKfuqh22kWC9cHNA0vJNMzjHh2F2Vt5GdpJfm 20 | KlZjd6q5oRJQsOje9/qa2LB5a0y8730dJfwT1LIH3eLXZNaADXoVk10+wo3To5FF 21 | Bnj2Y8/GFsZ9Bqj+/uhFrJrb0G6GaCnkHfIW++8rb3hYUbbTPxh1BOEaumWI89j3 22 | EtCzkDGgByUosG6SXfVI00e4hzk+RERinFGkBWv2ydtqfK+9hoRqMFv3+NoRCTKD 23 | pZ1rKFx6fsQAk7Iuuzh2SWJ37FT2z4yPPzYYJcMzyYDuP57c1wm8Rop0Xuq5lks1 24 | bb65OpWziuyH4/qcwszfavnYrjtytZgAqhWxN/uLU8bgS+59+7BXHUVf89Te4JjO 25 | m7Wivf9DgODmvJUn9/NohxILy9YGCyfkinpLTD2vVn0PwCpwe8AqRtErUGqoASo6 26 | 2zyZuHz5UcpFqr49xq8pCVsMEk5mgR/x2TUtSsrDaQ1eoqh64BDMR6fWXlJeF9Q2 27 | u8TFDyidoqEA3FSXXk1uZI699o7QlzdYs56W8bkQIazn3W5ohWYolUgFTs0iXAql 28 | 1l0AarSIfWAh6GHn0+BPFuWxdsIgMzD/TtyxyHHX49BWa5SQSSyaMCIJj/Ho32lQ 29 | re/a3NQoENJLIn4Qmod+L5hoT4d/N8J6tZ7suaNNiEF8o9ht9XeKP2SbyjUkQXuF 30 | 3ntsc9BdEzm41zAWABYS9mAVIc2X180cgKc+TVmn83xey3tFvY2jSMNxxV1ta6hR 31 | bsdNDXR7oqgO726pnzJybm/gwCtx864RfkWPfTBI6qxe64whPF0hl0IbtIVcmU2Z 32 | oJx2H3wazwoklyEuW8teZO4wq0MgyktTqGHZCErFDNq9k86XjON9vmV5Azy4z0zB 33 | 56Yrz8YUQyMfi5EAgw5UJ82jULdO6zrN8t+psWBjGmMmvgKIDjTzbqtWhMn6u94n 34 | 2c71EcHAv3B3qeFKMhtfwU/tukLqbODjRPFzPL0pjkjKFDbdCXSUQdw5YMG7jpuh 35 | 6L9MmMNu/f1/K7xdXVnWszDJ2iFZCvhaNUf0D+MPa/LtFj7r6ap1l1odfNnnRU/o 36 | 4/ZLU3TPdBx6jCOvmevynskGB7z/2QefE3kzK4hmBzM++O3Fm0rwMPXjeEVbXm82 37 | xgoUjGO0h9ECn5ukCqrX1x6C0ui3HNdN7LZ3zBX01qe4ygFsimvdJ2A+BG4lXqek 38 | nbh9kLkcr83pYd/YGNqYEu97XKXUwofodt64D5rTmbE8RsObzb78Nd1t0XQWC5Ek 39 | i8AdY+cER4aKpok1jpTuBxoXps6Ol27XKUeJ2AY3FUnuSLHeyDU8ZwKK2DfmjY1i 40 | ozwEqF5nYtvhchv/rLMI/BOjGMuwClIB6+ko4iZMjVc2zLVjDZJ7zZ9v3e0ue3eb 41 | CiZZFaVcmrs6vUDYnCWTqYELXoHscve2VAWsj9buEy0976YrHrPrfPSgeWwXfcvk 42 | /82wP3NGWa4k9Ff5ESyoUvoiF8PU446JZQHrsvaacCPlT1FFeg63XTi+Q2/QRNb0 43 | uEBjkA81lxJ/o+sad4Xb9FS9sUFxFYyzELjcmUzfAPt+ZQT+YSaGbmTkvHchosZZ 44 | RhkDmMJnCeLQlG9MRSIV60iQva5dg7J4PtrIlf624tXw8K8mQL0J2WJ0JvVjFhr5 45 | J28OWPJW7ThQ0avLlXuxRHaBtXNef9tCw/Ui1bo3spqMpyl70BUDC9E8DLjzJ5BH 46 | VaKW0Ulna5UT6LtpS7hF3Nqmh2qxg+rwKKW2bqRzM3APrVxPEwR8Hyi6X/ioeVMI 47 | 2LUuhkM+PKDdjlD+rcZA/4VpnRV71iTH3ffykCIHE/uBfSE5b15N/+PESlUFJbkJ 48 | Rm/swwG2F5D4+3zCagSlhBnR3a3+cLelwDzWi/8ZJSispk37WtDP3+/4Sf3uotmy 49 | a0b+sYkS12+KGgspGTw3Q7v1OX0ROTW9bCc1BFf6pVEjZGyD5eO3sMblMaXpkzug 50 | F6TWQxhnospkgMajsOzkciDMVhW8XI/Ka695Y4tbR98AxccbXBrwHigQEl3Nq5yZ 51 | mx6kvBur94O9zx6Tt94VPKBHY6sFfMKCmQ1HHibO3eIcALpe/rvN1BdTCyB0ZLGf 52 | Op8kpAFNPBu78YeDpc++JjZsDl8S0DNha/dkRtFnWO/jX+VUqwNf3UETgtCTWQQu 53 | pi723L/vL3V+ATH/yDPMBpHLjZ13ILg+haCZfFdK3mmSiQ== 54 | -----END AGE ENCRYPTED FILE----- 55 | -------------------------------------------------------------------------------- /private_dot_config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | vim.loader.enable() 2 | 3 | -- Disable some builtin plugins 4 | vim.g.loaded_gzip = 1 5 | vim.g.loaded_tar = 1 6 | vim.g.loaded_tarPlugin = 1 7 | vim.g.loaded_zip = 1 8 | vim.g.loaded_zipPlugin = 1 9 | vim.g.loaded_getscript = 1 10 | vim.g.loaded_getscriptPlugin = 1 11 | vim.g.loaded_2html_plugin = 1 12 | vim.g.loaded_netrw = 1 13 | vim.g.loaded_netrwPlugin = 1 14 | vim.g.loaded_netrwSettings = 1 15 | vim.g.loaded_netrwFileHandlers = 1 16 | vim.g.loaded_remote_plugins = 1 17 | 18 | -- Enable undotree 19 | -- TODO: remove mbbill/undotree and enable this on 0.12 20 | -- vim.cmd.packadd "nvim.undotree" 21 | 22 | -- Space as leaderkey 23 | vim.keymap.set("n", "", "", { silent = true }) 24 | vim.keymap.set("v", "", "", { silent = true }) 25 | vim.g.mapleader = " " 26 | vim.g.maplocalleader = " " 27 | 28 | ---@param plugin_name string 29 | ---@param opts? table 30 | function _G.setup_plugin(plugin_name, opts) 31 | local ok, plugin = pcall(require, plugin_name) 32 | if ok then 33 | if not opts then 34 | opts = {} 35 | end 36 | plugin.setup(opts) 37 | return 38 | end 39 | end 40 | 41 | -- TODO: replace with builtin vim.pack on 0.12 42 | local lazypath = vim.fn.stdpath "data" .. "/lazy/lazy.nvim" 43 | if not (vim.uv or vim.loop).fs_stat(lazypath) then 44 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 45 | local out = vim.fn.system { "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath } 46 | if vim.v.shell_error ~= 0 then 47 | vim.api.nvim_echo({ 48 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 49 | { out, "WarningMsg" }, 50 | { "\nPress any key to exit..." }, 51 | }, true, {}) 52 | vim.fn.getchar() 53 | os.exit(1) 54 | end 55 | end 56 | vim.opt.rtp:prepend(lazypath) 57 | 58 | local opts = { 59 | lockfile = os.getenv "HOME" .. "/.config/nvim/lazy-lock.json", 60 | } 61 | 62 | vim.keymap.set("n", "-", ":Lazy", { desc = "Lazy" }) 63 | require("lazy").setup({ 64 | { "https://github.com/neovim/nvim-lspconfig" }, 65 | { "https://github.com/mason-org/mason.nvim" }, 66 | { "https://github.com/nvim-mini/mini.nvim" }, 67 | { "https://github.com/ibhagwan/fzf-lua" }, 68 | { "https://github.com/stevearc/oil.nvim" }, 69 | { "https://codeberg.org/andyg/leap.nvim" }, 70 | { "https://github.com/stevearc/conform.nvim" }, 71 | { "https://github.com/alker0/chezmoi.vim" }, 72 | { "https://github.com/zk-org/zk-nvim" }, 73 | { "https://github.com/catppuccin/nvim", name = "catppuccin" }, 74 | { "https://github.com/windwp/nvim-ts-autotag" }, 75 | { "https://github.com/folke/ts-comments.nvim" }, 76 | { "https://github.com/RRethy/nvim-treesitter-endwise" }, 77 | { "https://github.com/nvim-treesitter/nvim-treesitter-textobjects", branch = "main" }, 78 | { 79 | "https://github.com/nvim-treesitter/nvim-treesitter", 80 | branch = "main", 81 | build = "TSUpdate", 82 | }, 83 | { "https://github.com/mbbill/undotree" } 84 | }, opts) 85 | 86 | vim.cmd.colorschem "catppuccin" 87 | 88 | vim.g.undotree_WindowLayout = 4 89 | vim.g.undotree_SplitWidth = 45 90 | vim.g.undotree_SetFocusWhenToggle = 1 91 | 92 | setup_plugin "mason" 93 | setup_plugin "zk" 94 | setup_plugin("fzf-lua", { "ivy" }) 95 | require("fzf-lua").register_ui_select() 96 | require "configs.mini" 97 | require "configs.oil" 98 | require "configs.leap" 99 | require "configs.format" 100 | 101 | -- Treesitter 102 | require "configs.treesitter" 103 | setup_plugin "ts-comments" 104 | setup_plugin "nvim-ts-autotag" 105 | -------------------------------------------------------------------------------- /private_dot_config/npm/npmrc: -------------------------------------------------------------------------------- 1 | ;;;; 2 | ; npm userconfig file: /home/rafa/.config/npm/npmrc 3 | ; this is a simple ini-formatted file 4 | ; lines that start with semi-colons are comments 5 | ; run `npm help 7 config` for documentation of the various options 6 | ; 7 | ; Configs like `@scope:registry` map a scope to a given registry url. 8 | ; 9 | ; Configs like `///:_authToken` are auth that is restricted 10 | ; to the registry host specified. 11 | 12 | prefix=${XDG_DATA_HOME}/npm 13 | cache=${XDG_CACHE_HOME}/npm 14 | init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js 15 | package-lock=false 16 | 17 | ;;;; 18 | ; all available options shown below with default values 19 | ;;;; 20 | 21 | 22 | ; _auth=null 23 | ; access=null 24 | ; all=false 25 | ; allow-same-version=false 26 | ; also=null 27 | ; always-auth=false 28 | ; audit=true 29 | ; audit-level=null 30 | ; auth-type=legacy 31 | ; before=null 32 | ; bin-links=true 33 | ; browser=null 34 | ; ca=null 35 | ; cache=~/.npm 36 | ; cache-max=null 37 | ; cache-min=0 38 | ; cafile=null 39 | ; call= 40 | ; cert=null 41 | ; ci-name=null 42 | ; cidr=null 43 | ; color=true 44 | ; commit-hooks=true 45 | ; depth=null 46 | ; description=true 47 | ; dev=false 48 | ; 49 | ; diff-ignore-all-space=false 50 | ; diff-name-only=false 51 | ; diff-no-prefix=false 52 | ; diff-dst-prefix=b/ 53 | ; diff-src-prefix=a/ 54 | ; diff-text=false 55 | ; diff-unified=3 56 | ; dry-run=false 57 | ; editor=/usr/bin/nvim 58 | ; engine-strict=false 59 | ; fetch-retries=2 60 | ; fetch-retry-factor=10 61 | ; fetch-retry-maxtimeout=60000 62 | ; fetch-retry-mintimeout=10000 63 | ; fetch-timeout=300000 64 | ; force=false 65 | ; foreground-scripts=false 66 | ; format-package-lock=true 67 | ; fund=true 68 | ; git=git 69 | ; git-tag-version=true 70 | ; global=false 71 | ; global-style=false 72 | ; globalconfig= 73 | ; heading=npm 74 | ; https-proxy=null 75 | ; if-present=false 76 | ; ignore-scripts=false 77 | ; 78 | ; include-staged=false 79 | ; init-author-email= 80 | ; init-author-name= 81 | ; init-author-url= 82 | ; init-license=ISC 83 | ; init-module=~/.npm-init.js 84 | ; init-version=1.0.0 85 | ; init.author.email= 86 | ; init.author.name= 87 | ; init.author.url= 88 | ; init.license=ISC 89 | ; init.module=~/.npm-init.js 90 | ; init.version=1.0.0 91 | ; json=false 92 | ; key=null 93 | ; legacy-bundling=false 94 | ; legacy-peer-deps=false 95 | ; link=false 96 | ; local-address=null 97 | ; loglevel=notice 98 | ; logs-max=10 99 | ; long=false 100 | ; maxsockets=15 101 | ; message=%s 102 | ; node-options=null 103 | ; node-version=v15.13.0 104 | ; noproxy= 105 | ; npm-version=7.8.0 106 | ; offline=false 107 | ; 108 | ; only=null 109 | ; optional=null 110 | ; otp=null 111 | ; 112 | ; package-lock=true 113 | ; package-lock-only=false 114 | ; parseable=false 115 | ; prefer-offline=false 116 | ; prefer-online=false 117 | ; prefix= 118 | ; preid= 119 | ; production=null 120 | ; progress=true 121 | ; proxy=null 122 | ; read-only=false 123 | ; rebuild-bundle=true 124 | ; registry=https://registry.npmjs.org/ 125 | ; save=true 126 | ; save-bundle=false 127 | ; save-dev=false 128 | ; save-exact=false 129 | ; save-optional=false 130 | ; save-peer=false 131 | ; save-prefix=^ 132 | ; save-prod=false 133 | ; scope= 134 | ; script-shell=null 135 | ; searchexclude= 136 | ; searchlimit=20 137 | ; searchopts= 138 | ; searchstaleness=900 139 | ; shell=/usr/bin/zsh 140 | ; shrinkwrap=true 141 | ; sign-git-commit=false 142 | ; sign-git-tag=false 143 | ; sso-poll-frequency=500 144 | ; sso-type=oauth 145 | ; strict-peer-deps=false 146 | ; strict-ssl=true 147 | ; tag=latest 148 | ; tag-version-prefix=v 149 | ; timing=false 150 | ; tmp=/tmp 151 | ; umask=0 152 | ; unicode=true 153 | ; update-notifier=true 154 | ; usage=false 155 | ; user-agent=npm/{npm-version} node/{node-version} {platform} {arch} {ci} 156 | ; userconfig=~/.npmrc 157 | ; version=false 158 | ; versions=false 159 | ; viewer=man 160 | ; which=null 161 | ; 162 | ; workspaces=false 163 | ; yes=null 164 | -------------------------------------------------------------------------------- /private_dot_config/shell/aliasrc: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | # add color to commands 4 | alias grep='grep --color=auto' 5 | alias diff='diff --color=auto' 6 | alias dir='dir --color=auto' 7 | alias ls='ls -Fh --color=auto' 8 | alias ll='ls -Flh --color=auto' 9 | alias lla='ls -FlAh --color=auto' 10 | alias d='dirs -v' 11 | 12 | # shortcuts 13 | alias sys='systemctl' 14 | alias icat='kitty +kitten icat' 15 | alias cp='cp -iv' 16 | alias mv='mv -iv' 17 | alias nuke='rm -rI' 18 | alias rm='rm -vI' 19 | # This allows expansion of aliases after sudo. E.g: sudo nuke 20 | # Normally, aliases in shells are only expanded for the first word. 21 | # So if you prefix an alias with sudo, it won't be expanded. 22 | # http://www.gnu.org/software/bash/manual/bashref.html#Aliases says: "If the 23 | # last character of the alias value is a space or tab character, then the next 24 | # command word following the alias is also checked for alias expansion." 25 | alias sudo='sudo ' 26 | alias untar='tar -xvf' 27 | alias v='nvim' 28 | alias vim='nvim' 29 | alias cm='chezmoi' 30 | alias lg='lazygit' 31 | alias mbsync='mbsync --config "$XDG_CONFIG_HOME/mbsync/mbsyncrc"' 32 | alias adb='HOME="$XDG_DATA_HOME"/android adb' 33 | alias ..='cd ..' 34 | alias ...='cd ../..' 35 | alias ....='cd ../../..' 36 | 37 | # git 38 | alias g='git' 39 | alias ga='git add' 40 | alias gcl='git clone' 41 | alias cdg='cd $(git rev-parse --show-toplevel)' 42 | alias gaa='git add --all' 43 | alias gb='git branch -a' 44 | alias gc='git commit' 45 | alias gcm='git commit -m' 46 | alias gd='git diff' 47 | alias gp='git push' 48 | alias gl='git pull' 49 | alias gll='git log' 50 | alias gs='git status' 51 | alias gr='git remote -v' 52 | alias grm='git rm' 53 | alias grmc='git rm --cached' 54 | alias gmv='git mv' 55 | 56 | # create an alias for folders in the pushd stack 57 | i=0 58 | while [ "$i" -le 9 ]; do 59 | # shellcheck disable=SC2139 60 | alias "$i"="cd +${i}" 61 | i=$((i + 1)) 62 | done 63 | 64 | if command -v xdg-open >/dev/null 2>&1; then 65 | open() { 66 | xdg-open "$@" >/dev/null 2>&1 & 67 | } 68 | fi 69 | 70 | # fkill - kill processes - list only the ones you can kill. Modified the earlier script. 71 | fkill() { 72 | pid="" 73 | if [ "$(id -u)" != "0" ]; then 74 | pid=$(ps -f -u "$(id -u)" | sed 1d | fzf | awk '{print $2}') 75 | else 76 | pid=$(ps -ef | sed 1d | fzf | awk '{print $2}') 77 | fi 78 | 79 | if [ ! -z "$pid" ]; then 80 | echo "$pid" | xargs kill -"${1:-9}" 81 | fi 82 | } 83 | 84 | compress() { 85 | tar -czf "${1%/}.tar.gz" "${1%/}"; 86 | } 87 | 88 | # Write iso file to sd card / USB drive 89 | # source: https://github.com/basecamp/omarchy/blob/master/default/bash/functions 90 | iso2sd() { 91 | if [ $# -ne 2 ]; then 92 | echo "Usage: iso2sd " 93 | echo "Example: iso2sd ~/Downloads/ubuntu-25.04-desktop-amd64.iso /dev/sda" 94 | printf "\nAvailable SD cards:" 95 | lsblk -d -o NAME | grep -E '^sd[a-z]' | awk '{print "/dev/"$1}' 96 | else 97 | sudo dd bs=4M status=progress oflag=sync if="$1" of="$2" 98 | sudo eject "$2" 99 | fi 100 | } 101 | 102 | # Reduce file size of video 103 | # Based of https://github.com/basecamp/omarchy/blob/master/default/bash/functions 104 | transcode_video_small() { 105 | ffmpeg -i "$1" -c:v libx264 -preset fast -crf 28 -c:a copy "${1%.*}"-small.mp4 106 | } 107 | 108 | # Transcode any image to JPG image that's great for sharing online without being too big 109 | # Source: https://github.com/basecamp/omarchy/blob/master/default/bash/functions 110 | img2jpg_small() { 111 | magick "$1" -quality 95 -strip "${1%.*}"-small.jpg 112 | } 113 | 114 | # Transcode any image to compressed-but-lossless PNG 115 | # source: https://github.com/basecamp/omarchy/blob/master/default/bash/functions 116 | img2png() { 117 | magick "$1" -strip -define png:compression-filter=5 \ 118 | -define png:compression-level=9 \ 119 | -define png:compression-strategy=1 \ 120 | -define png:exclude-chunk=all \ 121 | "${1%.*}.png" 122 | } 123 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/configs/leap.lua: -------------------------------------------------------------------------------- 1 | vim.api.nvim_set_hl(0, "LeapBackdrop", { link = "Comment" }) 2 | 3 | local leap = require "leap" 4 | 5 | vim.keymap.set({ "n", "x", "o" }, "s", "(leap)") 6 | vim.keymap.set({ "n", "x", "o" }, "gs", function() require("leap.remote").action() end) 7 | 8 | -- Define a preview filter to reduce visual noise 9 | -- and the blinking effect after the first keypress 10 | -- (`:h leap.opts.preview`). You can still target any visible 11 | -- positions if needed, but you can define what is considered an 12 | -- exceptional case. 13 | -- Exclude whitespace and the middle of alphabetic words from preview: 14 | -- foobar[baaz] = quux 15 | -- ^----^^^--^^-^-^--^ 16 | leap.opts.preview = function(ch0, ch1, ch2) 17 | return not (ch1:match "%s" or (ch0:match "%a" and ch1:match "%a" and ch2:match "%a")) 18 | end 19 | 20 | -- Define equivalence classes for brackets and quotes, in addition to 21 | -- the default whitespace group: 22 | leap.opts.equivalence_classes = { 23 | " \t\r\n", 24 | "([{", 25 | ")]}", 26 | "\"`'", 27 | ":.<>?", 28 | } 29 | 30 | -- Use the traversal keys to repeat the previous motion without 31 | -- explicitly invoking Leap: 32 | require("leap.user").set_repeat_keys("", "") 33 | 34 | -- remote line(s), with optional count (yaa{leap}, y3aa{leap}) 35 | vim.keymap.set({ "x", "o" }, "aa", function() 36 | -- Force linewise selection. 37 | local V = vim.fn.mode(true):match "V" and "" or "V" 38 | -- In any case, move horizontally, to trigger operations. 39 | local input = vim.v.count > 1 and (vim.v.count - 1 .. "j") or "h" 40 | -- With `count=false` you can skip feeding count to the command 41 | -- automatically (we need -1 here, see above). 42 | require("leap.remote").action { input = V .. input, count = false } 43 | end) 44 | 45 | -- Create remote versions of all a/i text objects by inserting `r` 46 | -- into the middle (`iw` becomes `irw`, etc.). 47 | do 48 | -- A trick to avoid having to create separate hardcoded mappings for 49 | -- each text object: when entering `ar`/`ir`, consume the next 50 | -- character, and create the input from that character concatenated to 51 | -- `a`/`i`. 52 | local remote_text_object = function(prefix) 53 | local ok, ch = pcall(vim.fn.getcharstr) -- pcall for handling 54 | if not ok or (ch == vim.keycode "") then 55 | return 56 | end 57 | require("leap.remote").action { input = prefix .. ch } 58 | end 59 | 60 | for _, prefix in ipairs { "a", "i" } do 61 | vim.keymap.set({ "x", "o" }, prefix .. "r", function() remote_text_object(prefix) end) 62 | end 63 | end 64 | 65 | -- 1-character search (enhanced f/t motions) 66 | do 67 | -- Return an argument table for `leap()`, tailored for f/t-motions. 68 | local function as_ft(key_specific_args) 69 | local common_args = { 70 | inputlen = 1, 71 | inclusive = true, 72 | -- To limit search scope to the current line: 73 | -- pattern = function (pat) return '\\%.l'..pat end, 74 | opts = { 75 | labels = "", -- force autojump 76 | safe_labels = vim.fn.mode(1):match "[no]" and "" or nil, -- [1] 77 | }, 78 | } 79 | return vim.tbl_deep_extend("keep", common_args, key_specific_args) 80 | end 81 | 82 | local clever = require("leap.user").with_traversal_keys -- [2] 83 | local clever_f = clever("f", "F") 84 | local clever_t = clever("t", "T") 85 | 86 | for key, key_specific_args in pairs { 87 | f = { opts = clever_f }, 88 | F = { backward = true, opts = clever_f }, 89 | t = { offset = -1, opts = clever_t }, 90 | T = { backward = true, offset = 1, opts = clever_t }, 91 | } do 92 | vim.keymap.set({ "n", "x" }, key, function() require("leap").leap(as_ft(key_specific_args)) end) 93 | end 94 | end 95 | ------------------------------------------------------------------------ 96 | -- [1] Match the modes here for which you don't want to use labels 97 | -- (`:h mode()`, `:h lua-pattern`). 98 | -- [2] This helper function makes it easier to set "clever-f"-like 99 | -- functionality (https://github.com/rhysd/clever-f.vim), returning 100 | -- an `opts` table derived from the defaults, where the given keys 101 | -- are added to `keys.next_target` and `keys.prev_target` 102 | -------------------------------------------------------------------------------- /private_dot_config/tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | # {{{ Options 2 | set -g mouse on 3 | 4 | # https://github.com/alacritty/alacritty/issues/6156#issuecomment-1180648186 5 | # some issues with alacritty not displaying the proper colors in tmux 6 | set -g default-terminal "tmux-256color" 7 | set -ga terminal-overrides ",xterm-256color:Tc" 8 | 9 | # Underculrs don't work by default 10 | # https://github.com/folke/lsp-colors.nvim?tab=readme-ov-file#making-undercurls-work-properly-in-tmux 11 | # https://www.reddit.com/r/neovim/comments/nc34j7/comment/gy2su5f/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button 12 | set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm' # undercurl support 13 | set -as terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m' # underscore colours - needs tmux-3.0 14 | 15 | # Start windows and panes index at 1, not 0. 16 | set -g base-index 1 17 | setw -g pane-base-index 1 18 | 19 | # Ensure window index numbers get reordered on delete. 20 | set-option -g renumber-windows on 21 | 22 | # don't exit from tmux when closing a session 23 | set -g detach-on-destroy off 24 | 25 | # Address vim mode switching delay (http://superuser.com/a/252717/65504) 26 | # https://superuser.com/a/1809494 27 | set -s escape-time 100 28 | 29 | # Increase scrollback buffer size from 2000 to 50000 lines 30 | set -g history-limit 50000 31 | 32 | # Increase tmux messages display duration from 750ms to 4s 33 | set -g display-time 4000 34 | 35 | # Refresh 'status-left' and 'status-right' more often, from every 15s to 5s 36 | set -g status-interval 5 37 | 38 | # (OS X) Fix pbcopy/pbpaste for old tmux versions (pre 2.6) 39 | # set -g default-command "reattach-to-user-namespace -l $SHELL" 40 | 41 | # Emacs key bindings in tmux command prompt (prefix + :) are better than 42 | # vi keys, even for vim users 43 | set -g status-keys emacs 44 | 45 | # Focus events enabled for terminals that support them 46 | set -g focus-events on 47 | 48 | # Super useful when using "grouped sessions" and multi-monitor setup 49 | setw -g aggressive-resize on 50 | 51 | # To enalbe yazi image preview 52 | # https://yazi-rs.github.io/docs/image-preview/#tmux 53 | set -g allow-passthrough on 54 | set -ga update-environment TERM 55 | set -ga update-environment TERM_PROGRAM 56 | # }}} 57 | 58 | # {{{ Statusline style 59 | set -g status-bg black 60 | set -g status-fg white 61 | set -g status-left-length 30 62 | set -g status-left "#{?client_prefix,#[fg=blue],#[bold]}[#{session_name}] " 63 | set -g status-right "#{?client_prefix,#[fg=blue],#[bold]} #(echo $USER) | #(hostname) " 64 | set-window-option -g window-status-current-format "#[fg=red, bold]#{window_index} #{window_name}*" 65 | set-window-option -g window-status-format "#{window_index} #{window_name} " 66 | # }}} 67 | 68 | # {{{ Key bindings 69 | 70 | # https://unix.stackexchange.com/a/30283 71 | # do not confirm when closing windows/panes 72 | # bind-key & kill-window 73 | # bind-key x kill-pane 74 | 75 | # https://unix.stackexchange.com/questions/12032/how-to-create-a-new-window-on-the-current-directory-in-tmux 76 | # bind keys to open windows and panes in same DIR 77 | bind '"' split-window -c "#{pane_current_path}" 78 | bind % split-window -h -c "#{pane_current_path}" 79 | bind c new-window -c "#{pane_current_path}" 80 | 81 | # pane navigation 82 | bind-key h select-pane -L 83 | bind-key C-h select-pane -L 84 | bind-key j select-pane -D 85 | bind-key C-j select-pane -D 86 | bind-key k select-pane -U 87 | bind-key C-k select-pane -U 88 | bind-key l select-pane -R 89 | bind-key C-l select-pane -R 90 | 91 | # pane resize 92 | bind-key -r H resize-pane -L 5 93 | bind-key -r J resize-pane -D 5 94 | bind-key -r K resize-pane -U 5 95 | bind-key -r L resize-pane -R 5 96 | 97 | # toggle last window/pane 98 | bind b last-window 99 | bind "'" last-pane 100 | 101 | # From https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/scripts/tmux-sessionizer 102 | bind-key -r f run-shell "tmux neww tmux-sessionizer" 103 | # }}} 104 | 105 | # {{{ Pugins 106 | # https://github.com/tmux-plugins/tpm/blob/master/docs/automatic_tpm_installation.md 107 | # Press `prefix + I` to install the plugin. 108 | # Press `prefix + alt + u` to uninstall the plugin. 109 | if "test ! -d ~/.config/tmux/plugins/tpm" \ 110 | "run 'git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm && ~/.config/tmux/plugins/tpm/bin/install_plugins'" 111 | 112 | set -g @plugin 'tmux-plugins/tmux-resurrect' 113 | set -g @plugin 'tmux-plugins/tmux-continuum' 114 | set -g @continuum-restore 'on' 115 | set -g @plugin 'Morantron/tmux-fingers' 116 | 117 | run '~/.config/tmux/plugins/tpm/tpm' 118 | # }}} 119 | 120 | # vim: foldmethod=marker foldlevel=0 121 | -------------------------------------------------------------------------------- /private_dot_config/nvim/plugin/coerce.lua: -------------------------------------------------------------------------------- 1 | local coerce = require "coerce" 2 | 3 | local convert_names = { 4 | ["snake_case"] = coerce.to_snake_case, 5 | ["camelCase"] = coerce.to_camel_case, 6 | ["PascalCase"] = coerce.to_pascal_case, 7 | ["UPPER_CASE"] = coerce.to_uppercase, 8 | ["kebab-case"] = coerce.to_kebab_case, 9 | ["dot.case"] = coerce.to_dot_case, 10 | } 11 | 12 | vim.api.nvim_create_user_command("To", function(opts) 13 | local cword = coerce.get_cword_position(opts.bang) 14 | local position = { 15 | start_row = cword.line + 1, 16 | start_col = cword.start_col, 17 | end_row = cword.line + 1, 18 | end_col = cword.end_col, 19 | } 20 | 21 | local mode = "" 22 | if opts.range > 0 then 23 | local start_pos = vim.fn.getpos "'<" 24 | local end_pos = vim.fn.getpos "'>" 25 | mode = vim.fn.visualmode() 26 | position = { 27 | start_row = start_pos[2], 28 | start_col = start_pos[3], 29 | end_row = end_pos[2], 30 | end_col = end_pos[3], 31 | } 32 | end 33 | 34 | local arg = opts.fargs[1]:gsub(" ", "") 35 | for key, to_case in pairs(convert_names) do 36 | if arg == key then 37 | coerce.handle_coerce(to_case, position, mode, opts.bang) 38 | end 39 | end 40 | end, { 41 | bang = true, 42 | range = true, 43 | nargs = 1, 44 | complete = function() 45 | local completion = {} 46 | for key, _ in pairs(convert_names) do 47 | table.insert(completion, key) 48 | end 49 | return completion 50 | end, 51 | }) 52 | 53 | -- Implementation of dot repeat from: 54 | -- https://gist.github.com/kylechui/a5c1258cd2d86755f97b10fc921315c3 55 | _G.cached_handle_coerce = nil 56 | 57 | _G.handle_coerce = function() 58 | if not _G.cached_handle_coerce then return end 59 | 60 | local cword = coerce.get_cword_position(false) 61 | local position = { 62 | start_row = cword.line + 1, 63 | start_col = cword.start_col, 64 | end_row = cword.line + 1, 65 | end_col = cword.end_col, 66 | } 67 | 68 | coerce.handle_coerce(_G.cached_handle_coerce, position, "", false) 69 | end 70 | 71 | local coerce_to_uppercase = function() 72 | if vim.api.nvim_get_mode().mode == "v" or vim.api.nvim_get_mode().mode == "V" then 73 | return ":To UPPER_CASE" 74 | end 75 | _G.cached_handle_coerce = coerce.to_uppercase 76 | vim.o.operatorfunc = "v:lua.handle_coerce" 77 | return "g@l" 78 | end 79 | 80 | local coerce_to_snake_case = function() 81 | if vim.api.nvim_get_mode().mode == "v" or vim.api.nvim_get_mode().mode == "V" then 82 | return ":To snake_case" 83 | end 84 | _G.cached_handle_coerce = coerce.to_snake_case 85 | vim.o.operatorfunc = "v:lua.handle_coerce" 86 | return "g@l" 87 | end 88 | 89 | local coerce_to_camel_case = function() 90 | if vim.api.nvim_get_mode().mode == "v" or vim.api.nvim_get_mode().mode == "V" then 91 | return ":To camelCase" 92 | end 93 | _G.cached_handle_coerce = coerce.to_camel_case 94 | vim.o.operatorfunc = "v:lua.handle_coerce" 95 | return "g@l" 96 | end 97 | 98 | local coerce_to_pascal_case = function() 99 | if vim.api.nvim_get_mode().mode == "v" or vim.api.nvim_get_mode().mode == "V" then 100 | return ":To PascalCase" 101 | end 102 | _G.cached_handle_coerce = coerce.to_pascal_case 103 | vim.o.operatorfunc = "v:lua.handle_coerce" 104 | return "g@l" 105 | end 106 | 107 | local coerce_to_dot_case = function() 108 | if vim.api.nvim_get_mode().mode == "v" or vim.api.nvim_get_mode().mode == "V" then 109 | return ":To dot.case" 110 | end 111 | _G.cached_handle_coerce = coerce.to_dot_case 112 | vim.o.operatorfunc = "v:lua.handle_coerce" 113 | return "g@l" 114 | end 115 | 116 | local coerce_to_kebab_case = function() 117 | if vim.api.nvim_get_mode().mode == "v" or vim.api.nvim_get_mode().mode == "V" then 118 | return ":To kebab-case" 119 | end 120 | _G.cached_handle_coerce = coerce.to_kebab_case 121 | vim.o.operatorfunc = "v:lua.handle_coerce" 122 | return "g@l" 123 | end 124 | 125 | vim.keymap.set({ "v", "n" }, "cru", coerce_to_uppercase, { expr = true, desc = "UPPER_CASE" }) 126 | vim.keymap.set({ "v", "n" }, "crs", coerce_to_snake_case, { expr = true, desc = "snake_case" }) 127 | vim.keymap.set({ "v", "n" }, "crc", coerce_to_camel_case, { expr = true, desc = "camelCase" }) 128 | vim.keymap.set({ "v", "n" }, "crp", coerce_to_pascal_case, { expr = true, desc = "PascalCase" }) 129 | vim.keymap.set({ "v", "n" }, "cr.", coerce_to_dot_case, { expr = true, desc = "dot.case" }) 130 | vim.keymap.set({ "v", "n" }, "cr-", coerce_to_kebab_case, { expr = true, desc = "kebab-case" }) 131 | -------------------------------------------------------------------------------- /private_dot_config/vis/themes/gruvbox.lua: -------------------------------------------------------------------------------- 1 | -- Gruvbox color scheme by Pavel Pertsev (https://github.com/morhetz) 2 | -- For the Vis text editor by Marc Tanner (https://github.com/martanne) 3 | 4 | -- Set to 'dark' or 'light' 5 | local mode = 'dark' 6 | -- Set to 'hard', 'medium', or 'soft' 7 | local contrast = 'medium' 8 | 9 | local gruvbox = { 10 | dark0h = '#1d2021', 11 | dark0 = '#282828', 12 | dark0s = '#32302f', 13 | dark1 = '#3c3836', 14 | dark2 = '#504945', 15 | dark3 = '#665c54', 16 | dark4 = '#7c6f64', 17 | light0h = '$f9f5d7', 18 | light0 = '#fbf1c7', 19 | light0s = '#f2e5bc', 20 | light1 = '#ebdbb2', 21 | light2 = '#d5c4a1', 22 | light3 = '#bdae93', 23 | light4 = '#a89984', 24 | gray = '#928374', 25 | red0 = '#fb4934', 26 | red1 = '#9d0006', 27 | green0 = '#b8bb26', 28 | green1 = '#79740e', 29 | yellow0 = '#fabd2f', 30 | yellow1 = '#b57614', 31 | blue0 = '#83a598', 32 | blue1 = '#076678', 33 | purple0 = '#d3869b', 34 | purple1 = '#8f3f71', 35 | aqua0 = '#8ec07c', 36 | aqua1 = '#427b58', 37 | orange0 = '#fe8019', 38 | orange1 = '#af3a03', 39 | } 40 | 41 | local colors = {} 42 | 43 | if mode == 'dark' then 44 | if contrast == 'hard' then 45 | colors.bg0 = gruvbox.dark0h 46 | elseif contrast == 'medium' then 47 | colors.bg0 = gruvbox.dark0 48 | elseif contrast == 'soft' then 49 | colors.bg0 = gruvbox.dark0s 50 | end 51 | colors.bg1 = gruvbox.dark1 52 | colors.bg2 = gruvbox.dark2 53 | colors.bg3 = gruvbox.dark3 54 | colors.bg4 = gruvbox.dark4 55 | colors.fg0 = gruvbox.light0 56 | colors.fg1 = gruvbox.light1 57 | colors.fg2 = gruvbox.light2 58 | colors.fg3 = gruvbox.light3 59 | colors.fg4 = gruvbox.light4 60 | colors.gray = gruvbox.gray 61 | colors.red = gruvbox.red0 62 | colors.green = gruvbox.green0 63 | colors.yellow = gruvbox.yellow0 64 | colors.blue = gruvbox.blue0 65 | colors.purple = gruvbox.purple0 66 | colors.aqua = gruvbox.aqua0 67 | colors.orange = gruvbox.orange0 68 | elseif mode == 'light' then 69 | if contrast == 'hard' then 70 | colors.bg0 = gruvbox.light0h 71 | elseif contrast == 'medium' then 72 | colors.bg0 = gruvbox.light0 73 | elseif contrast == 'soft' then 74 | colors.bg0 = gruvbox.light0s 75 | end 76 | colors.bg1 = gruvbox.light1 77 | colors.bg2 = gruvbox.light2 78 | colors.bg3 = gruvbox.light3 79 | colors.bg4 = gruvbox.light4 80 | colors.fg0 = gruvbox.dark0 81 | colors.fg1 = gruvbox.dark1 82 | colors.fg2 = gruvbox.dark2 83 | colors.fg3 = gruvbox.dark3 84 | colors.fg4 = gruvbox.dark4 85 | colors.gray = gruvbox.gray 86 | colors.red = gruvbox.red1 87 | colors.green = gruvbox.green1 88 | colors.yellow = gruvbox.yellow1 89 | colors.blue = gruvbox.blue1 90 | colors.purple = gruvbox.purple1 91 | colors.aqua = gruvbox.aqua1 92 | colors.orange = gruvbox.orange1 93 | end 94 | 95 | -- To use your terminal's default background (e.g. for transparency), set the value below to 'back:default,fore:'..colors.fg1 96 | vis.lexers.STYLE_DEFAULT = 'back:'..colors.bg0..',fore:'..colors.fg1 97 | vis.lexers.STYLE_NOTHING = '' 98 | vis.lexers.STYLE_CLASS = 'fore:'..colors.yellow 99 | vis.lexers.STYLE_COMMENT = 'fore:'..colors.gray..',italics' 100 | vis.lexers.STYLE_CONSTANT = 'fore:'..colors.purple 101 | vis.lexers.STYLE_DEFINITION = 'fore:'..colors.yellow 102 | vis.lexers.STYLE_ERROR = 'fore:'..colors.red..',back:'..colors.bg0..',reverse' 103 | vis.lexers.STYLE_FUNCTION = 'fore:'..colors.green..',bold' 104 | vis.lexers.STYLE_KEYWORD = 'fore:'..colors.red 105 | vis.lexers.STYLE_LABEL = 'fore:'..colors.red 106 | vis.lexers.STYLE_NUMBER = 'fore:'..colors.purple 107 | vis.lexers.STYLE_OPERATOR = vis.lexers.STYLE_DEFAULT 108 | vis.lexers.STYLE_REGEX = 'fore:'..colors.aqua 109 | vis.lexers.STYLE_STRING = 'fore:'..colors.green 110 | vis.lexers.STYLE_PREPROCESSOR = 'fore:'..colors.aqua 111 | vis.lexers.STYLE_TAG = 'fore:'..colors.blue 112 | vis.lexers.STYLE_TYPE = 'fore:'..colors.yellow 113 | vis.lexers.STYLE_VARIABLE = 'fore:'..colors.blue 114 | vis.lexers.STYLE_WHITESPACE = '' 115 | vis.lexers.STYLE_EMBEDDED = 'fore:'..colors.orange 116 | vis.lexers.STYLE_IDENTIFIER = 'fore:'..colors.blue 117 | 118 | vis.lexers.STYLE_LINENUMBER = 'fore:'..colors.bg4 119 | vis.lexers.STYLE_LINENUMBER_CURSOR = 'fore:'..colors.yellow..',back:'..colors.bg1 120 | vis.lexers.STYLE_CURSOR = 'reverse' 121 | vis.lexers.STYLE_CURSOR_PRIMARY = vis.lexers.STYLE_CURSOR..',fore:'..colors.yellow 122 | vis.lexers.STYLE_CURSOR_LINE = 'back:'..colors.bg1 123 | vis.lexers.STYLE_COLOR_COLUMN = 'reverse' 124 | vis.lexers.STYLE_SELECTION = 'back:'..colors.bg3..',reverse' 125 | vis.lexers.STYLE_STATUS = 'fore:'..colors.bg1..',back:'..colors.fg4..',reverse' 126 | vis.lexers.STYLE_STATUS_FOCUSED = 'fore:'..colors.bg2..',back:'..colors.fg1..',reverse' 127 | vis.lexers.STYLE_SEPARATOR = 'fore:'..colors.bg3 128 | vis.lexers.STYLE_INFO = 'fore:'..colors.yellow..',bold' 129 | vis.lexers.STYLE_EOF = vis.lexers.STYLE_LINENUMBER 130 | -------------------------------------------------------------------------------- /private_dot_config/nvim/plugin/autocommands.lua: -------------------------------------------------------------------------------- 1 | local aucmd = vim.api.nvim_create_autocmd 2 | local augroup = vim.api.nvim_create_augroup 3 | 4 | aucmd({ "TextYankPost" }, { 5 | pattern = "*", 6 | desc = "Highlight text on yank", 7 | group = augroup("TextHighlightYank", { clear = true }), 8 | callback = function() vim.hl.on_yank { timeout = 200 } end, 9 | }) 10 | 11 | local no_lastplace = { 12 | buftypes = { 13 | "quickfix", 14 | "nofile", 15 | "help", 16 | "terminal", 17 | }, 18 | filetypes = { 19 | "gitcommit", 20 | "gitrebase", 21 | }, 22 | } 23 | 24 | aucmd({ "BufReadPost" }, { 25 | pattern = "*", 26 | desc = "Jump to last place in files", 27 | group = augroup("JumpToLastPosition", { clear = true }), 28 | callback = function() 29 | if 30 | vim.fn.line [['"]] >= 1 31 | and vim.fn.line [['"]] <= vim.fn.line "$" 32 | and not vim.tbl_contains(no_lastplace.buftypes, vim.o.buftype) 33 | and not vim.tbl_contains(no_lastplace.filetypes, vim.o.filetype) 34 | then 35 | vim.cmd [[normal! g`" | zv]] 36 | end 37 | end, 38 | }) 39 | 40 | aucmd({ "TermOpen" }, { 41 | pattern = "term://*", 42 | desc = "Start in insert mode in terminal", 43 | group = augroup("MyTerminalOps", { clear = true }), 44 | callback = function() vim.cmd "startinsert" end, 45 | }) 46 | 47 | -- source: https://github.com/tsakirist/dotfiles/blob/7d3454a57679e5ba1c8ce4273bbed3eb737bb99c/nvim/lua/tt/autocommands.lua#L117-L142 48 | aucmd("BufWritePre", { 49 | pattern = "*", 50 | desc = "Automatically create missing directories when saving file", 51 | group = augroup("Mkdir", { clear = true }), 52 | callback = function(event) 53 | ---Checks whether the autocommand should run 54 | ---@param path string 55 | ---@return boolean 56 | local function is_excluded(path) 57 | for _, pattern in ipairs { "^oil://" } do 58 | if path:find(pattern) then 59 | return true 60 | end 61 | end 62 | return false 63 | end 64 | 65 | local full_path = event.match 66 | if is_excluded(full_path) then 67 | return 68 | end 69 | 70 | local directory = vim.fn.fnamemodify(full_path, ":p:h") 71 | vim.fn.mkdir(directory, "p") 72 | end, 73 | }) 74 | 75 | -- Use aucmd to set formatoptions, otherwise if I put them in options.lua it 76 | -- will get overrule by filetype plugin (super annoying). The other option is to 77 | -- use after/ftplugin but I would have to set formatoptions for every single 78 | -- filetype. According to comment in Ref: In order for this aucmd to work, it has 79 | -- to be defined `after` the default filetype detection (i.e. :filetype plugin 80 | -- on). 81 | -- Ref: https://stackoverflow.com/questions/28375119/how-to-override-options-set-by-ftplugins-in-vim 82 | aucmd({ "Filetype" }, { 83 | pattern = "*", 84 | desc = "Set formatoptions", 85 | group = augroup("SetFormatOptions", { clear = true }), 86 | callback = function() 87 | vim.opt.formatoptions = { 88 | ["1"] = true, -- Don't break a line after a one-letter word. 89 | ["2"] = false, -- Use indent from 2nd line of a paragraph 90 | q = true, -- Continue comments with gq" 91 | c = false, -- Insert current comment leader automatically 92 | r = true, -- Continue comments when pressing Enter 93 | o = false, -- Continue comments when pressing 'o' or 'O' 94 | n = true, -- Recognize numbered lists 95 | t = false, -- Autowrap lines using text width value 96 | j = true, -- Remove a comment leader when joining lines. 97 | l = true, -- When a line longer than 'textwidth', don't format it 98 | } 99 | end, 100 | }) 101 | 102 | -- HLSEARCH 103 | -- Source: https://github.com/Wansmer/nvim-config/blob/4bbfd1c9c693ae33b8d7a57a9ae9b14a94068bbb/lua/modules/key_listener.lua 104 | -- Source: https://www.reddit.com/r/neovim/comments/zc720y/tip_to_manage_hlsearch/ 105 | local auto_hlsearch = vim.api.nvim_create_namespace "auto_hlsearch" 106 | 107 | ---Deleting hlsearch when it already no needed 108 | local function toggle_hlsearch(char) 109 | local keys = { "", "n", "N", "*", "#", "?", "/" } 110 | local new_hlsearch = vim.tbl_contains(keys, char) and 1 or 0 111 | 112 | if vim.api.nvim_get_vvar "hlsearch" ~= new_hlsearch then 113 | vim.api.nvim_set_vvar("hlsearch", new_hlsearch) 114 | end 115 | end 116 | 117 | ---Handler for pressing keys. Added listeners for modes 118 | ---@param char string 119 | local function key_listener(char) 120 | local key = vim.fn.keytrans(char) 121 | local mode = vim.fn.mode() 122 | if mode == "n" then 123 | toggle_hlsearch(key) 124 | end 125 | end 126 | 127 | vim.on_key(key_listener, auto_hlsearch) 128 | -------------------------------------------------------------------------------- /private_dot_config/mpv/scripts/seek-to.lua: -------------------------------------------------------------------------------- 1 | local assdraw = require 'mp.assdraw' 2 | local active = false 3 | local cursor_position = 1 4 | local time_scale = {60*60*10, 60*60, 60*10, 60, 10, 1, 0.1, 0.01, 0.001} 5 | 6 | local ass_begin = mp.get_property("osd-ass-cc/0") 7 | local ass_end = mp.get_property("osd-ass-cc/1") 8 | 9 | local history = { {} } 10 | for i = 1, 9 do 11 | history[1][i] = 0 12 | end 13 | local history_position = 1 14 | 15 | -- timer to redraw periodically the message 16 | -- to avoid leaving bindings when the seeker disappears for whatever reason 17 | -- pretty hacky tbh 18 | local timer = nil 19 | local timer_duration = 3 20 | 21 | function show_seeker() 22 | local prepend_char = {'','',':','',':','','.','',''} 23 | local str = '' 24 | for i = 1, 9 do 25 | str = str .. prepend_char[i] 26 | if i == cursor_position then 27 | str = str .. '{\\b1}' .. history[history_position][i] .. '{\\r}' 28 | else 29 | str = str .. history[history_position][i] 30 | end 31 | end 32 | mp.osd_message("Seek to: " .. ass_begin .. str .. ass_end, timer_duration) 33 | end 34 | 35 | function copy_history_to_last() 36 | if history_position ~= #history then 37 | for i = 1, 9 do 38 | history[#history][i] = history[history_position][i] 39 | end 40 | history_position = #history 41 | end 42 | end 43 | 44 | function change_number(i) 45 | -- can't set above 60 minutes or seconds 46 | if (cursor_position == 3 or cursor_position == 5) and i >= 6 then 47 | return 48 | end 49 | if history[history_position][cursor_position] ~= i then 50 | copy_history_to_last() 51 | history[#history][cursor_position] = i 52 | end 53 | shift_cursor(false) 54 | end 55 | 56 | function shift_cursor(left) 57 | if left then 58 | cursor_position = math.max(1, cursor_position - 1) 59 | else 60 | cursor_position = math.min(cursor_position + 1, 9) 61 | end 62 | end 63 | 64 | function current_time_as_sec(time) 65 | local sec = 0 66 | for i = 1, 9 do 67 | sec = sec + time_scale[i] * time[i] 68 | end 69 | return sec 70 | end 71 | 72 | function time_equal(lhs, rhs) 73 | for i = 1, 9 do 74 | if lhs[i] ~= rhs[i] then 75 | return false 76 | end 77 | end 78 | return true 79 | end 80 | 81 | function seek_to() 82 | copy_history_to_last() 83 | mp.commandv("osd-bar", "seek", current_time_as_sec(history[history_position]), "absolute") 84 | --deduplicate consecutive timestamps 85 | if #history == 1 or not time_equal(history[history_position], history[#history - 1]) then 86 | history[#history + 1] = {} 87 | history_position = #history 88 | end 89 | for i = 1, 9 do 90 | history[#history][i] = 0 91 | end 92 | end 93 | 94 | function backspace() 95 | if cursor_position ~= 9 or current_time[9] == 0 then 96 | shift_cursor(true) 97 | end 98 | if history[history_position][cursor_position] ~= 0 then 99 | copy_history_to_last() 100 | history[#history][cursor_position] = 0 101 | end 102 | end 103 | 104 | function history_move(up) 105 | if up then 106 | history_position = math.max(1, history_position - 1) 107 | else 108 | history_position = math.min(history_position + 1, #history) 109 | end 110 | end 111 | 112 | local key_mappings = { 113 | LEFT = function() shift_cursor(true) show_seeker() end, 114 | RIGHT = function() shift_cursor(false) show_seeker() end, 115 | UP = function() history_move(true) show_seeker() end, 116 | DOWN = function() history_move(false) show_seeker() end, 117 | BS = function() backspace() show_seeker() end, 118 | ESC = function() set_inactive() end, 119 | ENTER = function() seek_to() set_inactive() end 120 | } 121 | for i = 0, 9 do 122 | local func = function() change_number(i) show_seeker() end 123 | key_mappings[string.format("KP%d", i)] = func 124 | key_mappings[string.format("%d", i)] = func 125 | end 126 | 127 | function set_active() 128 | if not mp.get_property("seekable") then return end 129 | -- find duration of the video and set cursor position accordingly 130 | local duration = mp.get_property_number("duration") 131 | if duration ~= nil then 132 | for i = 1, 9 do 133 | if duration > time_scale[i] then 134 | cursor_position = i 135 | break 136 | end 137 | end 138 | end 139 | for key, func in pairs(key_mappings) do 140 | mp.add_forced_key_binding(key, "seek-to-"..key, func) 141 | end 142 | show_seeker() 143 | timer = mp.add_periodic_timer(timer_duration, show_seeker) 144 | active = true 145 | end 146 | 147 | function set_inactive() 148 | mp.osd_message("") 149 | for key, _ in pairs(key_mappings) do 150 | mp.remove_key_binding("seek-to-"..key) 151 | end 152 | timer:kill() 153 | active = false 154 | end 155 | 156 | mp.add_key_binding(nil, "toggle-seeker", function() if active then set_inactive() else set_active() end end) 157 | 158 | -------------------------------------------------------------------------------- /private_dot_config/aerc/binds.conf: -------------------------------------------------------------------------------- 1 | # Binds are of the form = 2 | # To use '=' in a key sequence, substitute it with "Eq": "" 3 | # If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit 4 | = :prev-tab 5 | = :prev-tab 6 | = :next-tab 7 | = :next-tab 8 | \[t = :prev-tab 9 | \]t = :next-tab 10 | = :term 11 | ? = :help keys 12 | = :prompt 'Quit?' quit 13 | = :prompt 'Quit?' quit 14 | = :suspend 15 | 16 | [messages] 17 | q = :prompt 'Quit?' quit 18 | 19 | j = :next 20 | = :next 21 | = :next 50% 22 | = :next 100% 23 | = :next 100% 24 | 25 | k = :prev 26 | = :prev 27 | = :prev 50% 28 | = :prev 100% 29 | = :prev 100% 30 | g = :select 0 31 | G = :select -1 32 | 33 | J = :next-folder 34 | = :next-folder 35 | K = :prev-folder 36 | = :prev-folder 37 | H = :collapse-folder 38 | = :collapse-folder 39 | L = :expand-folder 40 | = :expand-folder 41 | 42 | v = :mark -t 43 | = :mark -t:next 44 | V = :mark -v 45 | 46 | T = :toggle-threads 47 | zc = :fold 48 | zo = :unfold 49 | za = :fold -t 50 | zM = :fold -a 51 | zR = :unfold -a 52 | = :fold -t 53 | 54 | zz = :align center 55 | zt = :align top 56 | zb = :align bottom 57 | 58 | = :view 59 | d = :choose -o y 'Really delete this message' delete-message 60 | D = :delete 61 | a = :archive flat 62 | A = :unmark -a:mark -T:archive flat 63 | 64 | C = :compose 65 | m = :compose 66 | 67 | b = :bounce 68 | 69 | rr = :reply -a 70 | rq = :reply -aq 71 | Rr = :reply 72 | Rq = :reply -q 73 | 74 | c = :cf 75 | $ = :term 76 | ! = :term 77 | | = :pipe 78 | 79 | / = :search 80 | \ = :filter 81 | n = :next-result 82 | N = :prev-result 83 | = :clear 84 | 85 | s = :split 86 | S = :vsplit 87 | 88 | pl = :patch list 89 | pa = :patch apply 90 | pd = :patch drop 91 | pb = :patch rebase 92 | pt = :patch term 93 | ps = :patch switch 94 | 95 | [messages:folder=Drafts] 96 | = :recall 97 | 98 | [view] 99 | / = :toggle-key-passthrough/ 100 | q = :close 101 | O = :open 102 | o = :open 103 | S = :save 104 | | = :pipe 105 | D = :delete 106 | A = :archive flat 107 | 108 | = :open-link 109 | 110 | f = :forward 111 | rr = :reply -a 112 | rq = :reply -aq 113 | Rr = :reply 114 | Rq = :reply -q 115 | 116 | H = :toggle-headers 117 | = :prev-part 118 | = :prev-part 119 | = :next-part 120 | = :next-part 121 | J = :next 122 | = :next 123 | K = :prev 124 | = :prev 125 | 126 | [view::passthrough] 127 | $noinherit = true 128 | $ex = 129 | = :toggle-key-passthrough 130 | 131 | [compose] 132 | # Keybindings used when the embedded terminal is not selected in the compose 133 | # view 134 | $noinherit = true 135 | $ex = 136 | $complete = 137 | = :prev-field 138 | = :prev-field 139 | = :next-field 140 | = :next-field 141 | = :switch-account -p 142 | = :switch-account -p 143 | = :switch-account -n 144 | = :switch-account -n 145 | = :next-field 146 | = :prev-field 147 | = :prev-tab 148 | = :prev-tab 149 | = :next-tab 150 | = :next-tab 151 | 152 | [compose::editor] 153 | # Keybindings used when the embedded terminal is selected in the compose view 154 | $noinherit = true 155 | $ex = 156 | = :prev-field 157 | = :prev-field 158 | = :next-field 159 | = :next-field 160 | = :prev-tab 161 | = :prev-tab 162 | = :next-tab 163 | = :next-tab 164 | 165 | [compose::review] 166 | # Keybindings used when reviewing a message to be sent 167 | # Inline comments are used as descriptions on the review screen 168 | y = :send # Send 169 | n = :abort # Abort (discard message, no confirmation) 170 | v = :preview # Preview message 171 | p = :postpone # Postpone 172 | q = :choose -o d discard abort -o p postpone postpone # Abort or postpone 173 | e = :edit # Edit (body and headers) 174 | a = :attach # Add attachment 175 | d = :detach # Remove attachment 176 | 177 | [terminal] 178 | $noinherit = true 179 | $ex = 180 | 181 | = :prev-tab 182 | = :next-tab 183 | = :prev-tab 184 | = :next-tab 185 | -------------------------------------------------------------------------------- /private_dot_config/zsh/prompt.zsh: -------------------------------------------------------------------------------- 1 | # Load colors and enable git 2 | autoload -U colors && colors 3 | autoload -Uz vcs_info 4 | zstyle ':vcs_info:*' enable git 5 | 6 | # setup a hook that runs before every prompt. 7 | precmd_vcs_info() { vcs_info } 8 | precmd_functions+=( precmd_vcs_info ) 9 | setopt PROMPT_SUBST 10 | 11 | # add a function to check for untracked files in the directory. 12 | # from https://github.com/zsh-users/zsh/blob/master/Misc/vcs_info-examples 13 | zstyle ':vcs_info:git*+set-message:*' hooks git-untracked 14 | +vi-git-untracked(){ 15 | if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \ 16 | git status --porcelain | grep '??' &> /dev/null ; then 17 | # This will show the marker if there are any untracked files in repo. 18 | # If instead you want to show the marker only if there are untracked 19 | # files in $PWD, use: 20 | #[[ -n $(git ls-files --others --exclude-standard) ]] ; then 21 | hook_com[staged]+='!' # signify new files with a bang 22 | fi 23 | } 24 | 25 | zstyle ':vcs_info:*' actionformats \ 26 | '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f ' 27 | zstyle ':vcs_info:*' formats \ 28 | '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{5}]%f ' 29 | zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{3}%r' 30 | 31 | zstyle ':vcs_info:*' check-for-changes true 32 | zstyle ':vcs_info:git:*' formats " %{$fg[red]%}%m%u%c%{$reset_color%} %{$fg[yellow]%}%{$reset_color%}%{$fg[magenta]%}%b%{$reset_color%}" 33 | 34 | # Example of two-line ZSH prompt with four components. 35 | # 36 | # top-left top-right 37 | # bottom-left bottom-right 38 | # 39 | # Components can be customized by editing set-prompt function. 40 | # 41 | # Installation: 42 | # 43 | # (cd && curl -fsSLO https://gist.githubusercontent.com/romkatv/2a107ef9314f0d5f76563725b42f7cab/raw/two-line-prompt.zsh) 44 | # echo 'source ~/two-line-prompt.zsh' >>~/.zshrc 45 | # 46 | # Accompanying article: 47 | # https://www.reddit.com/r/zsh/comments/cgbm24/multiline_prompt_the_missing_ingredient/ 48 | # 49 | # This is only an example. If you are looking for a good ZSH prompt, 50 | # try https://github.com/romkatv/powerlevel10k/. 51 | 52 | # Usage: prompt-length TEXT [COLUMNS] 53 | # 54 | # If you run `print -P TEXT`, how many characters will be printed 55 | # on the last line? 56 | # 57 | # Or, equivalently, if you set PROMPT=TEXT with prompt_subst 58 | # option unset, on which column will the cursor be? 59 | # 60 | # The second argument specifies terminal width. Defaults to the 61 | # real terminal width. 62 | # 63 | # The result is stored in REPLY. 64 | # 65 | # Assumes that `%{%}` and `%G` don't lie. 66 | # 67 | # Examples: 68 | # 69 | # prompt-length '' => 0 70 | # prompt-length 'abc' => 3 71 | # prompt-length $'abc\nxy' => 2 72 | # prompt-length '❎' => 2 73 | # prompt-length $'\t' => 8 74 | # prompt-length $'\u274E' => 2 75 | # prompt-length '%F{red}abc' => 3 76 | # prompt-length $'%{a\b%Gb%}' => 1 77 | # prompt-length '%D' => 8 78 | # prompt-length '%1(l..ab)' => 2 79 | # prompt-length '%(!.a.)' => 1 if root, 0 if not 80 | function prompt-length() { 81 | emulate -L zsh 82 | local -i COLUMNS=${2:-COLUMNS} 83 | local -i x y=${#1} m 84 | if (( y )); then 85 | while (( ${${(%):-$1%$y(l.1.0)}[-1]} )); do 86 | x=y 87 | (( y *= 2 )) 88 | done 89 | while (( y > x + 1 )); do 90 | (( m = x + (y - x) / 2 )) 91 | (( ${${(%):-$1%$m(l.x.y)}[-1]} = m )) 92 | done 93 | fi 94 | typeset -g REPLY=$x 95 | } 96 | 97 | # Usage: fill-line LEFT RIGHT 98 | # 99 | # Sets REPLY to LEFTRIGHT with enough spaces in 100 | # the middle to fill a terminal line. 101 | function fill-line() { 102 | emulate -L zsh 103 | prompt-length $1 104 | local -i left_len=REPLY 105 | prompt-length $2 9999 106 | local -i right_len=REPLY 107 | local -i pad_len=$((COLUMNS - left_len - right_len - ${ZLE_RPROMPT_INDENT:-1})) 108 | if (( pad_len < 1 )); then 109 | # Not enough space for the right part. Drop it. 110 | typeset -g REPLY=$1 111 | else 112 | local pad=${(pl.$pad_len.. .)} # pad_len spaces 113 | typeset -g REPLY=${1}${pad}${2} 114 | fi 115 | } 116 | 117 | # Sets PROMPT and RPROMPT. 118 | # 119 | # Requires: prompt_percent and no_prompt_subst. 120 | function set-prompt() { 121 | emulate -L zsh 122 | 123 | # Print empty line before each prompt. It's easier to visually parse the 124 | # terminal is there's some visual separation between the end of a command and 125 | # next prompt. 126 | precmd() { 127 | print "" 128 | } 129 | # %F{green}, %F{blue}, %F{yellow} = change foreground color 130 | # %f = turn off foreground color 131 | # %n = $USER 132 | # %m = hostname up to first "." 133 | # %B = bold on, %b = bold off 134 | # %1~ = show 1 trailing component of working directory, or "~" if is is $HOME 135 | # %(1j.*.) = "*" if the number of jobs is at least 1 136 | # %(?..!) = "!" if the exit status of the last command was not 0 137 | # %(!.%F{yellow}%n%f.) = if root (!) show yellow $USER, otherwise nothing. 138 | # $(!.%F{yellow}.%F{red})$(printf ...) = show one ❯ per $LVL (red for root, otherwise yellow) 139 | # partially generated with: https://zsh-prompt-generator.site/ 140 | # https://github.com/k-yokoishi/zsh-prompt-generator 141 | local top_left="%B%F{105}%n%f%b@%F{158}${CONTAINER_ID:-%m}%f %B%~%b$vcs_info_msg_0_" 142 | local bottom_left='%B%F{%(?.green.red)}%(#.#.❯)%f%b ' 143 | local top_right="%*" 144 | 145 | local REPLY 146 | fill-line "$top_left" "$top_right" 147 | PROMPT=$REPLY$'\n'$bottom_left 148 | # RPROMPT=$bottom_right 149 | } 150 | 151 | setopt no_prompt_{bang,subst} prompt_{cr,percent,sp} 152 | autoload -Uz add-zsh-hook 153 | add-zsh-hook precmd set-prompt 154 | -------------------------------------------------------------------------------- /private_dot_ssh/encrypted_private_known_hosts.age: -------------------------------------------------------------------------------- 1 | -----BEGIN AGE ENCRYPTED FILE----- 2 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBidm1iTFlWWmxBTHJLWFBp 3 | OFl6NHpoMlJyUFNwR2dWclhYaW9QZXlXSW5vCnBiVFNWNk1OWXp3MGhIVFhpbU5o 4 | ZWVncXJDODFGdlVKMXovdnBXclhDaUUKLS0tIGxQYTZHOXlhOXdIelVCeVE3bmNu 5 | RmFmZ0paMnpBMFdvSCtoSEZyQWdrVUUK6ihUu6+Xti06p8ME5oeF6yI0cVMv1BKy 6 | qTkZBtYNUCYjgTJrPDrv1HUMr8uU5nM8n9E2VndtWk9iijdqj8L3BHyHzEzg0BWk 7 | 05iSzaGVBj8ox7RnTzduVggFoZexuGqpzzaanczwMCNL9jHKlKmDLKAdBE21c3if 8 | uCTgpxRvL8sdMaKApd+7zsMyo516YtrFSbOVbVUzxJUsatSfB8ZaOEOxXgK+3zf7 9 | j7Zfv2KhZA2355kqOruJJCIr+E+Qyo8Dlr1lX01W5lDCIzw8XG3vhotja+By7MoH 10 | UkE5wyNJdgxESInTpsrVLtxdletcNccS8tSixZp1LuAqpKxvDFAufVGe2QIc8p3Z 11 | jTt9wXJNkMWrV9AnGEzbUWemVx/+thkacferhJY2CO4l0jO2QTJiudazBanqB1vy 12 | YCe/9KYgwRy+dh7QSfEXmRNjv3wN7fvWQrORFxI3Tdz7/8zKmajzyi/ABuP832gN 13 | /cBv4J81y6LpO7hwZzo1jpD+eRbYw1pNFR7+WVAh1o/vht8He/VypFl9DdTqchyH 14 | lx+KM6mY8vL8LMhTP0DFs65X3bSOTpB1sAwLNtYgX0W1QuWnadTMoERCQ/lyVRZ3 15 | +h1PqHgHU8CU+vBpJs4q9vIIp8vJ7lLB/AdMMGuJNBBiqH1ryNTxJ+nbABK6k5WE 16 | Koww+W07bfmKIDl+2lTUpjsqbbmlnzkPHrKZhvOckF/Z3cb4Pz5s7FQfjEZtCthG 17 | E5XGaOhEIJTP39VBpWLirJmIUTXMIBdh2LdDzgmW8prCbMxywoO7/Z3CD2musEMH 18 | Rc8uHpwsAvDyFkX/ahdr8BwJ1QGUSq1Q7ZQVGBocywDce2j/Cr2W8vuYyEd0Urtx 19 | xOHA3NcOMtd1Qrp1G8goNL0XmTEk8/s0PyisGeFv0FowE7oxkQ+I5kVnm4sGz3MB 20 | zQ7T/0XGnYPgj+Qr3/ROlwnmkQF9yHkySu4OiDGv4TxSJYr1SWp1+vRF5DV8Gw5g 21 | Kqg2Rbce37b7g7WzY2h4hL95Un9oItpYN11hDQyrgRwIjLRWEIon1dyj5yBEgLIF 22 | 2cLNhvlCVKA8CuTKHTCno/winmoSMCDxpluUqH6ZhHvqhtV+e/X6LzzMRfGjyfWY 23 | iCMBp5GLHPLgvdYt2/D+N237HeFsy5J/O0loLUC8kTJ642H6GwiOlbK+ar34x3Q0 24 | kFBn2sF3+2saCh+U8pMvZpK7JRejWlniTyUDoqRRzlp38uDj+5tNvnW6iMT4JAHy 25 | I3l19sFJLx2ns+SgEkpSDhp4MzZytBnQ+qTR04dLgVROIAcOfjLfADz0wLApnrh8 26 | bLn0ZjivvsdbRso9K0WSo3Q3rHF8uKf1JSp8TU6g+kfZScf2IPUO7WjqCSy2t26F 27 | inaSdwabz8H00cpFxEO0t0rNzbnA6nduCN5/mnRbRzKQvHxlyCr7GDIKRsWxeCki 28 | l8lyal+znVUIekSHTKQaMN6mwTBCrd3pzUeqXx/PI78fSl/O3gCyLCkPKtbDgPOH 29 | 34SxuiLztWgWK3svOXEqYaP7CGo7b1a7YO01Um/l7VhMcgfhz0BiC9Pl/kA/2oYB 30 | Bv0r4NJxz7sQ4T7e2+ESn5hV6H91Yae3yO5aooeyBTPG6z/i/xzyFE2CGbJpiknQ 31 | Uqf3oGwbwsw2od+YNECF1IrnIg2AZvISzeH25fHDI6KFINmLw3ChgACvtPplPhAh 32 | PFI+rx7h9Z0g7N2gGxZ6FRcBr+Ngaxjw74kH/DYAU04rgYpUOiIMuxxB2oHM31IP 33 | CQFE4WFcENLgnytYhN9Oqvn81JSWqhBDnNyZptVgS8xbf8stWDRBoUO3jZvYF+Nh 34 | nOVI55Xc9ubKBhZ4PUXULG2mNkz7JfLUCUKNeOJDFPrWw+kLIiDswHFDm9JzkMhR 35 | O/7D1rE+TGgT87TvGqb/QPOgaO0Twu7MuyvPekaAbMQqSXU0XExC6Peiv/O8+kTR 36 | a8/CD7Oa58cxsbXFYrZdFgMhE9D0zw31u9lNoVrDqwrAFzbTzqIWsAOiA1NWpw+w 37 | WE/ImsLXUnJ3b1gWXV5bQvE9H0HCVjMLZuYDhj3hOqSdlbeBCqs20eZOCMpy2QZu 38 | Rz0WRhDQbg5JyiyCndZ+nvFh1K/+YF1HVU4b+S+eTrpgVGNwXaOgCK9701sdweKc 39 | D+rrxHuJQ4CZkMLC84dwK36JcwV74Vj6Kfr+qVWF0SeVtGJhokR/pXM6WdH1U8rg 40 | DSmjBNwqfd+7AorW5YxSHoqsoj89bQxXjk8sJ4i1dwcVYfNwG8xFlSpxgcWAYSc8 41 | AVx/YC7m7UffPhqyhcojLCkjJ6EpW5sO5xhWQ7Vxans10drjNspxvpzFA33EGVfH 42 | d853pAhLkz4VaKMBOxtkV72zk60xo7cve6AQGNZJpfC+7V5x2ZeO7H5ISR02Eqsn 43 | jMyUpjgDpLR/YCFVJJJbpXa/yjD6f5TFwVZpep9dcTq7oNZ+ed89wlksRxI8b8dh 44 | sWyY88e+o+KohJTNpsnFzZ0hqvtP0hXxFQLaHsQzLNvTmyhNhML6RXUCj9DjVirm 45 | m26Uin/tweP9XAkC1zj9X5XCKNBGGWoEvTTfv/X9D+5JOolfpQAgAC+FZ3MhitDb 46 | x88hqL2QrAmAEV70X19KyeuR85xfMFSBCDFb22njIokqchBDAUERsj3RwKhyLjS7 47 | iHxH4MEgZJjbvzaq5fM9c5f85iFYLdHsbFDMLibyZs3wW60MXFFs5DRjs5Amp4vp 48 | F8wZzhj8jHfo8KdHhowvW9sxVZpbywYkqCL+bLziA1nAsyU01laFfUq0aDVY1ixn 49 | kERY6ybwIuc+impELVkrSow/pOyYJGC+w46zg/p74VwGLp8kDjhhYsxwiPjmki1K 50 | K6dvBRmwVsrrmRwiXgt93J43YG71DexuUiiEmPQfERtwGhUje41JtQHMHESRavwH 51 | mVRP4lUA15xf2cE6e8jP0mtyXpTFJiMPtiJHcRg7a7M/pnlKvaihWwa3G4a0Er7I 52 | Hn7BnjwfIcFyHLtUJEryRfe7ZlJvKihA7OmWkjnOrstylig3FNBrVyDo/JgjGv9n 53 | MWKWSAQspQ8eKlRy4HyqwYU/zNIMf59BvpiAjasom5xxeoXApj+jpKbzKkyEvbMI 54 | Zml4DZvOCGdtO7jxZtaTLmfFQIwWG28HFWpNzDUQ5OksA/ARvIAeoAmEGaMIRp0E 55 | tZI7M+6LV1Aza+6e8lXW2Je7jLHyTNR8tq1iJ2nUIRF07RjBNfDpRpdQ09ACAKlO 56 | TTkOMCq4FxCYNq34O08vNG1pXgyF2zGbFOSD7xAkL098lxukYgxcLe04uyLYQSDf 57 | vnC9hhboKycoU9Ec3jZa/PVP69fGI6UOKHEPE6O0EaWV+RXHDKr/ntdeWkVGrYtc 58 | d2XGj3JJzqEALf47KQ9qz/k/0rUF3kj1Y4MEgiSe4+pdxI44BbH9SABfrWU71lyA 59 | qalVrAJfmdK82D2DQJhmLtb0nUetupFiK71ndAqWdC1mT79zZwqmbXN28OFhLf0f 60 | WfXPfAuVoC43riZRGP9668eyCn3jS+jMEhTeImS4TPgde864uYIPDeOZzYy30rQt 61 | A37lsX6R2Sy7t5SUGKaPep+q4P6Tqj4x2syXjOQVvta8WvBcFtv4K0+N+MRaEkZQ 62 | kUkMTY3v0rxjTffoU9eT4kImjqLEL4ehMMH2q31f1ctXiobhVWaL782lfOI+Mmfo 63 | MW11E2rkgMlIU4XdZdMGSylMwK2wzzsm12fA6JqIqJJTQi5CWxxrMb0Qt/cHCpxb 64 | 2Z5OTwWntp6l0MVEe4rJdp0EsEcnXyCfHITrdB+eyFNpfMVYrnGFkYI19bn6cWjP 65 | jQl7DrT9Elamcwt7Z4XbeiVSopcIGnIk/zrypAnTtVo6riFohsdcga5P3LHFjaBn 66 | UG0cpKPOWfTQhQ6pycDYhrr8BCn9hrOhYVnRPQeQqicvNl7Fr2qMQoJnX1UhA28b 67 | /bIq0d4AENV44p4Y0t+TI147pgXlSz3l2qNopxY1T8e5HyprC3QlDr15R2Pf0c4A 68 | zu+7E2u1PlsT9i1kQ6pji8W3NUf7+v7m7Ae60gG1jnMbDjr+ToI9Zevy4UFyRDQQ 69 | P9myiS8DuQThp09p+xtmaVN3P1vhkD0l6De4JWRl7MCjgbJxydowA7t13/wKcS5x 70 | VlTItEGrB+gGLeceQS06dL0Er0R5tKGSGUVwH4t8q+KcHvUtrP+1I3l5YAw/rAFp 71 | QUSp0l9wtOaPqgbm4YofpclRtMhznzNNQDzKcGSsptb8wQI30J7GabCRHS20019C 72 | BQSG9Rqs4xvIpzygw8P5qMKEE3qEwo2v7vUDk2gaheANEK4pc13epLNApYDwswvX 73 | L8UWh+H9mvYxCFV4i2CVUmJqr+kqWGcfIJm6U3dzdyYbOth8A6wbtHcTrJkvTKCz 74 | a+wpSXCZiG1+Fv6FMis5utyzeB415VPfeXmMaG2Beeo6rCdv+gwLmvoc36falIlX 75 | uV/Ob0dn7ULOlPtPpfJsqQ5huA1bfxG7ujG+O2/NZnZa5ecjQC1XckUHroePqJxn 76 | NIlUl2LNLOctTkp01ReplkZYy4Ixpb4/dRRvvdt5xO+eHVDqJ9v5sS+csgHzra3G 77 | Y/DWJ1d9M7TabWT4yc+/4H8eewxoLpMCnXeNfUvwYFWzWHFCpaVHp3MJ+5DD/6Xq 78 | zcS1/1cUnODrytkkbkPxe236QfY1PCSYBxeNk04Lsg8Or+lYfwTXLrnUzLXSm66+ 79 | h0l+MSwWuknIYtQna+/Ou+gyHL2t15/32nuqb/Tn/RZiz0VeZq5+LAbNomoyyzmN 80 | vEGdbegNYQ5sqM7mGWYMGyS0lM4xH+AyaAwCL3txXzLSa75GkEeTiNdCcuYJyPfb 81 | IRz4rNfDKnxMr9NdmjhVZqaqbTTRfv7z/seLAnTI3FOZ7XXADV59lEZRebhLvKPD 82 | alrnR3bbHt3dSRS3Ny+MyPyeRobSYiPJRn8jleGmslVf36sII1+uCKTBP5u4kT2L 83 | 0IKAumh0xqa2NWeQIe2xbGEH9byVfAS8H+fhW4DjNlaRvZ6KbFV3Em+g7MN/U9p8 84 | QPrizc8TZRyl7WXgznRyBo4EYSEAYBMTs24Un8W09Q0NoFyybdFZaQddBmWD7XgX 85 | gV9ZH0Ox431IgEv2MMLmPJPkEWylRgM/qkpG7XOtPtkbeLC8JxSqsmNeM/BYK3rW 86 | bZF2+nGbzY7hbv09UY2QJh/apf0V0y8UuXJwP3OvwyypC6EuIT/KerokjDeYgBv3 87 | IU2GNbFB4KzbMG4zkRAzF2uJnfUCn6MlY2M16DpRP3+IDvqLfCWr7aWI1Xa8L4Yz 88 | 6ktuQJ8Xl+Ke+8ngJuZlv0RCArRc+zkdSSMoheOw+ab0SqKYSnyNmw0xBxOWCpJj 89 | sldlFWnDjD6ZVCaa2RC4xqw/eWW1Ur8= 90 | -----END AGE ENCRYPTED FILE----- 91 | -------------------------------------------------------------------------------- /private_dot_config/nvim/plugin/options.lua: -------------------------------------------------------------------------------- 1 | -- Timings 2 | vim.opt.timeoutlen = 1000 -- Time to wait for a keymap to complete 3 | vim.opt.ttimeoutlen = 300 -- Time to wait for a key code sequence to complete 4 | vim.opt.updatetime = 400 -- If nothing is typed is this time, swap file will be written. Also used for 'CursorHold' autocommand 5 | 6 | -- Window splitting 7 | vim.opt.splitbelow = true -- Horizontal splits will be below 8 | vim.opt.splitright = true -- Vertical splits will be to the right 9 | vim.opt.splitkeep = "screen" -- Keep the text on same line when resizing, closing... 10 | 11 | -- Diff options 12 | vim.opt.diffopt = { 13 | "internal", -- Use internal diff library (indent-heuristic). Ignored when diffexpr is set 14 | "filler", -- Show filler lines to keep text synchronized with window that has inserted lines in same place 15 | "closeoff", -- Disable diff mode when last window is closed 16 | "indent-heuristic", -- indent heuristic for internal diff library 17 | -- TODO: enable on 0.12 18 | -- "inline:char", -- Highlight inline differences character-wise 19 | "linematch:60", -- Align and mark changes between the most similar lines between buffers 20 | "algorithm:patience", -- Diff algorithm for internal diff engine 21 | "vertical", -- Start diff mode in vertical splits 22 | } 23 | 24 | -- Message output on vim acctions 25 | vim.opt.shortmess = { 26 | f = true, -- "(3 of 5)" instead of "(file 3 of 5)" 27 | i = true, -- "[noeol]" instead of "[Incomplete last line]" 28 | l = true, -- "999L, 888B" instead of "999 lines, 888 bytes" 29 | m = true, -- "[+]" instead of "[Modified]" 30 | n = true, -- "[New]" instead of "[New File]" 31 | x = true, -- "[unix]" instead if "[unix format]", same with other os's 32 | s = true, -- don't give "search hit BOTTOM, continuing at TOP" 33 | t = true, -- truncate file message if it is too long 34 | A = true, -- Ignore swap file messages 35 | } 36 | 37 | -- Display 38 | vim.opt.scrolloff = 2 -- Minimal number of lines to keep above/below the cursor 39 | vim.opt.signcolumn = "yes:2" -- show always, with fixed space for signs up to the given number (2) 40 | vim.opt.termguicolors = true -- Enables 24-bit RGB color in the TUI 41 | vim.opt.title = true -- When on, the title of the window will be `filename [+= -] (path) - Nvim` or to value of titlestring if not empty 42 | vim.opt.confirm = true -- Save me from doing destructive things 43 | vim.opt.showmode = false -- When in insert, show mode in last line 44 | vim.opt.pumheight = 15 -- Maximum number of items to show in the popup menu 45 | vim.opt.mouse = "a" -- Enables mouse support 46 | vim.opt.winborder = "rounded" -- Default border style for floating windows 47 | 48 | -- Completion 49 | vim.opt.completeopt = "menuone,fuzzy,popup,noselect" 50 | vim.opt.wildoptions = "pum,fuzzy" -- A list of words that change how cmdline-completion is done. 51 | 52 | -- Indentetion 53 | vim.opt.wrap = false 54 | vim.opt.expandtab = true -- Insert spaces instead of tabs on 55 | vim.opt.softtabstop = 4 56 | vim.opt.shiftwidth = 4 57 | vim.opt.virtualedit = "block" -- Allow the cursor be positioned where there is no actual character 58 | 59 | -- Numbers and lines 60 | vim.opt.number = true 61 | vim.opt.cursorline = true 62 | 63 | -- Match and Search 64 | vim.opt.ignorecase = true 65 | vim.opt.smartcase = true 66 | 67 | -- List Chars 68 | vim.opt.list = true 69 | vim.opt.fillchars = { 70 | eob = " ", -- supress ~ at EndOfBuffer 71 | diff = "/", 72 | } 73 | vim.opt.listchars = { 74 | trail = "•", 75 | -- eol = "↴", 76 | tab = "» ", 77 | extends = "…", 78 | precedes = "…", 79 | nbsp = "␣", 80 | space = nil, 81 | } 82 | 83 | -- Session options 84 | vim.opt.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal,localoptions,globals" 85 | vim.opt.exrc = true -- Enable project local configuration 86 | 87 | -- Use rg as grep program 88 | if vim.fn.executable "rg" > 0 then 89 | vim.opt.grepprg = [[rg --glob "!.git" --vimgrep --no-heading --smart-case --hidden]] 90 | end 91 | vim.opt.grepformat = "%f:%l:%c:%m" 92 | 93 | -- Folds 94 | vim.opt.foldlevelstart = 5 95 | vim.opt.foldmethod = "expr" 96 | vim.opt.foldtext = "" -- show original text with its syntax highlighting 97 | 98 | -- BACKUP AND SWAP 99 | vim.opt.swapfile = false 100 | vim.opt.undofile = true 101 | 102 | -- Lua version of `help fuzzy-file-picker` 103 | ---@param arg string 104 | ---@return string[] 105 | _G.fuzzy_find = function(arg, _) 106 | local paths = vim.fn.globpath(".", "**", true, true) 107 | local fuzzy_filescache = vim.tbl_filter(function(path) 108 | if vim.fn.isdirectory(path) then 109 | return true 110 | end 111 | return false 112 | end, paths) 113 | 114 | fuzzy_filescache = vim.tbl_map(function(path) return vim.fn.fnamemodify(path, ":.") end, fuzzy_filescache) 115 | 116 | if not arg or arg == "" then 117 | return fuzzy_filescache 118 | end 119 | return vim.fn.matchfuzzy(fuzzy_filescache, arg) 120 | end 121 | vim.opt.findfunc = "v:lua.fuzzy_find" 122 | 123 | -- Wild and file globbing stuff 124 | vim.opt.wildignorecase = true -- Ignore case when completing file names and directories 125 | vim.opt.path = ".,**,," 126 | vim.opt.wildignore = { 127 | "*.aux", 128 | "*.out", 129 | "*.toc", 130 | "*.o", 131 | "*.obj", 132 | "*.dll", 133 | "*.jar", 134 | "*.pyc", 135 | "*.rbc", 136 | "*.class", 137 | "*.gif", 138 | "*.ico", 139 | "*.jpg", 140 | "*.jpeg", 141 | "*.png", 142 | "*.avi", 143 | "*.wav", 144 | "*.webm", 145 | "*.eot", 146 | "*.otf", 147 | "*.ttf", 148 | "*.woff", 149 | "*.doc", 150 | "*.pdf", 151 | "*.zip", 152 | "*.tar.gz", 153 | "*.tar.bz2", 154 | "*.rar", 155 | "*.tar.xz", 156 | -- Cache 157 | ".sass-cache", 158 | "*/vendor/gems/*", 159 | "*/vendor/cache/*", 160 | "*/.bundle/*", 161 | "*.gem", 162 | -- Temp/System 163 | "*.*~", 164 | "*~ ", 165 | "*.swp", 166 | ".lock", 167 | ".DS_Store", 168 | "._*", 169 | "tags.lock", 170 | } 171 | -------------------------------------------------------------------------------- /private_dot_config/zsh/plugins/menu.zsh: -------------------------------------------------------------------------------- 1 | # Add zsh-completions to $fpath. 2 | fpath=("${0:h}/external/src" $fpath) 3 | 4 | # 5 | # Options 6 | # 7 | 8 | setopt COMPLETE_IN_WORD # Complete from both ends of a word. 9 | setopt ALWAYS_TO_END # Move cursor to the end of a completed word. 10 | setopt PATH_DIRS # Perform path search even on command names with slashes. 11 | setopt AUTO_MENU # Show completion menu on a successive tab press. 12 | setopt AUTO_LIST # Automatically list choices on ambiguous completion. 13 | setopt AUTO_PARAM_SLASH # If completed parameter is a directory, add a trailing slash. 14 | setopt EXTENDED_GLOB # Needed for file modification glob modifiers with compinit 15 | unsetopt MENU_COMPLETE # Do not autoselect the first completion entry. 16 | unsetopt FLOW_CONTROL # Disable start/stop characters in shell editor. 17 | 18 | # Generic options completion 19 | # https://github.com/junegunn/fzf/issues/3349 20 | compdef _gnu_generic fzf msmtp age 21 | 22 | # 23 | # Styles 24 | # 25 | 26 | # Use caching to make completion for commands such as dpkg and apt usable. 27 | zstyle ':completion::complete:*' use-cache on 28 | zstyle ':completion::complete:*' cache-path "$XDG_CACHE_HOME/zcompcache" 29 | 30 | # Color completion for some things. 31 | # http://linuxshellaccount.blogspot.com/2008/12/color-completion-using-zsh-modules-on.html 32 | zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} 33 | 34 | # Case-insensitive (all), partial-word, and then substring completion. 35 | zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' 36 | unsetopt CASE_GLOB 37 | 38 | # Group matches and describe. 39 | zstyle ':completion:*:*:*:*:*' menu select 40 | zstyle ':completion:*:matches' group 'yes' 41 | zstyle ':completion:*:options' description 'yes' 42 | zstyle ':completion:*:options' auto-description '%d' 43 | zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f' 44 | zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f' 45 | zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f' 46 | zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f' 47 | zstyle ':completion:*:default' list-prompt '%S%M matches%s' 48 | zstyle ':completion:*' format ' %F{yellow}-- %d --%f' 49 | zstyle ':completion:*' group-name '' 50 | zstyle ':completion:*' verbose yes 51 | 52 | # Fuzzy match mistyped completions. 53 | zstyle ':completion:*' completer _complete _match _approximate 54 | zstyle ':completion:*:match:*' original only 55 | zstyle ':completion:*:approximate:*' max-errors 1 numeric 56 | 57 | # Increase the number of errors based on the length of the typed word. But make 58 | # sure to cap (at 7) the max-errors to avoid hanging. 59 | zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3>7?7:($#PREFIX+$#SUFFIX)/3))numeric)' 60 | 61 | # Don't complete unavailable commands. 62 | zstyle ':completion:*:functions' ignored-patterns '(_*|pre(cmd|exec))' 63 | 64 | # Array completion element sorting. 65 | zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters 66 | 67 | # Directories 68 | zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} 69 | zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories 70 | zstyle ':completion:*:*:cd:*:directory-stack' menu yes select 71 | zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand' 72 | zstyle ':completion:*' squeeze-slashes true 73 | zstyle ':completion:*' file-sort modification 74 | zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls --color $realpath' 75 | 76 | # # History 77 | # zstyle ':completion:*:history-words' stop yes 78 | # zstyle ':completion:*:history-words' remove-all-dups yes 79 | # zstyle ':completion:*:history-words' list false 80 | # zstyle ':completion:*:history-words' menu yes 81 | 82 | # Environment Variables 83 | zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-} 84 | 85 | # Populate hostname completion. But allow ignoring custom entries from static 86 | # */etc/hosts* which might be uninteresting. 87 | zstyle -e ':completion:*:hosts' hosts 'reply=( 88 | ${=${=${=${${(f)"$(cat {/etc/ssh/ssh_,~/.ssh/}known_hosts(|2)(N) 2> /dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ } 89 | ${=${(f)"$(cat /etc/hosts(|)(N) <<(ypcat hosts 2> /dev/null))"}%%(\#${_etc_host_ignores:+|${(j:|:)~_etc_host_ignores}})*} 90 | ${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2> /dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}} 91 | )' 92 | 93 | # Don't complete uninteresting users... 94 | zstyle ':completion:*:*:*:users' ignored-patterns \ 95 | adm amanda apache avahi beaglidx bin cacti canna clamav daemon \ 96 | dbus distcache dovecot fax ftp games gdm gkrellmd gopher \ 97 | hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \ 98 | mailman mailnull mldonkey mysql nagios \ 99 | named netdump news nfsnobody nobody nscd ntp nut nx openvpn \ 100 | operator pcap postfix postgres privoxy pulse pvm quagga radvd \ 101 | rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs '_*' 102 | 103 | # ... unless we really want to. 104 | # zstyle '*' single-ignored show 105 | 106 | # Ignore multiple entries. 107 | zstyle ':completion:*:(rm|kill|diff):*' ignore-line other 108 | zstyle ':completion:*:rm:*' file-patterns '*:all-files' 109 | 110 | # Kill 111 | zstyle ':completion:*:*:*:*:processes' command 'ps -u $LOGNAME -o pid,user,command -w' 112 | zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01' 113 | zstyle ':completion:*:*:kill:*' menu yes select 114 | zstyle ':completion:*:*:kill:*' force-list always 115 | zstyle ':completion:*:*:kill:*' insert-ids single 116 | 117 | # Man 118 | zstyle ':completion:*:manuals' separate-sections true 119 | zstyle ':completion:*:manuals.(^1*)' insert-sections true 120 | 121 | # SSH/SCP/RSYNC 122 | zstyle ':completion:*:(ssh|scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *' 123 | zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr 124 | zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr 125 | zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost 126 | zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*' 127 | zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*' 128 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/configs/mini.lua: -------------------------------------------------------------------------------- 1 | require "configs.statusline" 2 | require("mini.align").setup() 3 | require("mini.icons").setup() 4 | require("mini.bracketed").setup() 5 | require("mini.completion").setup({ 6 | mappings = { 7 | scroll_down = "", 8 | scroll_up = "", 9 | } 10 | }) 11 | require("mini.cmdline").setup({ 12 | autocorrect = { 13 | enable = false, 14 | } 15 | }) 16 | 17 | -- Enhance text objects 18 | local ai = require "mini.ai" 19 | ai.setup { 20 | n_lines = 10, 21 | mappings = { around_last = "", inside_last = "" }, 22 | custom_textobjects = { 23 | i = ai.gen_spec.treesitter({ a = "@conditional.outer", i = "@conditional.inner" }, {}), 24 | f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }, {}), 25 | c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}), 26 | }, 27 | } 28 | 29 | local hipatterns = require('mini.hipatterns') 30 | hipatterns.setup { 31 | highlighters = { 32 | fixme = { pattern = "FIXME", group = "MiniHipatternsFixme" }, 33 | hack = { pattern = "HACK", group = "MiniHipatternsHack" }, 34 | todo = { pattern = "TODO", group = "MiniHipatternsTodo" }, 35 | note = { pattern = "NOTE", group = "MiniHipatternsNote" }, 36 | 37 | -- Highlight hex color strings (`#rrggbb`) using that color 38 | hex_color = hipatterns.gen_highlighter.hex_color(), 39 | }, 40 | } 41 | 42 | require("mini.surround").setup { 43 | mappings = { 44 | add = "ys", -- Add surrounding in Normal and Visual modes 45 | delete = "ds", -- Delete surrounding 46 | replace = "cs", -- Replace surrounding 47 | find = "", -- Find surrounding (to the right) 48 | find_left = "", -- Find surrounding (to the left) 49 | highlight = "", -- Highlight surrounding 50 | }, 51 | } 52 | 53 | -- Git 54 | local git = require "mini.git" 55 | git.setup {} 56 | vim.cmd.cnoreabbrev "G Git" 57 | 58 | require("mini.diff").setup { 59 | view = { 60 | style = "sign", 61 | signs = { add = "+", change = "~", delete = "-" } 62 | }, 63 | } 64 | 65 | vim.api.nvim_create_autocmd({ "FileType" }, { 66 | pattern = { "git", "diff" }, 67 | callback = function(args) 68 | if not vim.api.nvim_buf_is_valid(args.buf) then 69 | return 70 | end 71 | local buf_name = vim.api.nvim_buf_get_name(args.buf) 72 | if not vim.startswith(buf_name, "minigit://") then 73 | return 74 | end 75 | 76 | vim.wo.foldmethod = "expr" 77 | vim.wo.foldexpr = "v:lua.MiniGit.diff_foldexpr()" 78 | 79 | vim.keymap.set({ "n", "x" }, "K", git.show_at_cursor, { buffer = args.buf, desc = "Show git data" }) 80 | vim.keymap.set({ "n", "x" }, "gd", git.show_diff_source, { buffer = args.buf, desc = "Go to git source" }) 81 | end, 82 | }) 83 | vim.keymap.set("n", "gt", require("mini.diff").toggle_overlay, { desc = "toggle diff overlay" }) 84 | vim.keymap.set("n", "gs", ":Git add -- %", { desc = "stage buffer" }) 85 | vim.keymap.set("n", "gu", ":Git restore --staged -- %", { desc = "unstage buffer" }) 86 | vim.keymap.set("n", "gl", ":Git lg", { desc = "log oneline" }) 87 | vim.keymap.set("n", "gf", ":Git log --patch -- %", { desc = "full log patch (buffer)" }) 88 | vim.keymap.set("n", "gF", ":Git log --patch", { desc = "full log patch" }) 89 | vim.keymap.set("n", "gd", ":Git diff -- %", { desc = "diff (buffer)" }) 90 | vim.keymap.set("n", "gD", ":Git diff", { desc = "diff" }) 91 | 92 | -- Snippets 93 | local snippets = require "mini.snippets" 94 | local gen_loader = snippets.gen_loader 95 | 96 | local match_strict = function(snips) 97 | -- Do not match with whitespace to cursor's left 98 | return snippets.default_match(snips, { pattern_fuzzy = "%S+" }) 99 | end 100 | 101 | snippets.setup { 102 | snippets = { 103 | gen_loader.from_file(vim.fn.stdpath "config" .. "/snippets/global.json"), 104 | gen_loader.from_lang(), 105 | }, 106 | mappings = { expand = "", jump_next = "", jump_prev = "" }, 107 | expand = { match = match_strict }, 108 | } 109 | 110 | local expand_or_jump = function() 111 | local can_expand = #snippets.expand { insert = false } > 0 112 | if can_expand then 113 | vim.schedule(snippets.expand) 114 | return "" 115 | end 116 | local is_active = snippets.session.get() ~= nil 117 | if is_active then 118 | snippets.session.jump "next" 119 | return "" 120 | end 121 | return "\t" 122 | end 123 | 124 | local jump_prev = function() snippets.session.jump "prev" end 125 | 126 | vim.keymap.set("i", "", expand_or_jump, { expr = true }) 127 | vim.keymap.set("i", "", jump_prev) 128 | 129 | -- Clues 130 | local miniclue = require "mini.clue" 131 | miniclue.setup { 132 | window = { 133 | delay = 200, 134 | }, 135 | triggers = { 136 | -- Leader triggers 137 | { mode = "n", keys = "" }, 138 | { mode = "x", keys = "" }, 139 | 140 | -- `[` and `]` keys 141 | { mode = "n", keys = "[" }, 142 | { mode = "n", keys = "]" }, 143 | 144 | -- Built-in completion 145 | { mode = "i", keys = "" }, 146 | 147 | -- `g` key 148 | { mode = "n", keys = "g" }, 149 | { mode = "x", keys = "g" }, 150 | 151 | -- Marks 152 | { mode = "n", keys = "'" }, 153 | { mode = "n", keys = "`" }, 154 | { mode = "x", keys = "'" }, 155 | { mode = "x", keys = "`" }, 156 | 157 | -- Registers 158 | { mode = "n", keys = '"' }, 159 | { mode = "x", keys = '"' }, 160 | { mode = "i", keys = "" }, 161 | { mode = "c", keys = "" }, 162 | 163 | -- Window commands 164 | { mode = "n", keys = "" }, 165 | 166 | -- `z` key 167 | { mode = "n", keys = "z" }, 168 | { mode = "x", keys = "z" }, 169 | 170 | -- coerce plugin ./plugin/coerce.lua 171 | { mode = "v", keys = "cr" }, 172 | { mode = "n", keys = "cr" }, 173 | }, 174 | clues = { 175 | miniclue.gen_clues.square_brackets(), 176 | miniclue.gen_clues.builtin_completion(), 177 | miniclue.gen_clues.g(), 178 | miniclue.gen_clues.marks(), 179 | miniclue.gen_clues.registers(), 180 | miniclue.gen_clues.windows(), 181 | miniclue.gen_clues.z(), 182 | }, 183 | } 184 | -------------------------------------------------------------------------------- /private_dot_config/vis/commentary.lua: -------------------------------------------------------------------------------- 1 | -- https://github.com/lutobler/vis-commentary/blob/master/init.lua 2 | local comment_string = { 3 | actionscript = "//", 4 | ada = "--", 5 | ansi_c = "/*|*/", 6 | antlr = "//", 7 | apdl = "!", 8 | apl = "#", 9 | applescript = "--", 10 | asp = "'", 11 | autoit = ";", 12 | awk = "#", 13 | b_lang = "//", 14 | bash = "#", 15 | batch = ":", 16 | bibtex = "%", 17 | boo = "#", 18 | chuck = "//", 19 | cmake = "#", 20 | coffeescript = "#", 21 | context = "%", 22 | cpp = "//", 23 | crystal = "#", 24 | csharp = "//", 25 | css = "/*|*/", 26 | cuda = "//", 27 | dart = "//", 28 | desktop = "#", 29 | django = "{#|#}", 30 | dmd = "//", 31 | dockerfile = "#", 32 | dot = "//", 33 | eiffel = "--", 34 | elixir = "#", 35 | erlang = "%", 36 | faust = "//", 37 | fish = "#", 38 | forth = "|\\", 39 | fortran = "!", 40 | fsharp = "//", 41 | gap = "#", 42 | gettext = "#", 43 | gherkin = "#", 44 | glsl = "//", 45 | gnuplot = "#", 46 | go = "//", 47 | groovy = "//", 48 | gtkrc = "#", 49 | haskell = "--", 50 | html = "", 51 | icon = "#", 52 | idl = "//", 53 | inform = "!", 54 | ini = "#", 55 | Io = "#", 56 | java = "//", 57 | javascript = "//", 58 | json = "/*|*/", 59 | jsp = "//", 60 | latex = "%", 61 | ledger = "#", 62 | less = "//", 63 | lilypond = "%", 64 | lisp = ";", 65 | logtalk = "%", 66 | lua = "--", 67 | makefile = "#", 68 | markdown = "", 69 | matlab = "#", 70 | moonscript = "--", 71 | myrddin = "//", 72 | nemerle = "//", 73 | nsis = "#", 74 | objective_c = "//", 75 | pascal = "//", 76 | perl = "#", 77 | php = "//", 78 | pico8 = "//", 79 | pike = "//", 80 | pkgbuild = "#", 81 | prolog = "%", 82 | props = "#", 83 | protobuf = "//", 84 | ps = "%", 85 | pure = "//", 86 | python = "#", 87 | rails = "#", 88 | rc = "#", 89 | rebol = ";", 90 | rest = ".. ", 91 | rexx = "--", 92 | rhtml = "", 93 | rstats = "#", 94 | ruby = "#", 95 | rust = "//", 96 | sass = "//", 97 | scala = "//", 98 | scheme = ";", 99 | smalltalk = '"|"', 100 | sml = "(*)", 101 | snobol4 = "#", 102 | sql = "#", 103 | tcl = "#", 104 | tex = "%", 105 | text = "", 106 | toml = "#", 107 | vala = "//", 108 | vb = "'", 109 | vbscript = "'", 110 | verilog = "//", 111 | vhdl = "--", 112 | wsf = "", 113 | xml = "", 114 | yaml = "#", 115 | } 116 | 117 | -- escape all magic characters with a '%' 118 | local function esc(str) 119 | if not str then 120 | return "" 121 | end 122 | return ( 123 | str 124 | :gsub("%%", "%%%%") 125 | :gsub("^%^", "%%^") 126 | :gsub("%$$", "%%$") 127 | :gsub("%(", "%%(") 128 | :gsub("%)", "%%)") 129 | :gsub("%.", "%%.") 130 | :gsub("%[", "%%[") 131 | :gsub("%]", "%%]") 132 | :gsub("%*", "%%*") 133 | :gsub("%+", "%%+") 134 | :gsub("%-", "%%-") 135 | :gsub("%?", "%%?") 136 | ) 137 | end 138 | 139 | -- escape '%' 140 | local function pesc(str) 141 | if not str then 142 | return "" 143 | end 144 | return str:gsub("%%", "%%%%") 145 | end 146 | 147 | function rtrim(s) 148 | local n = #s 149 | while n > 0 and s:find("^%s", n) do 150 | n = n - 1 151 | end 152 | return s:sub(1, n) 153 | end 154 | 155 | local function comment_line(lines, lnum, prefix, suffix) 156 | if suffix ~= "" then 157 | suffix = " " .. suffix 158 | end 159 | lines[lnum] = string.gsub(lines[lnum], "(%s*)(.*)", "%1" .. pesc(prefix) .. " %2" .. pesc(suffix)) 160 | end 161 | 162 | local function uncomment_line(lines, lnum, prefix, suffix) 163 | local match_str = "^(%s*)" .. esc(prefix) .. "%s?(.*)" .. esc(suffix) 164 | m = table.pack(lines[lnum]:match(match_str)) 165 | lines[lnum] = m[1] .. rtrim(m[2]) 166 | end 167 | 168 | local function is_comment(line, prefix) 169 | return (line:match("^%s*(.+)"):sub(0, #prefix) == prefix) 170 | end 171 | 172 | local function toggle_line_comment(lines, lnum, prefix, suffix) 173 | if not lines or not lines[lnum] then 174 | return 175 | end 176 | if not lines[lnum]:match("^%s*(.+)") then 177 | return 178 | end -- ignore empty lines 179 | if is_comment(lines[lnum], prefix) then 180 | uncomment_line(lines, lnum, prefix, suffix) 181 | else 182 | comment_line(lines, lnum, prefix, suffix) 183 | end 184 | end 185 | 186 | -- if one line inside the block is not a comment, comment the block. 187 | -- only uncomment, if every single line is comment. 188 | local function block_comment(lines, a, b, prefix, suffix) 189 | local uncomment = true 190 | for i = a, b do 191 | if lines[i]:match("^%s*(.+)") and not is_comment(lines[i], prefix) then 192 | uncomment = false 193 | end 194 | end 195 | 196 | if uncomment then 197 | for i = a, b do 198 | if lines[i]:match("^%s*(.+)") then 199 | uncomment_line(lines, i, prefix, suffix) 200 | end 201 | end 202 | else 203 | for i = a, b do 204 | if lines[i]:match("^%s*(.+)") then 205 | comment_line(lines, i, prefix, suffix) 206 | end 207 | end 208 | end 209 | end 210 | 211 | vis:map(vis.modes.NORMAL, "gcc", function() 212 | local win = vis.win 213 | local lines = win.file.lines 214 | local comment = comment_string[win.syntax] 215 | if not comment then 216 | return 217 | end 218 | local prefix, suffix = comment:match("^([^|]+)|?([^|]*)$") 219 | if not prefix then 220 | return 221 | end 222 | 223 | for sel in win:selections_iterator() do 224 | local lnum = sel.line 225 | local col = sel.col 226 | 227 | toggle_line_comment(lines, lnum, prefix, suffix) 228 | sel:to(lnum, col) -- restore cursor position 229 | end 230 | 231 | win:draw() 232 | end, "Toggle comment on a the current line") 233 | 234 | local function visual_f(i) 235 | return function() 236 | local win = vis.win 237 | local lines = win.file.lines 238 | 239 | local comment = comment_string[win.syntax] 240 | if not comment then 241 | return 242 | end 243 | 244 | local prefix, suffix = comment:match("^([^|]+)|?([^|]*)$") 245 | if not prefix then 246 | return 247 | end 248 | 249 | for sel in win:selections_iterator() do 250 | local r = sel.range 251 | local lnum = sel.line -- line number of cursor 252 | local col = sel.col -- column of cursor 253 | 254 | if sel.anchored and r then 255 | sel.pos = r.start 256 | local a = sel.line 257 | sel.pos = r.finish 258 | local b = sel.line - i 259 | 260 | block_comment(lines, a, b, prefix, suffix) 261 | 262 | sel:to(lnum, col) -- restore cursor position 263 | end 264 | end 265 | 266 | win:draw() 267 | vis.mode = vis.modes.NORMAL -- go to normal mode 268 | end 269 | end 270 | 271 | vis:map(vis.modes.VISUAL_LINE, "gc", visual_f(1), "Toggle comment on the selected lines") 272 | vis:map(vis.modes.VISUAL, "gc", visual_f(0), "Toggle comment on the selected lines") 273 | -------------------------------------------------------------------------------- /private_dot_config/shell/profile: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | # shellcheck disable=SC2155 3 | # SC2155: Declare and assign separately to avoid masking return values. 4 | 5 | ############################################################ 6 | # Path # 7 | ############################################################ 8 | export PATH="$PATH:$(find ~/.local/bin -type d | paste -sd ':' -)" 9 | 10 | ############################################################ 11 | # XDG PATHS # 12 | ############################################################ 13 | export XDG_DATA_HOME="${XDG_DATA_HOME:="$HOME/.local/share"}" 14 | export XDG_CACHE_HOME="${XDG_CACHE_HOME:="$HOME/.cache"}" 15 | export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:="$HOME/.config"}" 16 | export XDG_STATE_HOME="${XDG_STATE_HOME:="$HOME/.local/state"}" 17 | 18 | ############################################################ 19 | # Defaults # 20 | ############################################################ 21 | export EDITOR="nvim" 22 | export VISUAL="nvim" 23 | export MANPAGER='nvim +Man!' 24 | export MANWIDTH=120 25 | export TERMINAL="ghostty" 26 | export BROWSER="firefox" 27 | export VIDEO="mpv" 28 | export COLORTERM="truecolor" 29 | export HOSTNAME="$(uname -n)" 30 | 31 | ############################################################ 32 | # Dotfiles # 33 | ############################################################ 34 | export DOTFILES="${XDG_DATA_HOME:-$HOME/.local/share}/chezmoi" 35 | export NVIMRC="${DOTFILES:-$HOME/.local/share/chezmoi}/private_dot_config/nvim" 36 | export ZK_NOTEBOOK_DIR="$HOME/Documents/notes" 37 | export MAILDIR="$XDG_DATA_HOME/maildir" 38 | 39 | ######################################################################################## 40 | # Others programs: # 41 | # - Fix cluttering since a lot of programs just put stuff in ~ # 42 | # Most of these were taken from: https://wiki.archlinux.org/title/XDG_Base_Directory # 43 | # - Add some bin folders to PATH from package managers like npm, cargo, go, etc # 44 | ######################################################################################## 45 | # GTK 46 | export GTK2_RC_FILES="$XDG_CONFIG_HOME"/gtk-2.0/gtkrc 47 | # WGET 48 | export WGETRC="${XDG_CONFIG_HOME:-$HOME/.config}/wget/wgetrc" 49 | # Disable less history files 50 | export LESSHISTFILE=- 51 | # Wine 52 | export WINEPREFIX="${XDG_DATA_HOME:-$HOME/.local/share}/wineprefixes/default" 53 | # Inputrc 54 | export INPUTRC="$XDG_CONFIG_HOME"/readline/inputrc 55 | # SQLite 56 | export SQLITE_HISTORY="$XDG_DATA_HOME"/sqlite_history 57 | # W3M 58 | export W3M_DIR="$XDG_STATE_HOME/w3m" 59 | # Pass 60 | export PASSWORD_STORE_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/password-store" 61 | # GPG 62 | export GNUPGHOME="$XDG_DATA_HOME"/gnupg 63 | export GPG_TTY="$(tty)" 64 | # Go 65 | export GOPATH="$XDG_DATA_HOME"/go 66 | export PATH="$PATH":"$GOPATH"/bin 67 | # Docker 68 | export DOCKER_CONFIG="$XDG_CONFIG_HOME"/docker 69 | export MACHINE_STORAGE_PATH="$XDG_DATA_HOME"/docker-machine 70 | # Haskell 71 | export GHCUP_INSTALL_BASE_PREFIX="$XDG_DATA_HOME" 72 | export PATH="$PATH":"$GHCUP_INSTALL_BASE_PREFIX"/.ghcup/bin 73 | # Julia 74 | export JULIA_DEPOT_PATH="$XDG_DATA_HOME/julia:$JULIA_DEPOT_PATH" 75 | export JULIAUP_DEPOT_PATH="$XDG_DATA_HOME/julia" 76 | # Rust 77 | export CARGO_HOME="$XDG_DATA_HOME"/cargo 78 | export PATH="$PATH":"$CARGO_HOME"/bin 79 | export RUSTUP_HOME="$XDG_DATA_HOME"/rustup 80 | # Java 81 | export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME"/java 82 | export JAVA_HOME="$(readlink -f /usr/bin/java | sed "s:/bin/java::")" 83 | export GRADLE_USER_HOME="$XDG_DATA_HOME"/gradle 84 | # Node, NPM 85 | export PATH="$PATH":"$XDG_DATA_HOME"/npm/bin 86 | export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME"/npm/npmrc 87 | export NVM_DIR="$XDG_DATA_HOME"/nvm 88 | export NODE_REPL_HISTORY="$XDG_DATA_HOME"/node_repl_history 89 | # Android 90 | export ADB_VENDOR_KEY="$XDG_CONFIG_HOME"/android 91 | export ANDROID_PREFS_ROOT="$XDG_CONFIG_HOME"/android 92 | export ADB_KEYS_PATH="$ANDROID_PREFS_ROOT" 93 | export ANDROID_EMULATOR_HOME="$XDG_DATA_HOME"/android/emulator 94 | export ANDROID_HOME="$XDG_DATA_HOME"/android 95 | export ANDROID_USER_HOME="$XDG_DATA_HOME"/android 96 | # Python 97 | export PYLINTHOME="${XDG_DATA_HOME:-$HOME/.local/share}"/pylint 98 | export PYTHON_EGG_CACHE="$XDG_CACHE_HOME"/python-eggs 99 | export PYTHONSTARTUP="$XDG_CONFIG_HOME"/python/config.py 100 | export RYE_HOME="$XDG_DATA_HOME"/rye 101 | export PYENV_ROOT="$XDG_DATA_HOME"/pyenv 102 | export PYTHON_HISTORY="$XDG_STATE_HOME"/python_history 103 | export PYTHONPYCACHEPREFIX="$XDG_CACHE_HOME"/python 104 | export PYTHONUSERBASE="$XDG_DATA_HOME"/python 105 | 106 | ############################################################ 107 | # ZSH # 108 | ############################################################ 109 | # word split 110 | # Delete up until `/` with , specially useful when typing paths and need to 111 | # correct just a single section, but by default doing deletes the entire 112 | # "word" Delete up until `.` and `-` and `_`, usefule for filenames separated by 113 | # `-` and `_` and to change file extensions by deleting only up until `.` 114 | # default: *?_-.[]~=/&;!#$%^(){}<> 115 | # source: https://unix.stackexchange.com/questions/48577/modifying-the-zsh-shell-word-split 116 | # source: https://apple.stackexchange.com/questions/382126/partially-delete-path-in-zsh-option-backspace 117 | export WORDCHARS="*?[]~=&;!#$%^(){}<>" 118 | 119 | ############################################################ 120 | # FZF # 121 | ############################################################ 122 | FZF_BINDS="--bind f4:toggle-preview \ 123 | --bind ctrl-d:preview-half-page-down \ 124 | --bind ctrl-u:preview-half-page-up \ 125 | --bind 'ctrl-y:execute-silent(wl-copy {})' \ 126 | --bind alt-a:toggle-all \ 127 | --bind ctrl-n:down \ 128 | --bind ctrl-p:up \ 129 | --bind ctrl-j:next-history \ 130 | --bind ctrl-k:previous-history \ 131 | --history='$HOME/.local/share/fzf_history' 132 | " 133 | 134 | FZF_DISPLAY="--layout=reverse --border=bold --multi --height=60% --style=full" 135 | 136 | if [ -x "$(command -v bat)" ]; then 137 | FZF_PREVIEW="--preview 'bat --color=always --line-range :50 {}' --preview-border=bold" 138 | else 139 | FZF_PREVIEW="--preview 'cat {}'" 140 | fi 141 | 142 | if [ -x "$(command -v fd)" ]; then 143 | FD_COMMAND='fd --strip-cwd-prefix --hidden --exclude=\*.git/\* --type=file' 144 | FZF_T_OPTS=" 145 | --bind 'ctrl-g:transform:[[ ! \$FZF_PROMPT == \" > \" ]] && 146 | echo \"rebind(ctrl-g)+change-prompt( > )+reload($FD_COMMAND --no-ignore)\" || 147 | echo \"rebind(ctrl-g)+change-prompt(ig> )+reload($FD_COMMAND)\"' \ 148 | --prompt 'ig> ' 149 | --header '/ CTRL-G .gitignore / CTRL-Y copy /' 150 | " 151 | else 152 | FD_COMMAND="find . -type f -not -path '*/\.git/*' -not -path '*/node_modules*'" 153 | FZF_T_OPTS="" 154 | fi 155 | 156 | export FZF_DEFAULT_COMMAND="$FD_COMMAND" 157 | export FZF_DEFAULT_OPTS="$FZF_DISPLAY $FZF_BINDS" 158 | export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" 159 | export FZF_CTRL_T_OPTS="$FZF_T_OPTS $FZF_PREVIEW" 160 | export FZF_ALT_C_COMMAND="find . -type d -not -path '*/\.git/*'" 161 | export FZF_ALT_C_OPTS="--preview 'tree -C {} | head -50'" 162 | -------------------------------------------------------------------------------- /dot_local/bin/scripts/git/executable_git-summary: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # From git-extras 4 | # source: https://github.com/tj/git-extras/blob/master/bin/git-summary 5 | 6 | cd "$(git rev-parse --show-toplevel)" || { 7 | echo "Can't cd to top level directory" 8 | exit 1 9 | } 10 | 11 | SUMMARY_BY_LINE= 12 | DEDUP_BY_EMAIL= 13 | MERGES_ARG= 14 | OUTPUT_STYLE= 15 | for arg in "$@"; do 16 | case "$arg" in 17 | --line) 18 | SUMMARY_BY_LINE=1 19 | ;; 20 | --dedup-by-email) 21 | DEDUP_BY_EMAIL=1 22 | ;; 23 | --no-merges) 24 | MERGES_ARG="--no-merges" 25 | ;; 26 | --output-style) 27 | OUTPUT_STYLE="$2" 28 | shift 29 | ;; 30 | -*) 31 | echo >&2 "unknown argument $arg found" 32 | exit 1 33 | ;; 34 | *) 35 | # set the argument back 36 | set -- "$@" "$arg" 37 | ;; 38 | esac 39 | 40 | shift 41 | done 42 | 43 | if [ -n "$DEDUP_BY_EMAIL" ] && [ -n "$SUMMARY_BY_LINE" ]; then 44 | echo >&2 "--dedup-by-email used with --line is not supported" 45 | exit 1 46 | fi 47 | 48 | if [ -n "$MERGES_ARG" ] && [ -n "$SUMMARY_BY_LINE" ]; then 49 | echo >&2 "--no-merges used with --line is not supported" 50 | exit 1 51 | fi 52 | 53 | if [ -n "$SUMMARY_BY_LINE" ]; then 54 | paths=("$@") 55 | else 56 | commit="HEAD" 57 | [ $# -ne 0 ] && commit=$* 58 | fi 59 | project=${PWD##*/} 60 | 61 | # 62 | # get date for the given 63 | # 64 | date() { 65 | # the $1 can be empty 66 | # shellcheck disable=SC2086 67 | git log $MERGES_ARG --pretty='format: %ai' $1 | cut -d ' ' -f 2 68 | } 69 | 70 | # 71 | # get active days for the given 72 | # 73 | active_days() { 74 | # shellcheck disable=SC2086 75 | date $1 | sort -r | uniq | awk ' 76 | { sum += 1 } 77 | END { print sum } 78 | ' 79 | } 80 | 81 | # 82 | # get the commit total 83 | # 84 | commit_count() { 85 | # shellcheck disable=SC2086 86 | git log $MERGES_ARG --oneline $commit | wc -l | tr -d ' ' 87 | } 88 | 89 | # 90 | # total file count 91 | # 92 | file_count() { 93 | git ls-files | wc -l | tr -d ' ' 94 | } 95 | 96 | # 97 | # remove duplicate authors who belong to the same email address 98 | # 99 | dedup_by_email() { 100 | # in: 101 | # 27 luo zexuan 102 | # 7 罗泽轩 103 | # out: 104 | # 34 luo zexuan 105 | LC_ALL=C awk ' 106 | { 107 | sum += $1 108 | last_field = tolower($NF) 109 | if (last_field in emails) { 110 | emails[last_field] += $1 111 | } else { 112 | email = last_field 113 | emails[email] = $1 114 | # set commits/email to empty 115 | $1=$NF="" 116 | sub(/^[[:space:]]+/, "", $0) 117 | sub(/[[:space:]]+$/, "", $0) 118 | name = $0 119 | if (name in names) { 120 | # when the same name is associated with existed email, 121 | # merge the previous email into the later one. 122 | emails[email] += emails[names[name]] 123 | emails[names[name]] = 0 124 | } 125 | names[name] = email 126 | } 127 | } 128 | END { 129 | for (name in names) { 130 | email = names[name] 131 | printf "%6d\t%s\n", emails[email], name 132 | } 133 | }' | sort -rn -k 1 134 | } 135 | 136 | # 137 | # list authors 138 | # 139 | format_authors() { 140 | # a rare unicode character is used as separator to avoid conflicting with 141 | # author name. However, Linux column utility will escape tab if separator 142 | # specified, so we do unesaping after it. 143 | LC_ALL=C awk ' 144 | { args[NR] = $0; sum += $0 } 145 | END { 146 | for (i = 1; i <= NR; ++i) { 147 | printf "%s♪%2.1f%%\n", args[i], 100 * args[i] / sum 148 | } 149 | } 150 | ' | column -t -s♪ | sed "s/\\\x09/\t/g" 151 | } 152 | 153 | # 154 | # fetch repository age from oldest commit 155 | # 156 | repository_age() { 157 | git log --reverse --pretty=oneline --format="%ar" | head -n 1 | LC_ALL=C sed 's/ago//' 158 | } 159 | 160 | # 161 | # fetch repository age of the latest commit 162 | # 163 | last_active() { 164 | git log --pretty=oneline --format="%ar" -n 1 165 | } 166 | 167 | # 168 | # list the last modified author for each line 169 | # 170 | single_file() { 171 | while read -r data; do 172 | if [[ $(file "$data") = *text* ]]; then 173 | git blame --line-porcelain "$data" 2>/dev/null | grep "^author " | LC_ALL=C sed -n 's/^author //p' 174 | fi 175 | done 176 | } 177 | 178 | current_branch_name() { 179 | git rev-parse --abbrev-ref HEAD 180 | } 181 | 182 | # 183 | # list the author for all file 184 | # 185 | lines() { 186 | git ls-files -- "$@" | single_file 187 | } 188 | 189 | # 190 | # get the number of the lines 191 | # 192 | line_count() { 193 | lines "$@" | wc -l 194 | } 195 | 196 | uncommitted_changes_count() { 197 | git status --porcelain | wc -l 198 | } 199 | 200 | COLUMN_CMD_DELIMTER="¬" # Hopefully, this symbol is not used in branch names... I use it as a seperator for columns 201 | SP="$COLUMN_CMD_DELIMTER|" 202 | 203 | print_summary_by_line() { 204 | if [ "$OUTPUT_STYLE" == "tabular" ]; then 205 | tabular_headers="# Repo $SP Lines" 206 | echo -e "$tabular_headers\n$project $SP $(line_count "${paths[@]}")" | column -t -s "$COLUMN_CMD_DELIMTER" 207 | elif [ "$OUTPUT_STYLE" == "oneline" ]; then 208 | echo "$project / lines: $(line_count "${paths[@]}")" 209 | elif [ -n "$SUMMARY_BY_LINE" ]; then 210 | echo 211 | echo " project : $project" 212 | echo " lines : $(line_count "${paths[@]}")" 213 | echo " authors :" 214 | lines "${paths[@]}" | sort | uniq -c | sort -rn | format_authors 215 | fi 216 | } 217 | 218 | print_summary() { 219 | if [ "$OUTPUT_STYLE" == "tabular" ]; then 220 | tabular_headers="# Repo $SP Age $SP Last active $SP Active on $SP Commits $SP Uncommitted $SP Branch" 221 | echo -e "$tabular_headers\n$project $SP $(repository_age) $SP $(last_active) $SP $(active_days $commit) days $SP $(commit_count $commit) $SP $(uncommitted_changes_count) $SP $(current_branch_name)" | column -t -s "$COLUMN_CMD_DELIMTER" 222 | elif [ "$OUTPUT_STYLE" == "oneline" ]; then 223 | echo "$project / age: $(repository_age) / last active: $(last_active) / active on $(active_days $commit) days / commits: $(commit_count $commit) / uncommitted: $(uncommitted_changes_count) / branch: $(current_branch_name)" 224 | else 225 | echo 226 | echo " project : $project" 227 | echo " repo age : $(repository_age)" 228 | echo " branch: : $(current_branch_name)" 229 | echo " last active : $(last_active)" 230 | # shellcheck disable=SC2086 231 | echo " active on : $(active_days $commit) days" 232 | # shellcheck disable=SC2086 233 | echo " commits : $(commit_count $commit)" 234 | 235 | # The file count doesn't support passing a git ref so ignore it if a ref is given 236 | if [ "$commit" == "HEAD" ]; then 237 | echo " files : $(file_count)" 238 | fi 239 | echo " uncommitted : $(uncommitted_changes_count)" 240 | echo " authors : " 241 | if [ -n "$DEDUP_BY_EMAIL" ]; then 242 | # the $commit can be empty 243 | # shellcheck disable=SC2086 244 | git shortlog $MERGES_ARG -n -s -e $commit | dedup_by_email | format_authors 245 | else 246 | # shellcheck disable=SC2086 247 | git shortlog $MERGES_ARG -n -s $commit | format_authors 248 | fi 249 | fi 250 | } 251 | 252 | if [ -n "$SUMMARY_BY_LINE" ]; then 253 | print_summary_by_line 254 | else 255 | print_summary 256 | fi 257 | --------------------------------------------------------------------------------