├── .gemrc ├── themes ├── tokyonight-moon │ ├── ghostty │ ├── nvim.lua │ ├── tmux.conf │ ├── fzf.sh │ ├── gitui.ron │ └── btop.theme └── gruvbox-dark-medium │ ├── ghostty │ ├── nvim.lua │ ├── tmux.conf │ ├── fzf.sh │ ├── gitui.ron │ └── btop.theme ├── .config ├── bat │ └── config ├── nvim │ ├── lua │ │ ├── plugins │ │ │ ├── vim-hugo.lua │ │ │ ├── vim-jinja2-syntax.lua │ │ │ ├── _disabled.lua │ │ │ ├── mason.lua │ │ │ ├── vim-better-whitespace.lua │ │ │ ├── treesitter.lua │ │ │ ├── vim-test.lua │ │ │ ├── data │ │ │ │ ├── .markdownlint-cli2.yaml │ │ │ │ └── github-markdown.css │ │ │ ├── multicursor.lua │ │ │ ├── snacks.lua │ │ │ ├── colorschemes.lua │ │ │ ├── markdown.lua │ │ │ ├── grug-far.lua │ │ │ ├── lsp.lua │ │ │ ├── completions.lua │ │ │ ├── lualine.lua │ │ │ └── theme-hot-reload.lua │ │ └── config │ │ │ ├── autocmds.lua │ │ │ ├── keymaps.lua │ │ │ ├── options.lua │ │ │ └── lazy.lua │ ├── stylua.toml │ ├── init.lua │ ├── .neoconf.json │ ├── after │ │ └── queries │ │ │ └── gitcommit │ │ │ └── highlights.scm │ ├── snippets │ │ ├── ruby.json │ │ ├── package.json │ │ ├── sh.json │ │ └── markdown.json │ ├── lazyvim.json │ ├── filetype.lua │ ├── lazy-lock.json │ └── spell │ │ └── en.utf-8.add ├── zsh │ ├── .zshenv │ ├── .aliases │ ├── .zprofile │ └── .zshrc ├── ghostty │ └── config ├── fzf │ └── config.sh ├── git │ └── config ├── tmux │ └── tmux.conf └── btop │ └── btop.conf ├── etc ├── wsl.conf └── pacman.d │ └── 01-options.conf ├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .editorconfig ├── .local └── bin │ ├── pw │ ├── weather │ ├── dtags │ ├── clip-paste │ ├── clip-copy │ ├── stop-recording │ ├── mkscript │ ├── change-terminal-font │ ├── ppjson │ ├── dot-update-zsh-plugins │ ├── gbd │ ├── dot-theme-set │ ├── gd │ ├── start-recording │ ├── tmux-shell-cmd │ └── pkg ├── pyproject.toml ├── mnt └── c │ └── Users │ └── Nick │ ├── .wslconfig │ └── AppData │ ├── Roaming │ └── Microsoft │ │ └── Windows │ │ └── Start Menu │ │ └── Programs │ │ └── Startup │ │ └── hotkeys.ahk │ └── Local │ └── Packages │ └── Microsoft.WindowsTerminal_8wekyb3d8bbwe │ └── LocalState │ └── settings.json ├── .gitignore ├── LICENSE ├── run ├── install-config.example └── README.md /.gemrc: -------------------------------------------------------------------------------- 1 | gem: --no-document 2 | -------------------------------------------------------------------------------- /themes/tokyonight-moon/ghostty: -------------------------------------------------------------------------------- 1 | theme = TokyoNight Moon 2 | -------------------------------------------------------------------------------- /themes/gruvbox-dark-medium/ghostty: -------------------------------------------------------------------------------- 1 | theme = Gruvbox Dark 2 | -------------------------------------------------------------------------------- /.config/bat/config: -------------------------------------------------------------------------------- 1 | --theme="base16" 2 | --style="numbers,changes" 3 | -------------------------------------------------------------------------------- /etc/wsl.conf: -------------------------------------------------------------------------------- 1 | [automount] 2 | root = /mnt 3 | options = "metadata" 4 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/vim-hugo.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "phelipetls/vim-hugo" }, 3 | } 4 | -------------------------------------------------------------------------------- /.config/nvim/stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | indent_width = 2 3 | column_width = 79 4 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/vim-jinja2-syntax.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "Glench/Vim-Jinja2-Syntax" }, 3 | } 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | github: "nickjj" 4 | custom: ["https://www.paypal.me/nickjanetakis"] 5 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/_disabled.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "akinsho/bufferline.nvim", enabled = false }, 3 | } 4 | -------------------------------------------------------------------------------- /.config/zsh/.zshenv: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | export ZDOTDIR="${XDG_CONFIG_HOME:-"${HOME}/.config"}/zsh" 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [[sh]] 2 | indent_style = space 3 | indent_size = 2 4 | 5 | [[bash]] 6 | indent_style = space 7 | indent_size = 2 8 | -------------------------------------------------------------------------------- /.local/bin/pw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | set -o nounset 6 | 7 | pwgen -sync "${1:-48}" -1 | clip-copy 8 | -------------------------------------------------------------------------------- /.local/bin/weather: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | set -o nounset 6 | 7 | curl "https://wttr.in/${1:-}" 8 | -------------------------------------------------------------------------------- /etc/pacman.d/01-options.conf: -------------------------------------------------------------------------------- 1 | # Override options from /etc/pacman.conf. 2 | 3 | [options] 4 | Color 5 | VerbosePkgLists 6 | ParallelDownloads = 10 7 | -------------------------------------------------------------------------------- /themes/gruvbox-dark-medium/nvim.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "LazyVim/LazyVim", 4 | opts = { 5 | colorscheme = "gruvbox", 6 | }, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /themes/tokyonight-moon/nvim.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "LazyVim/LazyVim", 4 | opts = { 5 | colorscheme = "tokyonight-moon", 6 | }, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /.config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- Global variables. 2 | MAP = vim.keymap.set 3 | DEL = vim.keymap.del 4 | 5 | -- Bootstrap lazy.nvim, LazyVim and your plugins. 6 | require("config.lazy") 7 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.ruff] 2 | line-length = 79 3 | include = [ 4 | "*.py", 5 | "*.pyi", 6 | "*.ipynb", 7 | "**/pyproject.toml", 8 | ".local/bin/set-theme", 9 | ] 10 | 11 | [tool.ruff.lint] 12 | extend-select = ["I", "SIM"] 13 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/mason.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "mason-org/mason.nvim", 4 | opts = { 5 | ensure_installed = { 6 | "shellcheck", 7 | "shfmt", 8 | "stylua", 9 | }, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /.config/nvim/.neoconf.json: -------------------------------------------------------------------------------- 1 | { 2 | "neodev": { 3 | "library": { 4 | "enabled": true, 5 | "plugins": true 6 | } 7 | }, 8 | "neoconf": { 9 | "plugins": { 10 | "lua_ls": { 11 | "enabled": true 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.local/bin/dtags: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | set -o nounset 6 | 7 | image="${1:-}" 8 | 9 | curl --silent \ 10 | "https://registry.hub.docker.com/v2/repositories/library/${image}/tags?page_size=1000" | 11 | jq -r ".results[].name" | sort --version-sort 12 | -------------------------------------------------------------------------------- /themes/gruvbox-dark-medium/tmux.conf: -------------------------------------------------------------------------------- 1 | set -g mode-style "fg=#ebdbb2,bg=#504945" 2 | 3 | set -g pane-border-style "fg=colour238" 4 | set -g pane-active-border-style "fg=colour241" 5 | 6 | set -g status-style "fg=colour244" 7 | set -g window-status-style "fg=colour244" 8 | set -g window-status-current-style "fg=colour222" 9 | -------------------------------------------------------------------------------- /themes/tokyonight-moon/tmux.conf: -------------------------------------------------------------------------------- 1 | set -g mode-style "fg=#82aaff,bg=#3b4261" 2 | 3 | set -g pane-border-style "fg=#3b4261" 4 | set -g pane-active-border-style "fg=#4a5480" 5 | 6 | set -g status-style "fg=#82aaff,bg=#1e2030" 7 | set -g window-status-style "fg=#828bb8,bg=#1e2030" 8 | set -g window-status-current-style "fg=#82aaff,bg=#1e2030" 9 | -------------------------------------------------------------------------------- /.local/bin/clip-paste: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # A cross OS / display server clipboard paster. 3 | # 4 | # Examples: 5 | # clip-paste 6 | # clip-paste | sort 7 | # clip-paste > myfile 8 | 9 | set -o errexit 10 | set -o pipefail 11 | set -o nounset 12 | 13 | wl-paste 2>/dev/null || pbpaste 2>/dev/null || xclip -out -selection clipboard 14 | -------------------------------------------------------------------------------- /.config/ghostty/config: -------------------------------------------------------------------------------- 1 | font-family = Inconsolata Nerd Font 2 | font-size = 14 3 | font-feature = -calt, -liga, -dlig 4 | 5 | cursor-style-blink = false 6 | cursor-text = #000000 7 | 8 | # Load theme. 9 | config-file = ?theme 10 | 11 | # Load a custom config for overrides, ? silently fails if the file is missing. 12 | config-file = ?config.local 13 | -------------------------------------------------------------------------------- /.local/bin/clip-copy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # A cross OS / display server clipboard copier. 3 | # 4 | # Examples: 5 | # echo "Hello world" | clip-copy 6 | # clip-copy <<< "Hello world" 7 | # clip-copy < myfile 8 | 9 | set -o errexit 10 | set -o pipefail 11 | set -o nounset 12 | 13 | wl-copy 2>/dev/null || pbcopy 2>/dev/null || xclip -sel clip 14 | -------------------------------------------------------------------------------- /.config/fzf/config.sh: -------------------------------------------------------------------------------- 1 | export FZF_DEFAULT_COMMAND="rg --files --follow --hidden --glob '!.git'" 2 | export FZF_DEFAULT_OPTS="--highlight-line --info=inline-right --ansi --layout=reverse --border=none --preview='bat --color=always {}' --bind shift-up:preview-page-up,shift-down:preview-page-down" 3 | export FZF_CTRL_T_OPTS="--height=100%" 4 | 5 | # shellcheck disable=SC1091 6 | . "${XDG_CONFIG_HOME}/fzf/theme.sh" 7 | -------------------------------------------------------------------------------- /.config/nvim/after/queries/gitcommit/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | 3 | ; Highlight longer lines as a suggestion to consider using less characters. 4 | ((subject) @comment.warning 5 | (#vim-match? @comment.warning ".\{50,}") 6 | (#offset! @comment.warning 0 50 0 0)) 7 | 8 | ((message_line) @comment.warning 9 | (#vim-match? @comment.warning ".\{72,}") 10 | (#offset! @comment.warning 0 72 0 0)) 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: "CI" 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "*" 7 | push: 8 | branches: 9 | - "main" 10 | - "master" 11 | schedule: 12 | - cron: "30 12 * * *" 13 | 14 | jobs: 15 | test: 16 | runs-on: "ubuntu-24.04" 17 | 18 | steps: 19 | - uses: "actions/checkout@v4" 20 | 21 | - name: "Linting and testing" 22 | run: | 23 | ./run ci:test 24 | -------------------------------------------------------------------------------- /mnt/c/Users/Nick/.wslconfig: -------------------------------------------------------------------------------- 1 | [wsl2] 2 | memory=6GB # Make sure you have this amount available to use! 3 | swapFile=E:\\wsl2-swap.vhdx # I put mine off my SSD, but this is optional. 4 | 5 | # Another option is to disable swap but if the VM goes out of memory, the 6 | # OOM killer might start killing important processes or the VM may crash. 7 | # 8 | # Uncomment the line below this to use no swap file at all in the WSL 2 VM. 9 | #swap=0 10 | -------------------------------------------------------------------------------- /.config/nvim/snippets/ruby.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rails model scaffold": { 3 | "prefix": "rms", 4 | "body": [ 5 | "\t# Includes\n", 6 | "\t# Default scope\n", 7 | "\t# Constants\n", 8 | "\t# Attributes\n", 9 | "\t# Enums\n", 10 | "\t# belongs_to\n", 11 | "\t# has_many", 12 | "\t# has_one\n", 13 | "\t# Validates\n", 14 | "\t# Callbacks\n", 15 | "\t# Other macros\n", 16 | "\t# Scopes\n" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.config/nvim/snippets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "personal-snippets", 3 | "contributes": { 4 | "snippets": [ 5 | { 6 | "language": [ 7 | "markdown" 8 | ], 9 | "path": "./markdown.json" 10 | }, 11 | { 12 | "language": [ 13 | "ruby" 14 | ], 15 | "path": "./ruby.json" 16 | }, 17 | { 18 | "language": [ 19 | "sh" 20 | ], 21 | "path": "./sh.json" 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.config/nvim/snippets/sh.json: -------------------------------------------------------------------------------- 1 | { 2 | "Heredoc": { 3 | "prefix": "heredoc", 4 | "body": [ 5 | "cat < ${1}", 23 | "${2}", 24 | "EOF" 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.local/bin/stop-recording: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | 6 | from_terminal_font_size="20" 7 | to_terminal_font_size="10" 8 | 9 | cp "${HISTFILE}.bak" "${HISTFILE}" 10 | 11 | change-terminal-font "${from_terminal_font_size}" "${to_terminal_font_size}" 12 | 13 | cat < Shell history has been restored 15 | -> Terminal font has been reverted to ${to_terminal_font_size} 16 | 17 | Nice work, here's a few things to maybe do: 18 | - Restore tmux sessions by running tmux and then Leader + CTRL + r 19 | EOF 20 | -------------------------------------------------------------------------------- /.local/bin/mkscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | set -o nounset 6 | 7 | file="${1:-}" 8 | 9 | [ -z "${file}" ] && { 10 | echo "Please supply a script name to create" 11 | exit 1 12 | } 13 | [ -f "${file}" ] && { 14 | echo "${file} already exists, aborting" 15 | exit 1 16 | } 17 | 18 | mkdir -p "$(dirname "${file}")" 19 | 20 | cat >"${file}" <tn", "TestNearest", { desc = "Test Nearest" }) 14 | MAP("n", "tf", "TestFile", { desc = "Test File" }) 15 | MAP("n", "ta", "TestSuite", { desc = "Test All" }) 16 | MAP("n", "tl", "TestLast", { desc = "Test Last" }) 17 | MAP("n", "tv", "TestVisit", { desc = "Test Visit" }) 18 | end, 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/data/.markdownlint-cli2.yaml: -------------------------------------------------------------------------------- 1 | # Globally set options. If you have a project specific directory you can 2 | # overwrite these globals with a .markdownlint-cli2.yaml file or add inline 3 | # comments to your document, such as: 4 | # 5 | # 6 | # 7 | config: 8 | # Disable everything by default. Set this to true to enable everything. 9 | # Additionally, even with it set to false you can define individual rules 10 | # here to turn them on for both linting and formatting. 11 | # 12 | # My goal is to over time opt into specific rules when I'm more comfortable 13 | # with the rules since I have over 500+ blog posts not in git so I can't 14 | # easily track if something changed on save. 15 | # 16 | # That is why I didn't disable the linter and formatter at the Lua level. 17 | default: false 18 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/multicursor.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "jake-stewart/multicursor.nvim", 4 | branch = "1.0", 5 | config = function() 6 | local mc = require("multicursor-nvim") 7 | mc.setup() 8 | 9 | -- Add and remove cursors with CTRL + left click. 10 | MAP("n", "", mc.handleMouse) 11 | MAP("n", "", mc.handleMouseDrag) 12 | MAP("n", "", mc.handleMouseRelease) 13 | 14 | -- Mappings defined in a keymap layer only apply when there are 15 | -- multiple cursors. This lets you have overlapping mappings. 16 | mc.addKeymapLayer(function(layerSet) 17 | -- Enable and clear cursors using escape. 18 | layerSet("n", "", function() 19 | if not mc.cursorsEnabled() then 20 | mc.enableCursors() 21 | else 22 | mc.clearCursors() 23 | end 24 | end) 25 | end) 26 | end, 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /.config/nvim/snippets/markdown.json: -------------------------------------------------------------------------------- 1 | { 2 | "YouTube description": { 3 | "prefix": "ytd", 4 | "body": [ 5 | "Hit the subscribe button to receive more videos like this!\n", 6 | "REFERENCE LINKS", 7 | "---------------------------------------------------", 8 | "► https://nickjanetakis.com/blog/TODO\n", 9 | "COURSES", 10 | "---------------------------------------------------", 11 | "Courses I've created that focus on web dev and deployment topics.\n", 12 | "► https://nickjanetakis.com/courses\n", 13 | "THE TOOLS I USE / GEAR", 14 | "---------------------------------------------------", 15 | "► https://nickjanetakis.com/blog/the-tools-i-use\n", 16 | "FOLLOW ME ELSEWHERE", 17 | "---------------------------------------------------", 18 | "► Twitter: https://twitter.com/nickjanetakis", 19 | "► GitHub: https://github.com/nickjj\n", 20 | "TIMESTAMPS", 21 | "---------------------------------------------------", 22 | "0:00 -- Intro\n" 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/snacks.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "folke/snacks.nvim", 4 | init = function() 5 | vim.g.snacks_animate = false 6 | end, 7 | opts = { 8 | dashboard = { enabled = false }, 9 | picker = { 10 | hidden = true, 11 | sources = { 12 | -- These define their own options, we must override their defaults. 13 | files = { hidden = true }, 14 | buffers = { hidden = true }, 15 | -- Explorer and the rest of the sources don't define their own opts 16 | -- so it will use the picker options defined above and we can choose 17 | -- to override them if desired. 18 | explorer = { 19 | ignored = true, 20 | -- If you prefer a right aligned explorer, uncomment this: 21 | -- layout = { 22 | -- layout = { 23 | -- position = "right", 24 | -- }, 25 | -- }, 26 | }, 27 | }, 28 | }, 29 | terminal = { 30 | win = { 31 | position = "float", 32 | border = "rounded", 33 | }, 34 | }, 35 | }, 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Nick Janetakis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /.local/bin/start-recording: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | set -o nounset 6 | 7 | from_terminal_font_size="10" 8 | to_terminal_font_size="20" 9 | 10 | cp "${HISTFILE}" "${HISTFILE}.bak" 11 | rm "${HISTFILE}" 12 | 13 | rm -f "${XDG_STATE_HOME}/nvim/swap/%"* 14 | change-terminal-font "${from_terminal_font_size}" "${to_terminal_font_size}" 15 | 16 | if [ "${1:-}" = "--obs" ]; then 17 | cd "/mnt/c/Program Files/obs-studio/bin/64bit" || exit 18 | wslview obs64.exe 19 | cd - >/dev/null 2>&1 || exit 20 | fi 21 | 22 | cat < Shell history has been backed up to ${HISTFILE} 24 | -> Temporary Neovim files have been deleted from ${XDG_STATE_HOME}/nvim/swap 25 | -> Terminal font has been increased to ${to_terminal_font_size} 26 | 27 | Plan to switch between tmux sessions? 28 | - 1. Leader + CTRL + s to save your sessions 29 | - 2. tmux kill-server 30 | 31 | Going to use a browser? 32 | - Use one with a cleared history 33 | 34 | Various tips: 35 | - Use CTRL + L instead of running clear to clear your screen as needed 36 | - Make sure your windows are positioned correctly with Sizer 37 | - Be mindful of secrets in any .env file! 38 | - Make sure OBS is actually recording / streaming (if and when applicable) 39 | EOF 40 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/colorschemes.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "ellisonleao/gruvbox.nvim", 4 | opts = { 5 | contrast = "medium", 6 | italic = { 7 | strings = false, 8 | emphasis = false, 9 | comments = false, 10 | operators = false, 11 | folds = false, 12 | }, 13 | overrides = { 14 | SnacksPickerBorder = { link = "GruvboxBlue" }, 15 | NormalFloat = { link = "GruvboxBlue" }, 16 | }, 17 | }, 18 | }, 19 | { 20 | "folke/tokyonight.nvim", 21 | opts = { 22 | styles = { 23 | comments = { italic = false }, 24 | keywords = { italic = false }, 25 | }, 26 | on_highlights = function(hl, c) 27 | hl.SnacksPickerPathHidden = { fg = c.comment } 28 | hl.SnacksPickerDir = { fg = c.comment } 29 | hl.SnacksPickerGitStatusIgnored = { fg = c.nontext } 30 | hl.SnacksPickerGitStatusUntracked = { fg = c.nontext } 31 | hl.ColorColumn = { bg = c.bg_highlight } 32 | hl.SpellBad = { fg = c.red, undercurl = true } 33 | hl.SpellCap = { fg = c.red, undercurl = true } 34 | hl.SpellLocal = { fg = c.red, undercurl = true } 35 | hl.SpellRare = { fg = c.red, undercurl = true } 36 | end, 37 | }, 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /.config/nvim/filetype.lua: -------------------------------------------------------------------------------- 1 | -- Set .aliases or any variant as "bash". 2 | vim.filetype.add({ pattern = { ["%.*aliases.*"] = "bash" } }) 3 | 4 | -- Set .zprofile or any variant as "bash". 5 | vim.filetype.add({ pattern = { ["%.*zprofile.*"] = "bash" } }) 6 | 7 | -- Set .env or any variant as "dotenv" except we want .env.example files to be 8 | -- treated differently so it's easier to know we are editing an example file. 9 | -- This has less syntax highlighting and comes up with a different explorer 10 | -- icon so it's easier to know it's not the "real" env file. 11 | vim.filetype.add({ 12 | pattern = { 13 | ["%.env.*"] = "dotenv", 14 | ["%.env.*.example"] = { "conf", { priority = 1 } }, 15 | }, 16 | }) 17 | 18 | -- Ensure all .env files and variants are syntax highlighted as shell scripts. 19 | -- This goes along with the filetype addition above. We do this to avoid using 20 | -- bash or sh so the BashLSP linter and formatter doesn't affect env files 21 | -- since that can create a lot of unwanted false positives and side effects. 22 | vim.treesitter.language.register("bash", "dotenv") 23 | 24 | -- Set git config variarts as "git_config". 25 | vim.filetype.add({ pattern = { [".*/git/config.*"] = "git_config" } }) 26 | 27 | -- Set requirements-lock.txt or any variant as "requirements". 28 | vim.filetype.add({ pattern = { ["requirements.*.txt"] = "requirements" } }) 29 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/markdown.lua: -------------------------------------------------------------------------------- 1 | local data_path = vim.fn.stdpath("config") .. "/lua/plugins/data" 2 | local markdownlint_cli2_path = data_path .. "/.markdownlint-cli2.yaml" 3 | local markdown_preview_css_path = data_path .. "/github-markdown.css" 4 | 5 | return { 6 | { 7 | "iamcco/markdown-preview.nvim", 8 | init = function() 9 | vim.g.mkdp_auto_close = false 10 | vim.g.mkdp_markdown_css = markdown_preview_css_path 11 | end, 12 | build = "cd app && yarn install", 13 | }, 14 | { 15 | "stevearc/conform.nvim", 16 | opts = { 17 | formatters = { 18 | ["markdownlint-cli2"] = { 19 | 20 | args = { "--config", markdownlint_cli2_path, "--fix", "$FILENAME" }, 21 | }, 22 | }, 23 | }, 24 | }, 25 | { 26 | "mfussenegger/nvim-lint", 27 | opts = { 28 | linters = { 29 | ["markdownlint-cli2"] = { 30 | args = { "--config", markdownlint_cli2_path, "--" }, 31 | }, 32 | }, 33 | }, 34 | }, 35 | { 36 | "MeanderingProgrammer/render-markdown.nvim", 37 | opts = { 38 | enabled = false, 39 | win_options = { 40 | colorcolumn = { default = vim.o.colorcolumn, rendered = "" }, 41 | }, 42 | heading = { 43 | width = "block", 44 | min_width = tonumber(vim.o.colorcolumn), 45 | }, 46 | }, 47 | }, 48 | } 49 | -------------------------------------------------------------------------------- /.config/nvim/lua/config/autocmds.lua: -------------------------------------------------------------------------------- 1 | -- Autocmds are automatically loaded on the VeryLazy event. 2 | -- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua 3 | 4 | local cursorline_group = 5 | vim.api.nvim_create_augroup("cursorline", { clear = true }) 6 | vim.api.nvim_create_autocmd({ "VimEnter", "WinEnter", "BufWinEnter" }, { 7 | group = cursorline_group, 8 | callback = function() 9 | vim.opt_local.cursorline = true 10 | end, 11 | }) 12 | vim.api.nvim_create_autocmd("WinLeave", { 13 | group = cursorline_group, 14 | callback = function() 15 | vim.opt_local.cursorline = false 16 | end, 17 | }) 18 | 19 | -- Fix indentation if a . comes before end such as when using "self.". 20 | -- Source: https://github.com/tree-sitter/tree-sitter-ruby/issues/230 21 | vim.api.nvim_create_autocmd("FileType", { 22 | pattern = { "ruby" }, 23 | callback = function() 24 | vim.opt_local.indentkeys:remove(".") 25 | end, 26 | }) 27 | 28 | vim.api.nvim_create_autocmd("FileType", { 29 | pattern = { "make" }, 30 | callback = function() 31 | vim.opt_local.expandtab = false 32 | vim.opt_local.shiftwidth = 4 33 | end, 34 | }) 35 | 36 | vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { 37 | pattern = { "*.yaml", "*.yml" }, 38 | callback = function() 39 | if 40 | vim.fn.getline(1):match("^apiVersion:") 41 | or vim.fn.getline(2):match("^apiVersion:") 42 | then 43 | vim.opt_local.filetype = "helm" 44 | end 45 | end, 46 | }) 47 | -------------------------------------------------------------------------------- /.config/nvim/lua/config/keymaps.lua: -------------------------------------------------------------------------------- 1 | -- Keymaps are automatically loaded on the VeryLazy event. 2 | -- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua 3 | 4 | DEL("n", "l") 5 | MAP("n", "ll", "Lazy", { desc = "Lazy" }) 6 | MAP("n", "lL", "LazyExtras", { desc = "Lazy Extras" }) 7 | 8 | MAP( 9 | "n", 10 | "", 11 | "execute 'move .+' . v:count1==", 12 | { desc = "Move Down" } 13 | ) 14 | MAP( 15 | "n", 16 | "", 17 | "execute 'move .-' . (v:count1 + 1)==", 18 | { desc = "Move Up" } 19 | ) 20 | MAP("i", "", "m .+1==gi", { desc = "Move Down" }) 21 | MAP("i", "", "m .-2==gi", { desc = "Move Up" }) 22 | MAP( 23 | "x", 24 | "", 25 | ":execute \"'<,'>move '>+\" . v:count1gv=gv", 26 | { desc = "Move Down" } 27 | ) 28 | MAP( 29 | "x", 30 | "", 31 | ":execute \"'<,'>move '<-\" . (v:count1 + 1)gv=gv", 32 | { desc = "Move Up" } 33 | ) 34 | 35 | MAP({ "n", "x" }, "x", '"_x', { desc = "Delete Chars Into Void" }) 36 | MAP({ "n", "x" }, "X", '"_x', { desc = "Delete Chars Into Void" }) 37 | MAP({ "n", "x" }, "", '"_x', { desc = "Delete Chars Into Void" }) 38 | 39 | MAP("x", "y", "ygv", { desc = "Yank Preserve Cursor" }) 40 | MAP("x", "p", "P", { desc = "Paste Without Override" }) 41 | 42 | MAP("n", "uW", ":set list!", { desc = "Toggle WhiteSpace" }) 43 | 44 | MAP("n", "bc", ":let @+ = expand('%:.')", { desc = "Copy Path" }) 45 | 46 | MAP( 47 | "x", 48 | "gt", 49 | "c=system('tcc', getreg('\"'))[:-2]", 50 | { desc = "Titleize Text" } 51 | ) 52 | -------------------------------------------------------------------------------- /.config/zsh/.aliases: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | alias ll="ls -alF" 4 | alias la="ls -A" 5 | alias l="ls -CF" 6 | 7 | alias eza="EZA_ICON_SPACING=2 eza --long --all --octal-permissions --group --group-directories-first --time-style long-iso --header --icons auto" 8 | 9 | alias diff="diff --color -u" 10 | 11 | alias sz='. ${ZDOTDIR}/.zprofile && . ${ZDOTDIR}/.zshrc' 12 | alias SZ='tmux-shell-cmd --kill "sz"' 13 | alias dt='cd ${DOTFILES_PATH} && nvim .' 14 | alias lz='cd ${XDG_DATA_HOME}/nvim/lazy/LazyVim && nvim .' 15 | alias lp='cd ${XDG_DATA_HOME}/nvim/lazy && nvim .' 16 | 17 | alias start-rec="start-recording && HISTSIZE=0" 18 | alias stop-rec='stop-recording && HISTSIZE=${SAVEHIST} && fc -R' 19 | 20 | alias 755d="find . -type d -exec chmod 755 {} \;" 21 | alias 644f="find . -type f -exec chmod 644 {} \;" 22 | 23 | alias vss='sort -u ${XDG_CONFIG_HOME}/nvim/spell/en.utf-8.add -o ${XDG_CONFIG_HOME}/nvim/spell/en.utf-8.add' 24 | alias vdt='rm ${XDG_STATE_HOME}/nvim/swap/%*' 25 | 26 | # shellcheck disable=SC2139 27 | alias pf="fzf ${FZF_CTRL_T_OPTS}" 28 | 29 | alias gi="git init && git symbolic-ref HEAD refs/heads/main" 30 | alias gcl="git diff --name-only --diff-filter=U" 31 | alias ge="rg '[\p{Emoji}--\p{Ascii}]'" 32 | 33 | alias drun='docker container run --rm -it -v "${PWD}":/app -w /app' 34 | 35 | alias myip="curl -s -4 https://ifconfig.me | tee >(clip-copy)" 36 | 37 | alias k="kubectl" 38 | alias tf="terraform" 39 | alias ymp3="youtube-dl --extract-audio --audio-format mp3" 40 | alias jek="RUBYOPT='-W0' bundle exec jekyll serve --config _config.yml,_config.dev.yml --drafts --livereload" 41 | 42 | # A way to define and run tasks in a project. It's like make except it's pure 43 | # Bash so there's no make limitations like not being able to forward arguments. 44 | alias run=./run 45 | -------------------------------------------------------------------------------- /.config/nvim/lua/config/options.lua: -------------------------------------------------------------------------------- 1 | -- Options are automatically loaded before lazy.nvim startup. 2 | -- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua 3 | 4 | -- Certain but not all LSPs will set the root directory based on which buffer 5 | -- is active. This affects picking files. I found this to be disruptive, for 6 | -- example editing a Lua file in my dotfiles prevented me from fuzzy finding 7 | -- files of the nvim/ directory. Remove this to bring things back to LazyVim's 8 | -- default behavior. 9 | vim.g.root_spec = { "cwd" } 10 | 11 | -- The ~/.local/state/nvim/lsp.log can get pretty noisy. Mine was ~28MB after 2 12 | -- weeks with the default setting. My thought process here is it can remain OFF 13 | -- by default but if you're looking to troubleshoot something you can 14 | -- temporarily set this to WARN or ERROR. 15 | vim.lsp.set_log_level("OFF") 16 | 17 | local opt = vim.opt 18 | 19 | -- I prefer seeing all characters by default. 20 | opt.conceallevel = 0 21 | 22 | -- Show a vertical line at this character. 23 | opt.colorcolumn = "80" 24 | 25 | -- Each buffer gets its own status line instead of sharing one. 26 | opt.laststatus = 2 27 | 28 | -- These are all invisible by default but we can toggle them with a keymap. 29 | opt.listchars = { 30 | eol = "$", 31 | tab = ">-", 32 | trail = "-", 33 | lead = "-", 34 | extends = "~", 35 | precedes = "~", 36 | conceal = "+", 37 | nbsp = "&", 38 | } 39 | opt.list = false 40 | 41 | -- Don't auto-scroll N number of lines from the top of the buffer. 42 | opt.scrolloff = 0 43 | 44 | -- Allow left and right arrow keys to move to the previous and next line. 45 | opt.whichwrap = "b,s,<,>" 46 | 47 | -- Wrap lines so it's easier to see anything that's cut off. 48 | opt.wrap = true 49 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/grug-far.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "MagicDuck/grug-far.nvim", 3 | cmd = { "GrugFar", "GrugFarWithin" }, 4 | config = function() 5 | vim.api.nvim_create_autocmd("FileType", { 6 | pattern = { "grug-far" }, 7 | callback = function() 8 | MAP({ "i", "n", "x" }, "", function() 9 | local state = unpack( 10 | require("grug-far") 11 | .get_instance(0) 12 | :toggle_flags({ "--hidden", "--glob !.git/" }) 13 | ) 14 | vim.notify( 15 | "grug-far: toggled --hidden --glob !.git/ " 16 | .. (state and "ON" or "OFF") 17 | ) 18 | end, { desc = "Toggle Hidden Files", buffer = true }) 19 | 20 | MAP({ "i", "n", "x" }, "", function() 21 | local state = unpack( 22 | require("grug-far").get_instance(0):toggle_flags({ "--no-ignore" }) 23 | ) 24 | vim.notify( 25 | "grug-far: toggled --no-ignore " .. (state and "ON" or "OFF") 26 | ) 27 | end, { desc = "Toggle Ignored Files", buffer = true }) 28 | end, 29 | }) 30 | end, 31 | init = function() 32 | MAP( 33 | "x", 34 | "sRa", 35 | ":lua require('grug-far').with_visual_selection()", 36 | { desc = "All Files" } 37 | ) 38 | 39 | MAP( 40 | "n", 41 | "sRc", 42 | ":lua require('grug-far').open({ prefills = { paths = vim.fn.expand('%') } })", 43 | { desc = "Current File" } 44 | ) 45 | 46 | MAP( 47 | "x", 48 | "sRc", 49 | ":lua require('grug-far').with_visual_selection({ prefills = { paths = vim.fn.expand('%') } })", 50 | { desc = "Current File" } 51 | ) 52 | 53 | MAP("x", "sRw", ":GrugFarWithin", { desc = "Within Range" }) 54 | end, 55 | } 56 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/lsp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "stevearc/conform.nvim", 4 | opts = { 5 | formatters_by_ft = { 6 | python = { "ruff_organize_imports", lsp_format = "first" }, 7 | }, 8 | }, 9 | }, 10 | { 11 | "neovim/nvim-lspconfig", 12 | opts = { 13 | servers = { 14 | yamlls = { 15 | settings = { 16 | yaml = { 17 | customTags = { 18 | -- These are all related to AWS CloudFormation. 19 | "!And sequence", 20 | "!Base64", 21 | "!Cidr sequence", 22 | "!Equals sequence", 23 | "!FindInMap sequence", 24 | "!GetAZs", 25 | "!GetAtt", 26 | "!If sequence", 27 | "!ImportValue", 28 | "!Join sequence", 29 | "!Length sequence", 30 | "!Not sequence", 31 | "!Or sequence", 32 | "!Ref", 33 | "!Select sequence", 34 | "!Split sequence", 35 | "!Sub", 36 | "!Transform scalar", 37 | }, 38 | }, 39 | }, 40 | }, 41 | bashls = { 42 | settings = { 43 | filetypes = { "sh", "bash", "zsh" }, 44 | }, 45 | }, 46 | rubocop = { 47 | enabled = false, 48 | }, 49 | pyright = { 50 | -- Both settings are to let Ruff handle these tasks. 51 | settings = { 52 | pyright = { 53 | disableOrganizeImports = true, 54 | }, 55 | python = { 56 | analysis = { 57 | ignore = { "*" }, 58 | }, 59 | }, 60 | }, 61 | }, 62 | }, 63 | }, 64 | }, 65 | } 66 | -------------------------------------------------------------------------------- /.config/zsh/.zprofile: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # This file runs once at login. 4 | 5 | # shellcheck disable=SC1091 6 | . "${XDG_CONFIG_HOME:-"${HOME}/.config"}/zsh/.xdg.local" 7 | 8 | # Add all local binaries to the system path and make sure they are first. 9 | export PATH="${HOME}/.local/bin:${HOME}/.local/bin/local:${PATH}" 10 | 11 | # Confiure Mise (programming language run-time manager). 12 | export PATH="${XDG_DATA_HOME}/mise/shims:${PATH}" 13 | 14 | # Default programs to run. 15 | export EDITOR="nvim" 16 | export DIFFPROG="nvim -d" 17 | 18 | # Add colors to the less and man commands. 19 | export LESS=-R 20 | LESS_TERMCAP_ue="$(printf '%b' '')" 21 | export LESS_TERMCAP_ue 22 | export LESS_TERMCAP_mb=$'\e[1;31mm' # begin blinking 23 | export LESS_TERMCAP_md=$'\e[1;36m' # begin bold 24 | export LESS_TERMCAP_us=$'\e[1;332m' # begin underline 25 | export LESS_TERMCAP_so=$'\e[1;44;33m' # begin standout-mode - info box 26 | export LESS_TERMCAP_me=$'\e[0m' # end mode 27 | export LESS_TERMCAP_ue=$'\e[0m' # end underline 28 | export LESS_TERMCAP_se=$'\e[0m' # end standout-mode 29 | 30 | # Configure GPG. 31 | export GNUPGHOME="${XDG_CONFIG_HOME}/gnupg" 32 | 33 | # Configure pass, Docker Desktop on Linux uses this tool and while I have used 34 | # it for years in the past, I've moved to using KeePassXC. 35 | export PASSWORD_STORE_DIR="${XDG_CONFIG_HOME}/password-store" 36 | 37 | # Configure delta (diffs) defaults. 38 | # https://dandavison.github.io/delta/environment-variables.html 39 | export DELTA_FEATURES="diff-so-fancy" 40 | 41 | # Configure zsh-vi-mode. 42 | export ZVM_NORMAL_MODE_CURSOR="${ZVM_CURSOR_BLOCK}" 43 | export ZVM_INSERT_MODE_CURSOR="${ZVM_CURSOR_BEAM}" 44 | 45 | # Load local settings if they exist. 46 | # shellcheck disable=SC1091 47 | if [ -f "${XDG_CONFIG_HOME}/zsh/.zprofile.local" ]; then . "${XDG_CONFIG_HOME}/zsh/.zprofile.local"; fi 48 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/completions.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "rafamadriz/friendly-snippets", 4 | config = function() 5 | require("luasnip.loaders.from_vscode").lazy_load() 6 | require("luasnip.loaders.from_vscode").lazy_load({ 7 | paths = { vim.fn.stdpath("config") .. "/snippets" }, 8 | }) 9 | end, 10 | }, 11 | { 12 | "saghen/blink.cmp", 13 | opts = { 14 | keymap = { 15 | preset = "enter", 16 | [""] = { "select_next", "snippet_forward", "fallback" }, 17 | [""] = { "select_prev", "snippet_backward", "fallback" }, 18 | }, 19 | completion = { 20 | list = { 21 | selection = { 22 | preselect = false, 23 | auto_insert = false, 24 | }, 25 | }, 26 | ghost_text = { enabled = false }, 27 | }, 28 | signature = { enabled = true }, 29 | cmdline = { 30 | enabled = true, 31 | completion = { 32 | list = { selection = { preselect = false } }, 33 | menu = { 34 | auto_show = function(_) 35 | -- Only trigger the menu for :, this avoids triggering it when 36 | -- doing / (search) or other commands. 37 | return vim.fn.getcmdtype() == ":" 38 | end, 39 | }, 40 | }, 41 | keymap = { 42 | [""] = { "accept_and_enter", "fallback" }, 43 | }, 44 | }, 45 | sources = { 46 | providers = { 47 | cmdline = { 48 | min_keyword_length = function(ctx) 49 | -- Only show after inputting 4+ characters. 50 | if 51 | ctx.mode == "cmdline" and string.find(ctx.line, " ") == nil 52 | then 53 | return 4 54 | end 55 | 56 | return 0 57 | end, 58 | }, 59 | }, 60 | }, 61 | }, 62 | }, 63 | } 64 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/lualine.lua: -------------------------------------------------------------------------------- 1 | local function get_wordcount() 2 | local word_count = 0 3 | 4 | if vim.fn.mode():find("[vV]") then 5 | word_count = vim.fn.wordcount().visual_words 6 | else 7 | word_count = vim.fn.wordcount().words 8 | end 9 | 10 | return word_count 11 | end 12 | 13 | local function wordcount() 14 | local label = "word" 15 | local word_count = get_wordcount() 16 | 17 | if word_count > 1 then 18 | label = label .. "s" 19 | end 20 | 21 | return word_count .. " " .. label 22 | end 23 | 24 | local function readingtime() 25 | -- 200 is about the average words read per minute. 26 | return tostring(math.ceil(get_wordcount() / 200.0)) .. " min" 27 | end 28 | 29 | local function is_prose() 30 | return vim.bo.filetype == "markdown" or vim.bo.filetype == "text" 31 | end 32 | 33 | local function location() 34 | -- This function existed in Lualine, I modified it to display the total 35 | -- number of selected characters spanning across multiple lines. 36 | local line = vim.fn.line(".") 37 | local col = vim.fn.charcol(".") 38 | 39 | local line_start = vim.fn.line("v") 40 | local line_end = vim.fn.line(".") 41 | 42 | if vim.fn.mode():find("[vV]") and line_end ~= line_start then 43 | return string.format( 44 | "%d:%d:%d", 45 | line, 46 | col, 47 | vim.fn.wordcount().visual_chars 48 | ) 49 | else 50 | return string.format("%d:%d", line, col) 51 | end 52 | end 53 | 54 | return { 55 | { 56 | "nvim-lualine/lualine.nvim", 57 | opts = { 58 | sections = { 59 | lualine_y = { 60 | { "progress", separator = " ", padding = { left = 1, right = 0 } }, 61 | { location, padding = { left = 0, right = 1 } }, 62 | }, 63 | -- Disable the default clock and replace it with word stats. 64 | lualine_z = { 65 | { wordcount, cond = is_prose }, 66 | { readingtime, cond = is_prose }, 67 | }, 68 | }, 69 | }, 70 | }, 71 | } 72 | -------------------------------------------------------------------------------- /themes/tokyonight-moon/btop.theme: -------------------------------------------------------------------------------- 1 | # Theme: tokyo-night 2 | # By: Pascal Jaeger 3 | 4 | # Main bg 5 | theme[main_bg]="#1a1b26" 6 | 7 | # Main text color 8 | theme[main_fg]="#cfc9c2" 9 | 10 | # Title color for boxes 11 | theme[title]="#cfc9c2" 12 | 13 | # Highlight color for keyboard shortcuts 14 | theme[hi_fg]="#7dcfff" 15 | 16 | # Background color of selected item in processes box 17 | theme[selected_bg]="#414868" 18 | 19 | # Foreground color of selected item in processes box 20 | theme[selected_fg]="#cfc9c2" 21 | 22 | # Color of inactive/disabled text 23 | theme[inactive_fg]="#565f89" 24 | 25 | # Misc colors for processes box including mini cpu graphs, details memory graph and details status text 26 | theme[proc_misc]="#7dcfff" 27 | 28 | # Cpu box outline color 29 | theme[cpu_box]="#565f89" 30 | 31 | # Memory/disks box outline color 32 | theme[mem_box]="#565f89" 33 | 34 | # Net up/down box outline color 35 | theme[net_box]="#565f89" 36 | 37 | # Processes box outline color 38 | theme[proc_box]="#565f89" 39 | 40 | # Box divider line and small boxes line color 41 | theme[div_line]="#565f89" 42 | 43 | # Temperature graph colors 44 | theme[temp_start]="#9ece6a" 45 | theme[temp_mid]="#e0af68" 46 | theme[temp_end]="#f7768e" 47 | 48 | # CPU graph colors 49 | theme[cpu_start]="#9ece6a" 50 | theme[cpu_mid]="#e0af68" 51 | theme[cpu_end]="#f7768e" 52 | 53 | # Mem/Disk free meter 54 | theme[free_start]="#9ece6a" 55 | theme[free_mid]="#e0af68" 56 | theme[free_end]="#f7768e" 57 | 58 | # Mem/Disk cached meter 59 | theme[cached_start]="#9ece6a" 60 | theme[cached_mid]="#e0af68" 61 | theme[cached_end]="#f7768e" 62 | 63 | # Mem/Disk available meter 64 | theme[available_start]="#9ece6a" 65 | theme[available_mid]="#e0af68" 66 | theme[available_end]="#f7768e" 67 | 68 | # Mem/Disk used meter 69 | theme[used_start]="#9ece6a" 70 | theme[used_mid]="#e0af68" 71 | theme[used_end]="#f7768e" 72 | 73 | # Download graph colors 74 | theme[download_start]="#9ece6a" 75 | theme[download_mid]="#e0af68" 76 | theme[download_end]="#f7768e" 77 | 78 | # Upload graph colors 79 | theme[upload_start]="#9ece6a" 80 | theme[upload_mid]="#e0af68" 81 | theme[upload_end]="#f7768e" 82 | -------------------------------------------------------------------------------- /.config/nvim/lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 2 | if not (vim.uv or vim.loop).fs_stat(lazypath) then 3 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 4 | local out = vim.fn.system({ 5 | "git", 6 | "clone", 7 | "--filter=blob:none", 8 | "--branch=stable", 9 | lazyrepo, 10 | lazypath, 11 | }) 12 | if vim.v.shell_error ~= 0 then 13 | vim.api.nvim_echo({ 14 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 15 | { out, "WarningMsg" }, 16 | { "\nPress any key to exit..." }, 17 | }, true, {}) 18 | vim.fn.getchar() 19 | os.exit(1) 20 | end 21 | end 22 | vim.opt.rtp:prepend(lazypath) 23 | 24 | require("lazy").setup({ 25 | spec = { 26 | -- Add LazyVim and import its plugins. 27 | { "LazyVim/LazyVim", import = "lazyvim.plugins" }, 28 | -- Import or override with your plugins. 29 | { import = "plugins" }, 30 | }, 31 | defaults = { 32 | -- By default, only LazyVim plugins will be lazy-loaded. Your custom 33 | -- plugins will load during startup. If you know what you're doing, you can 34 | -- set this to `true` to have all your custom plugins lazy-loaded by 35 | -- default. 36 | lazy = false, 37 | -- It's recommended to leave version=false for now, since a lot the plugin 38 | -- that support versioning, have outdated releases, which may break your 39 | -- Neovim install. 40 | version = false, -- Always use the latest git commit. 41 | -- version = "*", -- Try installing the latest stable version for plugins that support semver. 42 | }, 43 | install = { colorscheme = { "tokyonight" } }, 44 | checker = { 45 | enabled = true, -- Check for plugin updates periodically. 46 | notify = false, -- Notify on update. 47 | }, -- Automatically check for plugin updates. 48 | performance = { 49 | rtp = { 50 | -- Disable some rtp plugins. 51 | disabled_plugins = { 52 | "gzip", 53 | -- "matchit", 54 | -- "matchparen", 55 | -- "netrwPlugin", 56 | "tarPlugin", 57 | "tohtml", 58 | "tutor", 59 | "zipPlugin", 60 | }, 61 | }, 62 | }, 63 | }) 64 | -------------------------------------------------------------------------------- /.local/bin/tmux-shell-cmd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Run a shell command in all open tmux sessions, windows and panes. 3 | 4 | set -o pipefail 5 | set -o nounset 6 | 7 | AUTO_KILL="${AUTO_KILL:-}" 8 | KILL= 9 | ARGS=() 10 | 11 | for arg in "${@}"; do 12 | case "${arg}" in 13 | --kill) 14 | KILL=1 15 | ;; 16 | *) 17 | ARGS+=("${arg}") 18 | ;; 19 | esac 20 | done 21 | 22 | COMMAND="${ARGS[*]}" 23 | 24 | if [[ -z "${COMMAND:-}" ]]; then 25 | cat < 30 | EOF 31 | exit 1 32 | fi 33 | 34 | if [[ -n "${KILL}" && -z "${AUTO_KILL}" ]]; then 35 | printf "All processes running in any tmux shell session (nvim, etc.) will be killed, save you work! Are you sure? (y/n) " 36 | read -r yn 37 | 38 | if [[ "${yn}" != "y" ]]; then 39 | printf "\nAborting, your command was not run within any shell session.\n" 40 | exit 41 | fi 42 | fi 43 | 44 | tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index} #{pane_pid}" | while read -r pane pid; do 45 | # The running process will always be your shell (zsh, bash, etc.), in this 46 | # case if we have something like nvim or htop running there will be a child 47 | # process of that pid. 48 | child_pid=$(pgrep -P "${pid}") 49 | was_killed= 50 | 51 | if [[ -n "${KILL}" && -n "${child_pid}" ]]; then 52 | # We're using pkill and kill so child processes get killed for processes 53 | # that spawn a parent which cannot be killed with a normal kill. pkill is 54 | # useful for processes like docker compose up. 55 | kill "${child_pid}" 56 | pkill -P "${child_pid}" 57 | was_killed=1 58 | fi 59 | 60 | # Since we're using Vim key binds we first need to send escape (C-[), sleep a 61 | # tiny bit, then send "i" (insert mode) followed by the command. Without Vim 62 | # binds all of that can go away and you can just send the command directly. 63 | [[ -z "${child_pid}" || -n "${was_killed}" ]] && 64 | tmux send-keys -t "${pane}" "C-[" && 65 | sleep 0.1 && 66 | tmux send-keys -t "${pane}" "i${COMMAND}" "C-m" 67 | done 68 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/theme-hot-reload.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | name = "theme-hot-reload", 4 | dir = vim.fn.stdpath("config"), 5 | config = function() 6 | vim.api.nvim_create_autocmd("User", { 7 | pattern = "LazyReload", 8 | callback = function() 9 | package.loaded["plugins.theme"] = nil 10 | 11 | vim.schedule(function() 12 | local ok, theme_spec = pcall(require, "plugins.theme") 13 | if not ok then 14 | return 15 | end 16 | 17 | local theme_plugin_name = nil 18 | for _, spec in ipairs(theme_spec) do 19 | if spec[1] and spec[1] ~= "LazyVim/LazyVim" then 20 | theme_plugin_name = spec.name or spec[1] 21 | break 22 | end 23 | end 24 | 25 | vim.cmd("highlight clear") 26 | if vim.fn.exists("syntax_on") then 27 | vim.cmd("syntax reset") 28 | end 29 | 30 | vim.o.background = "dark" 31 | 32 | if theme_plugin_name then 33 | local plugin = 34 | require("lazy.core.config").plugins[theme_plugin_name] 35 | if plugin then 36 | local plugin_dir = plugin.dir .. "/lua" 37 | require("lazy.core.util").walkmods( 38 | plugin_dir, 39 | function(modname) 40 | package.loaded[modname] = nil 41 | package.preload[modname] = nil 42 | end 43 | ) 44 | end 45 | end 46 | 47 | for _, spec in ipairs(theme_spec) do 48 | if 49 | spec[1] == "LazyVim/LazyVim" 50 | and spec.opts 51 | and spec.opts.colorscheme 52 | then 53 | local colorscheme = spec.opts.colorscheme 54 | 55 | require("lazy.core.loader").colorscheme(colorscheme) 56 | 57 | vim.defer_fn(function() 58 | pcall(vim.cmd.colorscheme, colorscheme) 59 | vim.cmd("redraw!") 60 | end, 5) 61 | 62 | break 63 | end 64 | end 65 | end) 66 | end, 67 | }) 68 | end, 69 | }, 70 | } 71 | -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | 6 | lint() { 7 | # Lint all supported file types 8 | local shellcheck_cmd=(shellcheck) 9 | local ruff_cmd=(ruff) 10 | 11 | if ! command -v shellcheck >/dev/null 2>&1; then 12 | local shellcheck_cmd=(docker container run --rm -i -v "${PWD}:/mnt" koalaman/shellcheck:stable) 13 | fi 14 | 15 | if ! command -v ruff >/dev/null 2>&1; then 16 | local ruff_cmd=(docker container run --rm -i -v "${PWD}:/io" -u "$(id -u):$(id -g)" ghcr.io/astral-sh/ruff:0.11.1) 17 | fi 18 | 19 | find . -type f \ 20 | ! -path "./.git/*" \ 21 | ! -path "./.ruff_cache/*" \ 22 | ! -path "./.pytest_cache/*" \ 23 | ! -path "./c/*" \ 24 | -exec grep --quiet -E '^(#!.*sh|# shellcheck shell=)' {} \; -exec "${shellcheck_cmd[@]}" {} + 25 | 26 | "${ruff_cmd[@]}" check "${@}" 27 | } 28 | 29 | format() { 30 | # Format all supported file types 31 | local shfmt_cmd=(shfmt) 32 | local ruff_cmd=(ruff) 33 | 34 | if ! command -v shfmt >/dev/null 2>&1; then 35 | local shfmt_cmd=(docker container run --rm -i -v "${PWD}:/mnt" -u "$(id -u):$(id -g)" -w /mnt mvdan/shfmt:v3) 36 | fi 37 | 38 | if ! command -v ruff >/dev/null 2>&1; then 39 | local ruff_cmd=(docker container run --rm -i -v "${PWD}:/io" -u "$(id -u):$(id -g)" ghcr.io/astral-sh/ruff:0.11.1) 40 | fi 41 | 42 | local shfmt_args=("--write") 43 | 44 | for arg in "${@}"; do 45 | [ "${arg}" == "--check" ] && shfmt_args+=("--diff") 46 | 47 | if [ "${arg}" == "-d" ] || [ "${arg}" == "--diff" ] || [ "${shfmt_args[1]}" == "--diff" ]; then 48 | unset "shfmt_args[0]" 49 | fi 50 | done 51 | 52 | "${shfmt_cmd[@]}" "${shfmt_args[@]}" . .config/zsh/.{aliases,zprofile,zshrc} 53 | 54 | "${ruff_cmd[@]}" check --fix 55 | "${ruff_cmd[@]}" format "${@}" 56 | } 57 | 58 | quality() { 59 | # Perform all code quality commands together 60 | lint "${@}" 61 | format "${@}" 62 | } 63 | 64 | ci:test() { 65 | # Execute Continuous Integration (CI) pipeline 66 | lint 67 | format --check --diff 68 | } 69 | 70 | help() { 71 | printf "%s [args]\n\nTasks:\n" "${0}" 72 | 73 | compgen -A function | grep -v "^_" | cat -n 74 | 75 | printf "\nExtended help:\n Each task has comments for general usage\n" 76 | } 77 | 78 | TIMEFORMAT=$'\nTask completed in %3lR' 79 | time "${@:-help}" 80 | -------------------------------------------------------------------------------- /themes/gruvbox-dark-medium/btop.theme: -------------------------------------------------------------------------------- 1 | #Bashtop gruvbox (https://github.com/morhetz/gruvbox) theme 2 | #by BachoSeven 3 | 4 | # Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255" 5 | # example for white: "#FFFFFF", "#ff" or "255 255 255". 6 | 7 | # All graphs and meters can be gradients 8 | # For single color graphs leave "mid" and "end" variable empty. 9 | # Use "start" and "end" variables for two color gradient 10 | # Use "start", "mid" and "end" for three color gradient 11 | 12 | # Main background, empty for terminal default, need to be empty if you want transparent background 13 | theme[main_bg]="#1d2021" 14 | 15 | # Main text color 16 | theme[main_fg]="#a89984" 17 | 18 | # Title color for boxes 19 | theme[title]="#ebdbb2" 20 | 21 | # Highlight color for keyboard shortcuts 22 | theme[hi_fg]="#d79921" 23 | 24 | # Background color of selected items 25 | theme[selected_bg]="#282828" 26 | 27 | # Foreground color of selected items 28 | theme[selected_fg]="#fabd2f" 29 | 30 | # Color of inactive/disabled text 31 | theme[inactive_fg]="#282828" 32 | 33 | # Color of text appearing on top of graphs, i.e uptime and current network graph scaling 34 | theme[graph_text]="#585858" 35 | 36 | # Misc colors for processes box including mini cpu graphs, details memory graph and details status text 37 | theme[proc_misc]="#98971a" 38 | 39 | # Cpu box outline color 40 | theme[cpu_box]="#a89984" 41 | 42 | # Memory/disks box outline color 43 | theme[mem_box]="#a89984" 44 | 45 | # Net up/down box outline color 46 | theme[net_box]="#a89984" 47 | 48 | # Processes box outline color 49 | theme[proc_box]="#a89984" 50 | 51 | # Box divider line and small boxes line color 52 | theme[div_line]="#a89984" 53 | 54 | # Temperature graph colors 55 | theme[temp_start]="#458588" 56 | theme[temp_mid]="#d3869b" 57 | theme[temp_end]="#fb4394" 58 | 59 | # CPU graph colors 60 | theme[cpu_start]="#b8bb26" 61 | theme[cpu_mid]="#d79921" 62 | theme[cpu_end]="#fb4934" 63 | 64 | # Mem/Disk free meter 65 | theme[free_start]="#4e5900" 66 | theme[free_mid]="" 67 | theme[free_end]="#98971a" 68 | 69 | # Mem/Disk cached meter 70 | theme[cached_start]="#458588" 71 | theme[cached_mid]="" 72 | theme[cached_end]="#83a598" 73 | 74 | # Mem/Disk available meter 75 | theme[available_start]="#d79921" 76 | theme[available_mid]="" 77 | theme[available_end]="#fabd2f" 78 | 79 | # Mem/Disk used meter 80 | theme[used_start]="#cc241d" 81 | theme[used_mid]="" 82 | theme[used_end]="#fb4934" 83 | 84 | # Download graph colors 85 | theme[download_start]="#3d4070" 86 | theme[download_mid]="#6c71c4" 87 | theme[download_end]="#a3a8f7" 88 | 89 | # Upload graph colors 90 | theme[upload_start]="#701c45" 91 | theme[upload_mid]="#b16286" 92 | theme[upload_end]="#d3869b" 93 | -------------------------------------------------------------------------------- /.config/tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------- 2 | # This config is targeted for tmux 3.1+. 3 | # 4 | # Read the "Plugin Manager" section (bottom) before trying to use this config! 5 | # ----------------------------------------------------------------------------- 6 | 7 | # ----------------------------------------------------------------------------- 8 | # Global options 9 | # ----------------------------------------------------------------------------- 10 | 11 | # Set a new prefix / leader key. 12 | set -g prefix ` 13 | bind ` send-prefix 14 | 15 | # By default tmux starts a login shell which runs your profile each time you 16 | # open a pane or window. This disables that to prevent your profile script from 17 | # running many times instead of once. This can be problematic when you start 18 | # a window manager from your profile (you don't want multiples of them). 19 | set -g default-command "${SHELL}" 20 | 21 | # Allow opening multiple terminals to view the same session at different sizes. 22 | setw -g aggressive-resize on 23 | 24 | # Remove delay when switching between Vim modes. 25 | set -sg escape-time 1 26 | 27 | # Allow Vim's FocusGained to work when your terminal gains focus. 28 | # Requires Vim plugin: https://github.com/tmux-plugins/vim-tmux-focus-events 29 | set -g focus-events on 30 | 31 | # Add a bit more scroll history in the buffer. 32 | set -g history-limit 50000 33 | 34 | # Enable color support inside of tmux as well as home, end, etc. keys. 35 | set -g default-terminal "screen-256color" 36 | set -ga terminal-overrides ",*256col*:Tc" 37 | 38 | # Send xterm compatible control arrow keys so they work with Vim. 39 | setw -g xterm-keys on 40 | 41 | # Ensure window titles get renamed automatically. 42 | setw -g automatic-rename 43 | 44 | # Ensure window index numbers get reordered on delete. 45 | set-option -g renumber-windows on 46 | 47 | # Start windows and panes index at 1, not 0. 48 | set -g base-index 1 49 | setw -g pane-base-index 1 50 | 51 | # Enable full mouse support. 52 | set -g mouse on 53 | 54 | # Various colors and styles. 55 | source-file "~/.config/tmux/theme.conf" 56 | 57 | set -g status-left "" 58 | set -g status-left-length 0 59 | set -g status-right "" 60 | set -g status-right-length 0 61 | 62 | # Display a clock on the bottom right of the status bar. 63 | #set -g status-right "%a %Y-%m-%d %H:%M" 64 | #set -g status-right-length 20 65 | 66 | # ----------------------------------------------------------------------------- 67 | # Key bindings 68 | # ----------------------------------------------------------------------------- 69 | 70 | # Unbind default keys 71 | unbind C-b 72 | unbind '"' 73 | unbind % 74 | 75 | # Reload the tmux config. 76 | bind-key r source-file "~/.config/tmux/tmux.conf" 77 | 78 | # Split panes. 79 | bind-key b split-window -v 80 | bind-key v split-window -h 81 | 82 | # Move around panes with ALT + arrow keys. 83 | bind-key -n M-Up select-pane -U 84 | bind-key -n M-Left select-pane -L 85 | bind-key -n M-Down select-pane -D 86 | bind-key -n M-Right select-pane -R 87 | 88 | # ----------------------------------------------------------------------------- 89 | # Plugin Manager - https://github.com/tmux-plugins/tpm 90 | # If you didn't use my dotfiles install script you'll need to: 91 | # Step 1) git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm 92 | # Step 2) Reload tmux if it's already started with `r 93 | # Step 3) Launch tmux and hit `I (capital i) to fetch any plugins 94 | # ----------------------------------------------------------------------------- 95 | 96 | # List of plugins. 97 | set -g @plugin "tmux-plugins/tpm" 98 | set -g @plugin "tmux-plugins/tmux-resurrect" 99 | set -g @plugin "tmux-plugins/tmux-yank" 100 | 101 | # Customize where resurrect save files are stored. 102 | set -g @resurrect-dir "~/.config/tmux/resurrect" 103 | 104 | # Avoid using clip.exe in WSL 2 by using our own clipboard copying script. 105 | # This fixes certain UTF-8 encoded chars like emojis or `tree`'s pipes from 106 | # being garbled. See: https://github.com/tmux-plugins/tmux-yank/issues/188 107 | set -g @override_copy_command "clip-copy" 108 | 109 | # Prevent yank from scrolling to the bottom of your buffer after copying. 110 | set -g @yank_action "copy-pipe" 111 | 112 | # Initialize TPM (keep this line at the very bottom of your tmux.conf). 113 | run "~/.config/tmux/plugins/tpm/tpm" 114 | -------------------------------------------------------------------------------- /.config/nvim/lazy-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "LazyVim": { "branch": "main", "commit": "28db03f958d58dfff3c647ce28fdc1cb88ac158d" }, 3 | "LuaSnip": { "branch": "master", "commit": "3732756842a2f7e0e76a7b0487e9692072857277" }, 4 | "SchemaStore.nvim": { "branch": "main", "commit": "3941c524f88fd4b7696bc574d7acde0313ef5bf5" }, 5 | "Vim-Jinja2-Syntax": { "branch": "master", "commit": "2c17843b074b06a835f88587e1023ceff7e2c7d1" }, 6 | "blink.cmp": { "branch": "main", "commit": "b19413d214068f316c78978b08264ed1c41830ec" }, 7 | "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, 8 | "catppuccin": { "branch": "main", "commit": "193e123cdbc4dd3e86db883d55349e9587f0ded6" }, 9 | "conform.nvim": { "branch": "master", "commit": "ffe26e8df8115c9665d24231f8a49fadb2d611ce" }, 10 | "flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" }, 11 | "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, 12 | "gitsigns.nvim": { "branch": "main", "commit": "5813e4878748805f1518cee7abb50fd7205a3a48" }, 13 | "grug-far.nvim": { "branch": "main", "commit": "b58b2d65863f4ebad88b10a1ddd519e5380466e0" }, 14 | "gruvbox.nvim": { "branch": "main", "commit": "5e0a460d8e0f7f669c158dedd5f9ae2bcac31437" }, 15 | "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, 16 | "lazydev.nvim": { "branch": "main", "commit": "5231c62aa83c2f8dc8e7ba957aa77098cda1257d" }, 17 | "lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" }, 18 | "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, 19 | "mason-lspconfig.nvim": { "branch": "main", "commit": "c55bd8a8fb191e24176c206a7af1dd51ce7276a5" }, 20 | "mason.nvim": { "branch": "main", "commit": "57e5a8addb8c71fb063ee4acda466c7cf6ad2800" }, 21 | "mini.ai": { "branch": "main", "commit": "bfb26d9072670c3aaefab0f53024b2f3729c8083" }, 22 | "mini.hipatterns": { "branch": "main", "commit": "add8d8abad602787377ec5d81f6b248605828e0f" }, 23 | "mini.icons": { "branch": "main", "commit": "ff2e4f1d29f659cc2bad0f9256f2f6195c6b2428" }, 24 | "mini.pairs": { "branch": "main", "commit": "472ec50092a3314ec285d2db2baa48602d71fe93" }, 25 | "mini.surround": { "branch": "main", "commit": "88c52297ed3e69ecf9f8652837888ecc727a28ee" }, 26 | "multicursor.nvim": { "branch": "1.0", "commit": "a0ea3303a6c4b233cf3272fb1e358d4c842e5260" }, 27 | "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, 28 | "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, 29 | "nvim-lint": { "branch": "master", "commit": "54c5f839f8b3e3e69afbf2e074be8ac7e5b793b9" }, 30 | "nvim-lspconfig": { "branch": "master", "commit": "a2bd1cf7b0446a7414aaf373cea5e4ca804c9c69" }, 31 | "nvim-treesitter": { "branch": "main", "commit": "b6271b678e035a5cbf62d637364f3eeca0890171" }, 32 | "nvim-treesitter-textobjects": { "branch": "main", "commit": "76deedf0f1cec4496ef8d49b6d1f020f6d0c6ec9" }, 33 | "nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" }, 34 | "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" }, 35 | "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, 36 | "render-markdown.nvim": { "branch": "main", "commit": "b2b135347e299ffbf7f4123fb7811899b0c9f4b8" }, 37 | "snacks.nvim": { "branch": "main", "commit": "fe7cfe9800a182274d0f868a74b7263b8c0c020b" }, 38 | "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, 39 | "tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" }, 40 | "tree-sitter-ghostty": { "branch": "main", "commit": "c2f7af6d7250f63f01401a6d84b3e353e71ff3c3" }, 41 | "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, 42 | "ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" }, 43 | "venv-selector.nvim": { "branch": "main", "commit": "58bae72c84b9f7f864c879ec1896e384296f9ffb" }, 44 | "vim-better-whitespace": { "branch": "master", "commit": "de99b55a6fe8c96a69f9376f16b1d5d627a56e81" }, 45 | "vim-hugo": { "branch": "master", "commit": "324fb8c7371d31701349c1192e25a0bdcf9898f8" }, 46 | "vim-illuminate": { "branch": "master", "commit": "0d1e93684da00ab7c057410fecfc24f434698898" }, 47 | "vim-test": { "branch": "master", "commit": "1eeb12774a0f251571700ccf68da27789b2f0852" }, 48 | "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } 49 | } 50 | -------------------------------------------------------------------------------- /mnt/c/Users/Nick/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$help": "https://aka.ms/terminal-documentation", 3 | "$schema": "https://aka.ms/terminal-profiles-schema", 4 | "actions": [], 5 | "defaultProfile": "{a9741877-f895-512d-a385-bb120648fbbe}", 6 | "keybindings": [ 7 | { 8 | "id": null, 9 | "keys": "alt+down" 10 | }, 11 | { 12 | "id": null, 13 | "keys": "alt+left" 14 | }, 15 | { 16 | "id": null, 17 | "keys": "alt+up" 18 | }, 19 | { 20 | "id": null, 21 | "keys": "alt+right" 22 | }, 23 | { 24 | "id": null, 25 | "keys": "ctrl+shift+k" 26 | } 27 | ], 28 | "multiLinePasteWarning": false, 29 | "newTabMenu": [ 30 | { 31 | "type": "remainingProfiles" 32 | } 33 | ], 34 | "profiles": { 35 | "defaults": { 36 | "adjustIndistinguishableColors": "indexed", 37 | "colorScheme": "tokyonight-moon", 38 | "cursorShape": "filledBox", 39 | "experimental.retroTerminalEffect": false, 40 | "font": { 41 | "face": "Inconsolata Nerd Font", 42 | "size": 10 43 | }, 44 | "opacity": 100, 45 | "padding": "1, 1, 1, 1", 46 | "scrollbarState": "hidden", 47 | "useAcrylic": false 48 | }, 49 | "list": [ 50 | { 51 | "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", 52 | "hidden": false, 53 | "name": "Windows PowerShell" 54 | }, 55 | { 56 | "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", 57 | "hidden": false, 58 | "name": "cmd" 59 | }, 60 | { 61 | "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}", 62 | "hidden": false, 63 | "name": "Azure Cloud Shell", 64 | "source": "Windows.Terminal.Azure" 65 | }, 66 | { 67 | "guid": "{a9741877-f895-512d-a385-bb120648fbbe}", 68 | "hidden": false, 69 | "name": "Arch Linux", 70 | "source": "Microsoft.WSL" 71 | } 72 | ] 73 | }, 74 | "schemes": [ 75 | { 76 | "background": "#282828", 77 | "black": "#282828", 78 | "blue": "#458588", 79 | "brightBlack": "#928374", 80 | "brightBlue": "#83A598", 81 | "brightCyan": "#8EC07C", 82 | "brightGreen": "#B8BB26", 83 | "brightPurple": "#D3869B", 84 | "brightRed": "#FB4934", 85 | "brightWhite": "#EBDBB2", 86 | "brightYellow": "#FABD2F", 87 | "cursorColor": "#FFB261", 88 | "cyan": "#689D6A", 89 | "foreground": "#EBDBB2", 90 | "green": "#98971A", 91 | "name": "gruvbox-dark-medium", 92 | "purple": "#B16286", 93 | "red": "#CC241D", 94 | "selectionBackground": "#FFFFFF", 95 | "white": "#A89984", 96 | "yellow": "#D79921" 97 | }, 98 | { 99 | "background": "#222436", 100 | "black": "#1B1D2B", 101 | "blue": "#82AAFF", 102 | "brightBlack": "#444A73", 103 | "brightBlue": "#82AAFF", 104 | "brightCyan": "#86E1FC", 105 | "brightGreen": "#C3E88D", 106 | "brightPurple": "#FCA7EA", 107 | "brightRed": "#FF757F", 108 | "brightWhite": "#C8D3F5", 109 | "brightYellow": "#FFC777", 110 | "cursorColor": "#C8D3F5", 111 | "cyan": "#86E1FC", 112 | "foreground": "#C8D3F5", 113 | "green": "#C3E88D", 114 | "name": "tokyonight-moon", 115 | "purple": "#C099FF", 116 | "red": "#FF757F", 117 | "selectionBackground": "#2D3F76", 118 | "white": "#828BB8", 119 | "yellow": "#FFC777" 120 | } 121 | ], 122 | "theme": "tokyonight-moon", 123 | "themes": [ 124 | { 125 | "name": "gruvbox-dark-medium", 126 | "tab": { 127 | "background": "#282828FF", 128 | "iconStyle": "default", 129 | "showCloseButton": "always", 130 | "unfocusedBackground": "terminalBackground" 131 | }, 132 | "tabRow": { 133 | "background": "#1D2021FF", 134 | "unfocusedBackground": "#1D2021FF" 135 | }, 136 | "window": { 137 | "applicationTheme": "dark", 138 | "experimental.rainbowFrame": false, 139 | "frame": null, 140 | "unfocusedFrame": null, 141 | "useMica": false 142 | } 143 | }, 144 | { 145 | "name": "tokyonight-moon", 146 | "tab": { 147 | "background": "#2A2E45FF", 148 | "iconStyle": "default", 149 | "showCloseButton": "always", 150 | "unfocusedBackground": "terminalBackground" 151 | }, 152 | "tabRow": { 153 | "background": "#1D1F2EFF", 154 | "unfocusedBackground": "#1D1F2EFF" 155 | }, 156 | "window": { 157 | "applicationTheme": "dark", 158 | "experimental.rainbowFrame": false, 159 | "frame": null, 160 | "unfocusedFrame": null, 161 | "useMica": false 162 | } 163 | } 164 | ] 165 | } 166 | -------------------------------------------------------------------------------- /.config/zsh/.zshrc: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # Load colors so we can access $fg and more. 4 | autoload -U colors && colors 5 | 6 | # Disable CTRL-s from freezing your terminal's output. 7 | stty stop undef 8 | 9 | # Enable comments when working in an interactive shell. 10 | setopt interactive_comments 11 | 12 | # Prompt. Using single quotes around the PROMPT is very important, otherwise 13 | # the git branch will always be empty. Using single quotes delays the 14 | # evaluation of the prompt. Also PROMPT is an alias to PS1. 15 | git_prompt() { 16 | local branch 17 | branch="$(git symbolic-ref HEAD 2>/dev/null | cut -d'/' -f3-)" 18 | local branch_truncated="${branch:0:30}" 19 | if ((${#branch} > ${#branch_truncated})); then 20 | branch="${branch_truncated}..." 21 | fi 22 | 23 | [ -n "${branch}" ] && echo " (${branch})" 24 | } 25 | setopt PROMPT_SUBST 26 | # shellcheck disable=SC2016 27 | PROMPT='%B%{$fg[green]%}%n@%{$fg[green]%}%M %{$fg[blue]%}%~%{$fg[yellow]%}$(git_prompt)%{$reset_color%} %(?.$.%{$fg[red]%}$)%b ' 28 | export PROMPT 29 | 30 | # History settings. 31 | export HISTFILE="${DOTFILES_PATH}/.config/zsh/.zsh_history" 32 | export HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S: " 33 | export HISTSIZE=50000 # History lines stored in mememory. 34 | export SAVEHIST=50000 # History lines stored on disk. 35 | setopt INC_APPEND_HISTORY # Immediately append commands to history file. 36 | setopt HIST_IGNORE_ALL_DUPS # Never add duplicate entries. 37 | setopt HIST_IGNORE_SPACE # Ignore commands that start with a space. 38 | setopt HIST_REDUCE_BLANKS # Remove unnecessary blank lines. 39 | 40 | # Use modern completion system. Other than enabling globdots for showing 41 | # hidden files, these ares values in the default generated zsh config. 42 | autoload -U compinit 43 | compinit 44 | _comp_options+=(globdots) 45 | 46 | zstyle ":completion:*" menu select=2 47 | zstyle ":completion:*" auto-description "specify: %d" 48 | zstyle ":completion:*" completer _expand _complete _correct _approximate 49 | zstyle ":completion:*" format "Completing %d" 50 | zstyle ":completion:*" group-name "" 51 | 52 | # dircolors is a GNU utility that's not on macOS by default. With this not 53 | # being used on macOS it means zsh's complete menu won't have colors. 54 | command -v dircolors >/dev/null 2>&1 && eval "$(dircolors -b)" 55 | 56 | # shellcheck disable=SC2016,SC2296 57 | zstyle ":completion:*:default" list-colors '${(s.:.)LS_COLORS}' 58 | zstyle ":completion:*" list-colors "" 59 | zstyle ":completion:*" list-prompt %SAt %p: Hit TAB for more, or the character to insert%s 60 | zstyle ":completion:*" matcher-list "" "m:{a-z}={A-Z}" "m:{a-zA-Z}={A-Za-z}" "r:|[._-]=* r:|=* l:|=*" 61 | zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s 62 | zstyle ":completion:*" use-compctl false 63 | zstyle ":completion:*" verbose true 64 | 65 | # Use Vim key binds. 66 | bindkey -v 67 | 68 | # Ensure home / end keys continue to work. 69 | bindkey "\e[1~" beginning-of-line 70 | bindkey "\e[H" beginning-of-line 71 | bindkey "\e[7~" beginning-of-line 72 | bindkey "\e[4~" end-of-line 73 | bindkey "\e[F" end-of-line 74 | bindkey "\e[8~" end-of-line 75 | bindkey "\e[3~" delete-char 76 | 77 | # Allows your gpg passphrase prompt to spawn (useful for signing commits). 78 | GPG_TTY="$(tty)" 79 | export GPG_TTY 80 | 81 | # zsh-vi-mode-plugin sets a few key binds such as CTRL+r/p/n which may conflict 82 | # with other binds. This ensures fzf and our binds always win. If you choose 83 | # to remove this zsh plugin then each array item can exist normally in zshrc. 84 | zvm_after_init_commands+=( 85 | ". <(fzf --zsh)" 86 | "bindkey '^p' history-search-backward" 87 | "bindkey '^n' history-search-forward" 88 | "bindkey '^[OA' history-search-backward" 89 | "bindkey '^[OB' history-search-forward" 90 | "bindkey '^[[A' history-search-backward" 91 | "bindkey '^[[B' history-search-forward" 92 | ) 93 | 94 | # Configure fzf. 95 | # shellcheck disable=SC1091 96 | . "${XDG_CONFIG_HOME}/fzf/config.sh" 97 | 98 | # zsh-autosuggestions settings. 99 | export ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20 100 | 101 | # Load / source zsh plugins. 102 | # shellcheck disable=SC1091 103 | . "${XDG_DATA_HOME}/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh" 104 | # shellcheck disable=SC1091 105 | . "${XDG_DATA_HOME}/zsh-autosuggestions/zsh-autosuggestions.zsh" 106 | # shellcheck disable=SC1091 107 | . "${XDG_DATA_HOME}/zsh-vi-mode/zsh-vi-mode.plugin.zsh" 108 | # shellcheck disable=SC1091 109 | . "${XDG_DATA_HOME}/fzf-tab/fzf-tab.plugin.zsh" 110 | 111 | # Ensure colors match by using FZF_DEFAULT_OPTS. 112 | zstyle ":fzf-tab:*" use-fzf-default-opts yes 113 | 114 | # Preview file contents when tab completing directories. 115 | zstyle ":fzf-tab:complete:cd:*" fzf-preview "ls --color=always \${realpath}" 116 | 117 | # Load aliases if they exist. 118 | # shellcheck disable=SC1091 119 | [ -f "${XDG_CONFIG_HOME}/zsh/.aliases" ] && . "${XDG_CONFIG_HOME}/zsh/.aliases" 120 | 121 | # Load local settings if they exist. 122 | # shellcheck disable=SC1091 123 | [ -f "${XDG_CONFIG_HOME}/zsh/.zshrc.local" ] && . "${XDG_CONFIG_HOME}/zsh/.zshrc.local" 124 | # shellcheck disable=SC1091 125 | if [ -f "${XDG_CONFIG_HOME}/zsh/.aliases.local" ]; then . "${XDG_CONFIG_HOME}/zsh/.aliases.local"; fi 126 | -------------------------------------------------------------------------------- /.local/bin/pkg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Manage packages using Pacman (Arch) and Yay (AUR) repositories. 3 | 4 | set -o errexit 5 | set -o pipefail 6 | set -o nounset 7 | 8 | if [ -r /etc/os-release ]; then 9 | # shellcheck disable=SC1091 10 | OS_DISTRO="$(. /etc/os-release && echo "${ID_LIKE:-${ID}}")" 11 | if [ "${OS_DISTRO}" != "arch" ]; then 12 | echo "This script is only available on Arch Linux, sorry!" >&2 13 | exit 1 14 | fi 15 | fi 16 | 17 | POSITION=0 18 | CMD= 19 | AUR= 20 | 21 | usage() { 22 | cat <&2 68 | usage >&2 69 | exit 1 70 | ;; 71 | esac 72 | ;; 73 | esac 74 | done 75 | 76 | [[ -z "${CMD}" ]] && usage >&2 && exit 1 77 | 78 | fzf_args() { 79 | local prompt="${1}" 80 | local preview="${2}" 81 | local tiebreak="${3:-}" 82 | 83 | local args=( 84 | --multi 85 | --prompt "${prompt} " 86 | --delimiter "::" 87 | --preview "${preview}" 88 | --preview-window "down:55%:wrap" 89 | --preview-label-pos "bottom" 90 | --preview-label " tab: multi-select, shift+tab: deselect " 91 | ) 92 | 93 | [ -n "${tiebreak}" ] && args+=(--nth "1,2" --tiebreak "begin,index") 94 | 95 | printf "%s\n" "${args[@]}" 96 | } 97 | 98 | install() { 99 | local packages= 100 | 101 | # shellcheck disable=SC2016 102 | mapfile -t fzf_opts \ 103 | < <(fzf_args "Search packages to install..." 'pacman -Si $(echo {} | cut -d " " -f 1)' "tiebreak") 104 | 105 | packages="$( 106 | pacman -Ss "" | awk ' 107 | /^[a-z]+\/[^\s]+/ { 108 | split($1,a,"/") 109 | pkg = a[2] 110 | getline desc 111 | sub(/^[ \t]+/, "", desc) 112 | printf "%s :: %s\n", pkg, desc 113 | }' | 114 | fzf "${fzf_opts[@]}" | cut -d " " -f 1 115 | )" 116 | 117 | if [ -n "${packages}" ]; then 118 | # shellcheck disable=SC2086 119 | sudo pacman -Syu --needed ${packages} 120 | fi 121 | } 122 | 123 | install_aur() { 124 | local packages= 125 | 126 | local query packages= 127 | 128 | read -rp "Enter AUR search query (at least 3 characters): " query 129 | 130 | if [[ ${#query} -lt 3 ]]; then 131 | echo "'${query}' must be 3 or more characters, aborting!" >&2 132 | exit 1 133 | fi 134 | 135 | # shellcheck disable=SC2016 136 | mapfile -t fzf_opts \ 137 | < <(fzf_args "Filter AUR packages to install..." 'yay -Si $(echo {} | cut -d " " -f 1)' "tiebreak") 138 | 139 | packages="$( 140 | yay -Ssa "$query" | awk ' 141 | /^[^ ]/ { 142 | split($1, a, "/") 143 | pkg = a[2] 144 | next 145 | } 146 | /^[ ]/ { 147 | desc = $0 148 | sub(/^[ \t]+/, "", desc) 149 | printf "%s :: %s\n", pkg, desc 150 | } 151 | ' | 152 | fzf "${fzf_opts[@]}" | cut -d " " -f 1 153 | )" 154 | 155 | if [ -n "${packages}" ]; then 156 | # shellcheck disable=SC2086 157 | yay -S --answerclean N --needed ${packages} 158 | fi 159 | } 160 | 161 | list() { 162 | local packages= 163 | 164 | # shellcheck disable=SC2016 165 | mapfile -t fzf_opts \ 166 | < <(fzf_args "Search installed packages..." 'pacman -Qi $(echo {} | cut -d " " -f 1)' "tiebreak") 167 | 168 | packages="$( 169 | pacman -Qei | awk ' 170 | BEGIN { name = ""; desc = "" } 171 | /^Name\s*:/ { name = $3 } 172 | /^Description\s*:/ { desc = substr($0, index($0,$3)) } 173 | /^$/ && name != "" && desc != "" { 174 | printf "%s :: %s\n", name, desc 175 | name = ""; desc = "" 176 | }' | fzf "${fzf_opts[@]}" 177 | )" 178 | } 179 | 180 | list_aur() { 181 | local packages= 182 | 183 | # shellcheck disable=SC2016 184 | mapfile -t fzf_opts \ 185 | < <(fzf_args "Search installed AUR packages..." 'yay -Qi $(echo {} | cut -d" " -f1)' "tiebreak") 186 | 187 | packages="$( 188 | yay -Qm | awk ' 189 | { 190 | pkg = $1 191 | cmd = "yay -Qi " pkg " 2>/dev/null | grep -m1 \"^Description\"" 192 | desc = "" 193 | if ((cmd | getline line) > 0) { 194 | sub(/^[^:]*:\s*/, "", line) 195 | desc = line 196 | } 197 | close(cmd) 198 | printf "%s :: %s\n", pkg, desc 199 | }' | fzf "${fzf_opts[@]}" 200 | )" 201 | } 202 | 203 | remove() { 204 | local packages= 205 | 206 | # shellcheck disable=SC2016 207 | mapfile -t fzf_opts \ 208 | < <(fzf_args "Search installed packages to remove..." 'pacman -Qi $(echo {} | cut -d " " -f 1)' "tiebreak") 209 | 210 | packages="$( 211 | pacman -Qei | awk ' 212 | BEGIN { name = ""; desc = "" } 213 | /^Name\s*:/ { name = $3 } 214 | /^Description\s*:/ { desc = substr($0, index($0,$3)) } 215 | /^$/ && name != "" && desc != "" { 216 | printf "%s :: %s\n", name, desc 217 | name = ""; desc = "" 218 | }' | fzf "${fzf_opts[@]}" | cut -d " " -f 1 219 | )" 220 | 221 | if [ -n "${packages}" ]; then 222 | # shellcheck disable=SC2086 223 | sudo pacman -Rns ${packages} 224 | fi 225 | } 226 | 227 | remove_aur() { 228 | local packages= 229 | 230 | # shellcheck disable=SC2016 231 | mapfile -t fzf_opts \ 232 | < <(fzf_args "Search installed AUR packages to remove..." 'yay -Qi $(echo {} | cut -d " " -f 1)' "tiebreak") 233 | 234 | # This is the same code as listing from the AUR plus an added cut pipe. This 235 | # could be refactored at some point, for now it's not the end of the world. 236 | packages="$( 237 | yay -Qm | awk ' 238 | { 239 | pkg = $1 240 | cmd = "yay -Qi " pkg " 2>/dev/null | grep -m1 \"^Description\"" 241 | desc = "" 242 | if ((cmd | getline line) > 0) { 243 | sub(/^[^:]*:\s*/, "", line) 244 | desc = line 245 | } 246 | close(cmd) 247 | printf "%s :: %s\n", pkg, desc 248 | }' | fzf "${fzf_opts[@]}" | cut -d " " -f 1 249 | )" 250 | 251 | if [ -n "${packages}" ]; then 252 | # shellcheck disable=SC2086 253 | sudo pacman -Rns ${packages} 254 | fi 255 | } 256 | 257 | if [[ "${CMD}" = "install" && -z "${AUR}" ]]; then 258 | install 259 | elif [[ "${CMD}" = "install" && -n "${AUR}" ]]; then 260 | install_aur 261 | elif [[ "${CMD}" = "list" && -z "${AUR}" ]]; then 262 | list 263 | elif [[ "${CMD}" = "list" && -n "${AUR}" ]]; then 264 | list_aur 265 | elif [[ "${CMD}" = "remove" && -z "${AUR}" ]]; then 266 | remove 267 | elif [[ "${CMD}" = "remove" && -n "${AUR}" ]]; then 268 | remove_aur 269 | else 270 | printf "Unknown command: %s\n\n" "${CMD}" >&2 271 | usage >&2 272 | exit 1 273 | fi 274 | -------------------------------------------------------------------------------- /install-config.example: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | 5 | # You can find the default values in the install script near the top of the 6 | # file. Any value here which is empty will be ignored and the default value 7 | # will be used. The non-example version of this file is git ignored. 8 | # 9 | # The goal of this config is to help you customize the defaults for a few 10 | # common things without needing to fork the repo. 11 | # 12 | # I also use some of these to further customize my system with packages that 13 | # I didn't push up to my dotfiles. 14 | 15 | # Provide a different repo to use. This could be useful if you've forked the 16 | # project into your account. If you're using GitHub you only need to 17 | # update DOTFILES_REPO_SLUG, ie. youraccount/dotfiles. 18 | export DOTFILES_REPO_SLUG="${DOTFILES_REPO_SLUG:-nickjj/dotfiles}" 19 | export DOTFILES_CLONE_URL="${DOTFILES_CLONE_URL:-https://github.com/${DOTFILES_REPO_SLUG}}" 20 | export DOTFILES_UPSTREAM_URL="${DOTFILES_UPSTREAM_URL:-https://github.com/nickjj/dotfiles}" 21 | 22 | # Provide a different remote branch. This branch will be merged into your 23 | # current locally checked out branch when pulling in updates. 24 | export DOTFILES_BRANCH="${DOTFILES_BRANCH:-master}" 25 | 26 | # If you define these, they will get used instead of prompting you. Keep in 27 | # mind you won't be prompted once you've answered them once since the values 28 | # get persisted and read independent of these values. Still, this could be 29 | # handy to set for fresh systems to avoid ever needing to input them manually. 30 | export YOUR_NAME= 31 | export YOUR_EMAIL= 32 | 33 | # XDG paths. If you ever want to change them then change them here, they will 34 | # get written to the correct files from this script, there's a few spots! 35 | # 36 | # I use the defaults and I suggest you do the same, here's the source: 37 | # https://specifications.freedesktop.org/basedir/latest/ 38 | export XDG_CACHE_HOME="${HOME}/.cache" 39 | export XDG_CONFIG_HOME="${HOME}/.config" 40 | export XDG_DATA_HOME="${HOME}/.local/share" 41 | export XDG_STATE_HOME="${HOME}/.local/state" 42 | 43 | # Override which packages get installed. If you define anything in the extras 44 | # variable they will get appended to the non-extra packages. This lets you use 45 | # the default packages but add any extra packages you want. 46 | # 47 | # If you don't want to install any default packages then you can use a single 48 | # quoted space as the value, for example: export PACMAN_PACKAGES=" " 49 | export PACMAN_PACKAGES= 50 | export PACMAN_PACKAGES_EXTRAS= 51 | 52 | # Override which packages get installed. If you define anything in the extras 53 | # variable they will get appended to the non-extra packages. This lets you use 54 | # the default packages but add any extra packages you want. 55 | # 56 | # If you don't want to install any default packages then you can use a single 57 | # quoted space as the value, for example: export AUR_PACKAGES=" " 58 | export AUR_PACKAGES= 59 | export AUR_PACKAGES_EXTRAS= 60 | 61 | # Override which packages get installed. If you define anything in the extras 62 | # variable they will get appended to the non-extra packages. This lets you use 63 | # the default packages but add any extra packages you want. 64 | # 65 | # If you don't want to install any default packages then you can use a single 66 | # quoted space as the value, for example: export APT_PACKAGES=" " 67 | export APT_PACKAGES= 68 | export APT_PACKAGES_EXTRAS= 69 | 70 | # Override which packages get installed. If you define anything in the extras 71 | # variable they will get appended to the non-extra packages. This lets you use 72 | # the default packages but add any extra packages you want. 73 | # 74 | # If you don't want to install any default packages then you can use a single 75 | # quoted space as the value, for example: export BREW_CASK_PACKAGES=" " 76 | export BREW_PACKAGES= 77 | export BREW_PACKAGES_EXTRAS= 78 | export BREW_CASK_PACKAGES= 79 | export BREW_CASK_PACKAGES_EXTRAS= 80 | 81 | # Install Mise packages for specific platforms. For example, maybe you want 82 | # the latest and greatest versions on Debian for a few tools but Arch and 83 | # macOS already have them so you don't need Mise packages there. 84 | # 85 | # However, maybe on Arch if you want a specific version of a tool, you can 86 | # use Mise to install it instead of ignoring it with Pacman to avoid a partial 87 | # update of your system. It may also not exist in the official Arch repo too. 88 | # 89 | # If you don't want to install any default packages then you can use a single 90 | # quoted space as the value, for example: export MISE_PACKAGES_DEBIAN=" " 91 | export MISE_PACKAGES_ARCH= 92 | export MISE_PACKAGES_ARCH_EXTRAS= 93 | 94 | export MISE_PACKAGES_DEBIAN= 95 | export MISE_PACKAGES_DEBIAN_EXTRAS= 96 | 97 | export MISE_PACKAGES_MACOS= 98 | export MISE_PACKAGES_MACOS_EXTRAS= 99 | 100 | # Install programming languages. 101 | # 102 | # If you don't want to install any default languages then you can use a single 103 | # quoted space as the value, for example: export MISE_LANGUAGES=" " 104 | declare -A MISE_LANGUAGES= 105 | declare -A MISE_LANGUAGES_EXTRAS= 106 | 107 | # Here's an example to demonstrate the syntax. The key is the binary name and 108 | # the value is what you would pass into Mise to install it. 109 | # MISE_LANGUAGES_EXTRAS["ruby"]="ruby@3.4" 110 | 111 | export MISE_LANGUAGES 112 | export MISE_LANGUAGES_EXTRAS 113 | 114 | # Symlinks that will get created in all operating systems. This lets you add 115 | # your own custom tools and set up whatever configuration you may need. Chances 116 | # are you'll want to customize the SYMLINKS_EXTRAS variable to add new things. 117 | export SYMLINKS=( 118 | "ln -fns \"\${DOTFILES_PATH}/.config/bat/config\" \"\${XDG_CONFIG_HOME}/bat/config\"" 119 | "ln -fns \"\${DOTFILES_PATH}/.config/btop/btop.conf\" \"\${XDG_CONFIG_HOME}/btop/btop.conf\"" 120 | "ln -fns \"\${DOTFILES_PATH}/.config/fzf/config.sh\" \"\${XDG_CONFIG_HOME}/fzf/config.sh\"" 121 | "ln -fns \"\${DOTFILES_PATH}/.config/ghostty/config.local\" \"\${XDG_CONFIG_HOME}/ghostty/config.local\"" 122 | "ln -fns \"\${DOTFILES_PATH}/.config/ghostty/config\" \"\${XDG_CONFIG_HOME}/ghostty/config\"" 123 | "ln -fns \"\${DOTFILES_PATH}/.config/git/config.local\" \"\${XDG_CONFIG_HOME}/git/config.local\"" 124 | "ln -fns \"\${DOTFILES_PATH}/.config/git/config\" \"\${XDG_CONFIG_HOME}/git/config\"" 125 | "ln -fns \"\${DOTFILES_PATH}/.config/nvim\" \"\${XDG_CONFIG_HOME}/nvim\"" 126 | "ln -fns \"\${DOTFILES_PATH}/.config/tmux/tmux.conf\" \"\${XDG_CONFIG_HOME}/tmux/tmux.conf\"" 127 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.aliases.local\" \"\${XDG_CONFIG_HOME}/zsh/.aliases.local\"" 128 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.aliases\" \"\${XDG_CONFIG_HOME}/zsh/.aliases\"" 129 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.xdg.local\" \"\${XDG_CONFIG_HOME}/zsh/.xdg.local\"" 130 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.zprofile.local\" \"\${XDG_CONFIG_HOME}/zsh/.zprofile.local\"" 131 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.zprofile\" \"\${XDG_CONFIG_HOME}/zsh/.zprofile\"" 132 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.zshenv\" \"\${HOME}/.zshenv\"" 133 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.zshrc.local\" \"\${XDG_CONFIG_HOME}/zsh/.zshrc.local\"" 134 | "ln -fns \"\${DOTFILES_PATH}/.config/zsh/.zshrc\" \"\${XDG_CONFIG_HOME}/zsh/.zshrc\"" 135 | "ln -fns \"\${DOTFILES_PATH}/.local/bin/\"* \"\${HOME}/.local/bin/\"" 136 | ) 137 | export SYMLINKS_EXTRAS= 138 | 139 | # Symlinks that will get created only in WSL. 140 | export SYMLINKS_WSL=( 141 | "cp \"\${DOTFILES_PATH}/mnt/c/Users/Nick/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json\" \"/mnt/c/Users/%WindowsUser/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json\" || true" 142 | "sudo ln -fns \"\${DOTFILES_PATH}/etc/wsl.conf\" \"/etc/wsl.conf\"" 143 | ) 144 | export SYMLINKS_WSL_EXTRAS= 145 | 146 | # Symlinks that will get created only on Arch Linux. 147 | export SYMLINKS_ARCH=( 148 | "sudo ln -fns \"\${DOTFILES_PATH}/etc/pacman.d/01-options.conf\" \"/etc/pacman.d/01-options.conf\"" 149 | ) 150 | export SYMLINKS_ARCH_EXTRAS= 151 | -------------------------------------------------------------------------------- /.config/nvim/spell/en.utf-8.add: -------------------------------------------------------------------------------- 1 | 1080p 2 | 3D 3 | ACH 4 | ACM 5 | ActiveJob 6 | ActiveRecord 7 | ADHOC 8 | AGPL 9 | AHK 10 | Airtable 11 | Akka 12 | Alacritty 13 | AMD64 14 | AMI 15 | AMIs 16 | analytics 17 | Analytics 18 | And 19 | AngularJS 20 | anonymized 21 | Ansible 22 | Ansible's 23 | ap 24 | APIs 25 | APM 26 | APS 27 | arg 28 | argparse 29 | args 30 | ARGs 31 | ARM64 32 | asdf 33 | async 34 | AT2005 35 | AutoHotkey 36 | AutoHotKey 37 | AWS 38 | B2B 39 | backports 40 | BackupPC 41 | balancer 42 | base64 43 | benchmarking 44 | Benchmarking 45 | BigQuery 46 | Bitbucket 47 | blockchain 48 | BOM 49 | boolean 50 | Braintree 51 | BuildKit 52 | buildpack 53 | Buildx 54 | bundler 55 | Caddy 56 | callout 57 | callouts 58 | Camtasia 59 | Capistrano 60 | CapRover 61 | card 62 | CDN 63 | centos 64 | CentOS 65 | centric 66 | Certbot 67 | changelog 68 | chown'ing 69 | Chroma 70 | Chromebook 71 | CI 72 | CIDR 73 | CircleCI 74 | CLI 75 | ClickHouse 76 | Cloudflare 77 | CloudFormation 78 | CloudFormation's 79 | CloudFront 80 | Cloudlifter 81 | CloudWatch 82 | CMD 83 | CME 84 | CMS 85 | CNAME 86 | codebase 87 | codebases 88 | CodeIgniter 89 | CommonMark 90 | compgen 91 | Compose's 92 | ConEmu 93 | config 94 | configs 95 | Connexion 96 | containerd 97 | Coronavirus 98 | CPUs 99 | CRM 100 | cron 101 | Cron 102 | Cronitor 103 | cryptocurrency 104 | CSRF 105 | CSS 106 | CSV 107 | CTO 108 | CTRL 109 | DaemonSet 110 | Datadog 111 | Datadog's 112 | datetime 113 | DaVinci 114 | DAW 115 | DBeaver 116 | DDD 117 | DDoS 118 | DebOps 119 | declaratively 120 | decrypt 121 | decrypted 122 | decrypting 123 | deliverables 124 | deployable 125 | deploy's 126 | deserializer 127 | dev 128 | DevOps 129 | devs 130 | DexPot 131 | DigitalOcean 132 | DigitalOcean's 133 | dir 134 | Disqus 135 | distro 136 | distro's 137 | distros 138 | Django 139 | DKIM 140 | DMARC 141 | DNS 142 | dnsmasq 143 | DockerCon 144 | Dockerfile 145 | Dockerfiles 146 | Dockerize 147 | Dockerized 148 | Docker's 149 | dockershim 150 | dotfiles 151 | Dragonpad 152 | DropBox 153 | DuckDuckGo 154 | Dyno 155 | Dynos 156 | EBS 157 | EC2 158 | ECDSA 159 | ECR 160 | ECS 161 | Ecto 162 | Ed25519 163 | Edgestore 164 | EEx 165 | EKS 166 | eksctl 167 | ElastiCache 168 | Elasticsearch 169 | ELB 170 | ElephantSQL 171 | EmberJS 172 | entrypoint 173 | env 174 | ENV 175 | envsubst 176 | ERD 177 | esbuild 178 | eslint 179 | ESLint 180 | ETS 181 | eval 182 | extensibility 183 | Fargate 184 | FastAPI 185 | Fastly 186 | Favicon 187 | FFmpeg 188 | Firebase 189 | Flake8 190 | Flatpickr 191 | FlexiSpot 192 | Focusrite 193 | foobar2000 194 | Freshping 195 | frictionless 196 | frontmatter 197 | fzf 198 | fzf's 199 | GalliumOS 200 | GCP 201 | GCP's 202 | GDPR 203 | Gemfile 204 | Genomic 205 | GenServer 206 | Geocities 207 | GID 208 | gifs 209 | Gigalixir 210 | Gitlab 211 | GitLab 212 | GitOps 213 | git's 214 | GitUI 215 | GKE 216 | globbing 217 | globstar 218 | GlusterFS 219 | gmail 220 | gmail's 221 | GnuCash 222 | Golang 223 | Golang's 224 | GoodJob 225 | Google'd 226 | GoRails 227 | GovCloud 228 | GPG 229 | Gracenote 230 | Grafana 231 | Graphene 232 | GraphQL 233 | Gruvbox 234 | Gumroad 235 | Gunicorn 236 | Gunicorn's 237 | GVim 238 | gzip 239 | gzipped 240 | hackaton 241 | HackerNews 242 | hacky 243 | Hadolint 244 | haha 245 | HashiCorp 246 | Hatchbox 247 | HCL 248 | healthcheck 249 | hellobar2000 250 | heredoc 251 | Heroku 252 | Heroku's 253 | HexChat 254 | HIPAA 255 | Honeybadger 256 | hostname 257 | hostnames 258 | Hotjar 259 | Hotwire 260 | html 261 | htop 262 | HTTPS 263 | i2 264 | i3 265 | IaC 266 | IAM 267 | Idempotency 268 | IE8 269 | IIS 270 | impactful 271 | InertiaJS 272 | InfluxDB 273 | InnoGear 274 | integrations 275 | IOPS 276 | iOS 277 | IPs 278 | IPS 279 | iptables 280 | IPv4 281 | IPv6 282 | IrfanView 283 | irreproducible 284 | ish 285 | ISP's 286 | iTerm2 287 | Javascript 288 | Jinja 289 | Jira 290 | JIT 291 | journald 292 | jQuery 293 | JS 294 | JSON 295 | JSONB 296 | Jumpstart 297 | Jupyter 298 | JupyterLab 299 | K8s 300 | Kanban 301 | keymaps 302 | keyring 303 | Keyserver 304 | KinD 305 | Knex 306 | Koa 307 | KPI 308 | kubectl 309 | Kubernetes 310 | Kustomize 311 | Laravel 312 | LastPass 313 | LazyVim 314 | libs 315 | Linode 316 | Linode's 317 | linter 318 | linters 319 | linux 320 | LiveView 321 | Livewire 322 | LOC 323 | localhost 324 | localStorage 325 | Logentries 326 | Loggly 327 | LTS 328 | Lua 329 | M1 330 | MacBook 331 | macOS 332 | Magento 333 | Mailchimp 334 | Mailgun 335 | Makefile 336 | MariaDB 337 | master 338 | MBPs 339 | MD5 340 | memcached 341 | Memcached 342 | Metadata 343 | microservice 344 | microservices 345 | Microservices 346 | middleware 347 | minified 348 | minifies 349 | Minify 350 | mintty 351 | Mise 352 | Mixpanel 353 | MobaXterm 354 | Moby 355 | MobyLinux 356 | Modularity 357 | MongoDB 358 | mortem 359 | MP3 360 | MP3's 361 | mtime 362 | multiline 363 | Mux 364 | mysql 365 | MySQL 366 | mysqldump 367 | namespace 368 | namespaced 369 | Namespacing 370 | NEEWER 371 | Neo4j 372 | Neovim 373 | NERDTree 374 | Netcat 375 | Netlify 376 | nginx 377 | NGiNX 378 | ngrok 379 | nitty 380 | Noctua 381 | Nokogiri 382 | NoSQL 383 | NumPy 384 | nvim 385 | OAuth 386 | Oban 387 | observability 388 | ok 389 | OKR 390 | Okta 391 | OpenAPI 392 | OpenBSD 393 | OpenGraph 394 | OpenJDK 395 | OpenKeychain 396 | OpenSSH 397 | openssl 398 | OpenWrt 399 | OpsGenie 400 | ORM 401 | OTP 402 | Overcomplicating 403 | OVH 404 | PaaS 405 | Pacman 406 | PagerDuty 407 | Pandoc 408 | Papertrail 409 | PaymentIntents 410 | PDFs 411 | peasy 412 | pem 413 | pem's 414 | performant 415 | Permalink 416 | pgAdmin 417 | Photoshop 418 | PHP 419 | PHP's 420 | pid 421 | PII 422 | Pingdom 423 | Pinterest 424 | Pipenv 425 | pjax 426 | PKI 427 | pkill 428 | Plan9 429 | PM2 430 | podcasting 431 | POSIX 432 | PostCSS 433 | Postgres 434 | PostgreSQL 435 | POV 436 | PowerShell 437 | PowerToys 438 | PPA 439 | PPI 440 | pre 441 | Prepending 442 | printf 443 | Prisma 444 | Procfile 445 | programmatically 446 | Propshaft 447 | PRs 448 | psql 449 | purs 450 | pwgen 451 | Pygments 452 | PyPi 453 | PyPI 454 | Pytest 455 | PythonAnywhere 456 | QuakeLive 457 | queueing 458 | QuickBook's 459 | QuickBooks 460 | RabbitMQ 461 | Rbenv 462 | rc 463 | RDS 464 | README 465 | rebase 466 | Recurly 467 | Reddit 468 | RedHat 469 | Redis 470 | Redux 471 | Rekognition 472 | Rekognition's 473 | relatable 474 | RelPermalink 475 | renderers 476 | repo 477 | repo's 478 | repos 479 | repurposed 480 | resize 481 | Resque 482 | RESTful 483 | RESTPlus 484 | RGB 485 | RHEL 486 | Rogan 487 | Rollbar 488 | rollout 489 | Route53 490 | RPMs 491 | RQ 492 | RSA 493 | RSS 494 | rsync 495 | Rubocop 496 | RubyGems 497 | runnable 498 | runtimes 499 | S3 500 | SAAS 501 | SageMaker 502 | SBOM 503 | SCA 504 | scalable 505 | ScaleGrid 506 | Scarlett 507 | schemas 508 | SCP 509 | screencast 510 | screencasts 511 | SCSS 512 | SDK 513 | SDKs 514 | SealedSecrets 515 | searchable 516 | sed 517 | sendgrid 518 | SendGrid 519 | Sendy 520 | Sennheiser 521 | SEO 522 | serializer 523 | Serverless 524 | ServerPilot 525 | SES 526 | SHA 527 | ShellCheck 528 | shfmt 529 | Shopify 530 | Shopify's 531 | shortcode 532 | shortcodes 533 | Shortcodes 534 | Shure 535 | sibilance 536 | Sidekiq 537 | Sidekiq's 538 | SIGKILL 539 | SIGTERM 540 | sitemap 541 | Sitemap 542 | SKUs 543 | SM7B 544 | SMTP 545 | SNS 546 | Snyk 547 | SocketIO 548 | Solr 549 | SparkPost 550 | Splunk 551 | sql 552 | SQLAlchemy 553 | SQLite 554 | SQS 555 | SRE 556 | SSD 557 | SSDs 558 | SSL 559 | SSO 560 | StackOverflow 561 | StackSet 562 | stateful 563 | stderr 564 | STDIN 565 | stdout 566 | StimulusJS 567 | StimulusReflex 568 | Strapi 569 | subnet 570 | subnets 571 | substring 572 | sudo 573 | swiss 574 | symlink 575 | symlinked 576 | symlinks 577 | syslog 578 | systemd 579 | t2 580 | Tailkit 581 | Tailkit's 582 | TailwindCSS 583 | TailwindUI 584 | TCP 585 | Technica 586 | templated 587 | templating 588 | Tensorflow 589 | Terraform 590 | Terraform's 591 | Textract 592 | That'll 593 | Theorycrafting 594 | Threadripper 595 | Timestamped 596 | timestamps 597 | TLD 598 | TLS 599 | tmux 600 | toc 601 | TODO 602 | Tokyonight 603 | TOML 604 | tooltip 605 | Traefik 606 | transactional 607 | transcoding 608 | Trix 609 | TTY 610 | Turbolinks 611 | TXT 612 | TypeScript 613 | Udemy 614 | UI 615 | UID 616 | Umar 617 | uncomment 618 | Unikernel 619 | Unikernels 620 | unlike 621 | unmaintained 622 | unmarking 623 | unopinionated 624 | unstage 625 | unstaged 626 | unstaging 627 | untracked 628 | uprecords 629 | uptime 630 | Uptime 631 | UptimeRobot 632 | URI 633 | url 634 | UTF-8 635 | UUID 636 | uvicorn 637 | uwsgi 638 | VB6 639 | vCPUs 640 | VcXsrv 641 | Vercel 642 | versioning 643 | Vertica 644 | vhost 645 | Vimeo 646 | VirtualBox 647 | Virtualenv 648 | virtualized 649 | vLAN 650 | VM 651 | VMs 652 | VNC 653 | VPC 654 | VPN 655 | VPS 656 | vscode 657 | VSCode 658 | VSCode's 659 | VST 660 | VSTs 661 | Vue 662 | VueJS 663 | webcomic 664 | webhook 665 | webhooks 666 | Webpack 667 | Webpacker 668 | WebSockets 669 | WezTerm 670 | WhatsApp 671 | whitelisting 672 | whitespace 673 | Wi-Fi 674 | wildcard 675 | Wireshark 676 | Wistia 677 | WordPress 678 | workspace 679 | writeable 680 | wrk 681 | WSL 682 | WSLg 683 | wsltty 684 | WTF'd 685 | www 686 | Xenial 687 | XLR 688 | YAML 689 | Yay 690 | YCombinator 691 | Youtube 692 | Zapier 693 | Zope 694 | zsh 695 | Zsh 696 | zsh's 697 | -------------------------------------------------------------------------------- /.config/btop/btop.conf: -------------------------------------------------------------------------------- 1 | #? Config file for btop v.1.4.5 2 | 3 | #* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. 4 | #* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" 5 | color_theme = "theme" 6 | 7 | #* If the theme set background should be shown, set to False if you want terminal background transparency. 8 | theme_background = true 9 | 10 | #* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false. 11 | truecolor = true 12 | 13 | #* Set to true to force tty mode regardless if a real tty has been detected or not. 14 | #* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols. 15 | force_tty = false 16 | 17 | #* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets. 18 | #* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box. 19 | #* Use whitespace " " as separator between different presets. 20 | #* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty" 21 | presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty" 22 | 23 | #* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists. 24 | #* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift. 25 | vim_keys = false 26 | 27 | #* Rounded corners on boxes, is ignored if TTY mode is ON. 28 | rounded_corners = true 29 | 30 | #* Use terminal synchronized output sequences to reduce flickering on supported terminals. 31 | terminal_sync = true 32 | 33 | #* Default symbols to use for graph creation, "braille", "block" or "tty". 34 | #* "braille" offers the highest resolution but might not be included in all fonts. 35 | #* "block" has half the resolution of braille but uses more common characters. 36 | #* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY. 37 | #* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view. 38 | graph_symbol = "braille" 39 | 40 | # Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". 41 | graph_symbol_cpu = "default" 42 | 43 | # Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty". 44 | graph_symbol_gpu = "default" 45 | 46 | # Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". 47 | graph_symbol_mem = "default" 48 | 49 | # Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". 50 | graph_symbol_net = "default" 51 | 52 | # Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". 53 | graph_symbol_proc = "default" 54 | 55 | #* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace. 56 | shown_boxes = "cpu mem net proc" 57 | 58 | #* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs. 59 | update_ms = 2000 60 | 61 | #* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct", 62 | #* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly. 63 | proc_sorting = "user" 64 | 65 | #* Reverse sorting order, True or False. 66 | proc_reversed = false 67 | 68 | #* Show processes as a tree. 69 | proc_tree = false 70 | 71 | #* Use the cpu graph colors in the process list. 72 | proc_colors = true 73 | 74 | #* Use a darkening gradient in the process list. 75 | proc_gradient = true 76 | 77 | #* If process cpu usage should be of the core it's running on or usage of the total available cpu power. 78 | proc_per_core = false 79 | 80 | #* Show process memory as bytes instead of percent. 81 | proc_mem_bytes = true 82 | 83 | #* Show cpu graph for each process. 84 | proc_cpu_graphs = true 85 | 86 | #* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate) 87 | proc_info_smaps = false 88 | 89 | #* Show proc box on left side of screen instead of right. 90 | proc_left = false 91 | 92 | #* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop). 93 | proc_filter_kernel = false 94 | 95 | #* In tree-view, always accumulate child process resources in the parent process. 96 | proc_aggregate = false 97 | 98 | #* Should cpu and memory usage display be preserved for dead processes when paused. 99 | keep_dead_proc_usage = false 100 | 101 | #* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available. 102 | #* Select from a list of detected attributes from the options menu. 103 | cpu_graph_upper = "Auto" 104 | 105 | #* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available. 106 | #* Select from a list of detected attributes from the options menu. 107 | cpu_graph_lower = "Auto" 108 | 109 | #* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off". 110 | show_gpu_info = "Auto" 111 | 112 | #* Toggles if the lower CPU graph should be inverted. 113 | cpu_invert_lower = true 114 | 115 | #* Set to True to completely disable the lower CPU graph. 116 | cpu_single_graph = false 117 | 118 | #* Show cpu box at bottom of screen instead of top. 119 | cpu_bottom = false 120 | 121 | #* Shows the system uptime in the CPU box. 122 | show_uptime = true 123 | 124 | #* Shows the CPU package current power consumption in watts. Requires running `make setcap` or `make setuid` or running with sudo. 125 | show_cpu_watts = true 126 | 127 | #* Show cpu temperature. 128 | check_temp = true 129 | 130 | #* Which sensor to use for cpu temperature, use options menu to select from list of available sensors. 131 | cpu_sensor = "Auto" 132 | 133 | #* Show temperatures for cpu cores also if check_temp is True and sensors has been found. 134 | show_coretemp = true 135 | 136 | #* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core. 137 | #* Use lm-sensors or similar to see which cores are reporting temperatures on your machine. 138 | #* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries. 139 | #* Example: "4:0 5:1 6:3" 140 | cpu_core_map = "" 141 | 142 | #* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine". 143 | temp_scale = "celsius" 144 | 145 | #* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024. 146 | base_10_sizes = false 147 | 148 | #* Show CPU frequency. 149 | show_cpu_freq = true 150 | 151 | #* How to calculate CPU frequency, available values: "first", "range", "lowest", "highest" and "average". 152 | freq_mode = "first" 153 | 154 | #* Draw a clock at top of screen, formatting according to strftime, empty string to disable. 155 | #* Special formatting: /host = hostname | /user = username | /uptime = system uptime 156 | clock_format = "%X" 157 | 158 | #* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort. 159 | background_update = true 160 | 161 | #* Custom cpu model name, empty string to disable. 162 | custom_cpu_name = "" 163 | 164 | #* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ". 165 | #* Only disks matching the filter will be shown. Prepend exclude= to only show disks not matching the filter. Examples: disk_filter="/boot /home/user", disks_filter="exclude=/boot /home/user" 166 | disks_filter = "" 167 | 168 | #* Show graphs instead of meters for memory values. 169 | mem_graphs = true 170 | 171 | #* Show mem box below net box instead of above. 172 | mem_below_net = false 173 | 174 | #* Count ZFS ARC in cached and available memory. 175 | zfs_arc_cached = true 176 | 177 | #* If swap memory should be shown in memory box. 178 | show_swap = true 179 | 180 | #* Show swap as a disk, ignores show_swap value above, inserts itself after first disk. 181 | swap_disk = true 182 | 183 | #* If mem box should be split to also show disks info. 184 | show_disks = true 185 | 186 | #* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar. 187 | only_physical = true 188 | 189 | #* Read disks list from /etc/fstab. This also disables only_physical. 190 | use_fstab = true 191 | 192 | #* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool) 193 | zfs_hide_datasets = false 194 | 195 | #* Set to true to show available disk space for privileged users. 196 | disk_free_priv = false 197 | 198 | #* Toggles if io activity % (disk busy time) should be shown in regular disk usage view. 199 | show_io_stat = true 200 | 201 | #* Toggles io mode for disks, showing big graphs for disk read/write speeds. 202 | io_mode = false 203 | 204 | #* Set to True to show combined read/write io graphs in io mode. 205 | io_graph_combined = false 206 | 207 | #* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ". 208 | #* Example: "/mnt/media:100 /:20 /boot:1". 209 | io_graph_speeds = "" 210 | 211 | #* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False. 212 | net_download = 100 213 | 214 | net_upload = 100 215 | 216 | #* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest. 217 | net_auto = true 218 | 219 | #* Sync the auto scaling for download and upload to whichever currently has the highest scale. 220 | net_sync = true 221 | 222 | #* Starts with the Network Interface specified here. 223 | net_iface = "" 224 | 225 | #* "True" shows bitrates in base 10 (Kbps, Mbps). "False" shows bitrates in binary sizes (Kibps, Mibps, etc.). "Auto" uses base_10_sizes. 226 | base_10_bitrate = "Auto" 227 | 228 | #* Show battery stats in top right if battery is present. 229 | show_battery = true 230 | 231 | #* Which battery to use if multiple are present. "Auto" for auto detection. 232 | selected_battery = "Auto" 233 | 234 | #* Show power stats of battery next to charge indicator. 235 | show_battery_watts = true 236 | 237 | #* Set loglevel for "~/.local/state/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG". 238 | #* The level set includes all lower levels, i.e. "DEBUG" will show all logging info. 239 | log_level = "WARNING" 240 | 241 | #* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards. 242 | nvml_measure_pcie_speeds = true 243 | 244 | #* Measure PCIe throughput on AMD cards, may impact performance on certain cards. 245 | rsmi_measure_pcie_speeds = true 246 | 247 | #* Horizontally mirror the GPU graph. 248 | gpu_mirror_graph = true 249 | 250 | #* Set which GPU vendors to show. Available values are "nvidia amd intel" 251 | shown_gpus = "nvidia amd intel" 252 | 253 | #* Custom gpu0 model name, empty string to disable. 254 | custom_gpu_name0 = "" 255 | 256 | #* Custom gpu1 model name, empty string to disable. 257 | custom_gpu_name1 = "" 258 | 259 | #* Custom gpu2 model name, empty string to disable. 260 | custom_gpu_name2 = "" 261 | 262 | #* Custom gpu3 model name, empty string to disable. 263 | custom_gpu_name3 = "" 264 | 265 | #* Custom gpu4 model name, empty string to disable. 266 | custom_gpu_name4 = "" 267 | 268 | #* Custom gpu5 model name, empty string to disable. 269 | custom_gpu_name5 = "" 270 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotfiles 2 | 3 | This readme along with an install script will help you get everything running 4 | in a few minutes. It contains a bunch of configuration for the [tools I 5 | use](https://nickjanetakis.com/blog/the-tools-i-use). I also have a number of 6 | [blog posts and 7 | videos](https://nickjanetakis.com/blog/tag/dev-environment-tips-tricks-and-tutorials) 8 | related to my dev environment. 9 | 10 | ## 🧬 Who Is This For? 11 | 12 | This project is more than a few config files. **In 1 command and ~5 minutes it 13 | can take a new or existing system and install / configure a number of tools 14 | aimed at developers**. It will prompt or warn you if it's doing a destructive 15 | action like overwriting a config file. You can run the idempotent [install 16 | script](./install) multiple times to stay up to date. 17 | 18 | There's too many things to list here but here's the highlights: 19 | 20 | - Set you up for success with command line tools and workflows 21 | - Tweak out your shell (zsh) 22 | - Set up tmux 23 | - Fully configure Neovim 24 | - Create SSH / GPG keys if they don't already exist 25 | - Install modern CLI tools 26 | - Install programming languages 27 | 28 | **It supports Arch Linux, Debian, Ubuntu and macOS. It also supports WSL 2 for 29 | any supported Linux distro.** 30 | 31 | *If you don't plan to run the install script that's ok, everything is MIT 32 | licensed. The code is here to look at.* 33 | 34 | ## 🧾 Documentation 35 | 36 | - [Themes](#-themes) 37 | - [Quickly Get Set Up](#-quickly-get-set-up) 38 | - [FAQ](#-faq) 39 | - [How to personalize these dotfiles?](#how-to-personalize-these-dotfiles) 40 | - [How to theme custom apps?](#how-to-get-theme-custom-apps) 41 | - [How to add custom themes?](#how-to-add-custom-themes) 42 | - [How to fix Neovim taking a long time to open when inside of WSL?](#how-to-fix-neovim-taking-a-long-time-to-open-when-inside-of-wsl) 43 | - [Where is the original Vim config?](#where-is-the-original-vim-config) 44 | - [About the Author](#-about-the-author) 45 | 46 | ## 🎨 Themes 47 | 48 | Since these dotfiles are constantly evolving and I tend to reference them in 49 | videos, blog posts and other places I thought it would be a good idea to 50 | include screenshots in 1 spot. 51 | 52 | ### Tokyonight Moon 53 | 54 | ![Tokyonight Moon](https://nickjanetakis.com/assets/screenshots/dotfiles-tokyonight-moon-7320a3fb8a76462e64d13bc125a2f284.jpg) 55 | 56 | ### Gruvbox Dark (Medium) 57 | 58 | ![Gruvbox Dark Medium](https://nickjanetakis.com/assets/screenshots/dotfiles-gruvbox-dark-medium-cfde05b1e4ccfa0ca9ebf0c089d99a28.jpg) 59 | 60 | I prefer using themes that have good contrast ratios and are clear to see in 61 | video recordings. These dotfiles currently support easily switching between 62 | both themes but you can use any theme you'd like. 63 | 64 | If you want to see icons you'll need a "nerd font". There's hundreds of them on 65 | with previews. I personally use 66 | Inconsolata NF which these dotfiles install for you. 67 | 68 | ### Setting a theme 69 | 70 | These dotfiles include a `dot-theme-set` script that you can run from your 71 | terminal to set your theme to any of the themes listed above. 72 | 73 | You can look in the [themes/](./themes/) directory to see which apps are themed. 74 | 75 | If you don't like the included themes that's no problem. You can [add custom 76 | themes](#how-to-add-custom-themes). 77 | 78 | After installing these dotfiles you can switch themes with: 79 | 80 | ```sh 81 | # Get a full list of themes by running: dot-theme-set --list 82 | # 83 | # Optionally you can skip adding a theme name and a random theme will be chosen. 84 | dot-theme-set THEME_NAME 85 | ``` 86 | 87 | When switching themes most apps will update automatically, but if you have a 88 | bunch of shells already open you can run the `SZ` ([source 89 | zsh](https://nickjanetakis.com/blog/running-commands-in-all-tmux-sessions-windows-and-panes)) 90 | alias to source new theme related configs. 91 | 92 | *Not all terminals are supported, if yours didn't change then check [theming 93 | custom apps](#how-to-theme-custom-apps).* 94 | 95 | ## ✨ Quickly Get Set Up 96 | 97 | There's an `./install` script you can run to automate installing everything. 98 | That includes installing system packages such as zsh, tmux, Neovim, etc. and 99 | configuring a number of tools in your home directory. 100 | 101 | It even handles cloning down this repo. You'll get a chance to pick the clone 102 | location when running the script as well as view and / or change any system 103 | packages that get installed before your system is modified. 104 | 105 | ### 🌱 On a fresh system? 106 | 107 | We're in a catch-22 where this install script will set everything up for you 108 | but to download and run the script to completion a few things need to exist on 109 | your system first. 110 | 111 | **It comes down to needing these packages, you can skip this step if you have 112 | them**: 113 | 114 | - `curl` to download the install script 115 | - `bash 4+` since the install script uses modern Bash features 116 | - This is only related to macOS, all supported Linux distros are good to go out of the box 117 | 118 | Here's 1 liners you can copy / paste once to meet the above requirements on all 119 | supported platforms: 120 | 121 | #### Arch Linux 122 | 123 | ```sh 124 | # You can run this as root. 125 | pacman -Syu --noconfirm --needed curl 126 | ``` 127 | 128 | #### Debian / Ubuntu 129 | 130 | ```sh 131 | # You can run this as root. 132 | apt-get update && apt-get install -y curl 133 | ``` 134 | 135 | #### macOS 136 | 137 | If you run `bash --version` and it says you're using Bash 3.X please follow 138 | the instructions below: 139 | 140 | ```sh 141 | # Curl is installed by default but bash needs to be upgraded, we can do that 142 | # by brew installing bash. Once this command completes you can run the install 143 | # script in the same terminal where you ran this command. Before running the 144 | # install script `bash --version` should return a version > 3.X. 145 | 146 | # OPTION 1: Using Apple silicon? 147 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \ 148 | && eval "$(/opt/homebrew/bin/brew shellenv)" \ 149 | && brew install bash \ 150 | && bash 151 | 152 | # OPTION 2: Using an Intel CPU? 153 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \ 154 | && eval "$(/usr/local/bin/brew shellenv)" \ 155 | && brew install bash \ 156 | && bash 157 | 158 | # The colors will look bad with the default macOS Terminal app. These dotfiles install: https://ghostty.org/ 159 | ``` 160 | 161 | ### ⚡️ Install script 162 | 163 | **You can download and run the install script with this 1 liner:** 164 | 165 | ```sh 166 | BOOTSTRAP=1 bash <(curl -sS https://raw.githubusercontent.com/nickjj/dotfiles/master/install) 167 | ``` 168 | 169 | *If you're not comfortable blindly running a script on the internet, that's no 170 | problem. You can view the [install script](./install) to see exactly what it 171 | does. The bottom of the file is a good place to start. Sudo is only used to 172 | install system packages. Alternatively you can look around this repo and 173 | reference the config files directly without using any script.* 174 | 175 | *Please understand if you run this script on your existing system and hit yes 176 | to some of the prompts your config files will get overwritten. Always have good 177 | backups!* 178 | 179 | **You can also run the script without installing system packages:** 180 | 181 | ```sh 182 | BOOTSTRAP=1 bash <(curl -sS https://raw.githubusercontent.com/nickjj/dotfiles/master/install) --skip-system-packages 183 | ``` 184 | 185 | The above can be useful if you're using an unsupported distro of Linux in which 186 | case you'll need to install the [dependent system packages](./install) on your 187 | own beforehand. Besides that, everything else is supported since it's only 188 | dealing with files in your home directory. 189 | 190 | This set up targets zsh 5.0+, tmux 3.1+ and Neovim v0.11+. As long as you can 191 | meet those requirements you're good to go. The install script will take care 192 | of installing these for you unless you've skipped system packages. 193 | 194 | 🐳 **Try it in Docker without modifying your system:** 195 | 196 | ```sh 197 | # Start a Debian container, we're passing IN_CONTAINER to be explicit we're in Docker. 198 | docker container run --rm -it -e "IN_CONTAINER=1" -v "${PWD}:/app" -w /app debian:stable-slim bash 199 | 200 | # Copy / paste all 3 lines into the container's prompt and run it. 201 | # 202 | # Since we can't open a new terminal in a container we'll need to manually 203 | # launch zsh and source a few files. That's what the last line is doing. 204 | apt-get update && apt-get install -y curl \ 205 | && bash <(curl -sS https://raw.githubusercontent.com/nickjj/dotfiles/master/install) \ 206 | && zsh -c ". ~/.config/zsh/.zprofile && . ~/.config/zsh/.zshrc; zsh -i" 207 | ``` 208 | 209 | *Keep in mind with the Docker set up, unless your terminal is already 210 | configured to use Tokyonight Moon then the colors may look off. That's because 211 | your local terminal's config will not get automatically updated.* 212 | 213 | **🚀 Keeping things up to date and tinkering** 214 | 215 | Once you've installed these dotfiles you can run `cd "${DOTFILES_PATH}"` to 216 | manage them. 217 | 218 | Here's a few handy commands, you can run `./install --help` to see all of them: 219 | 220 | - `./install` 221 | - Run the install script based on the local copy of your dotfiles 222 | - Keeps your system up to date or apply local changes 223 | - `./install --skip-system-packages` 224 | - Run the install script like above but skip installing or updating packages 225 | - Helps regenerate symlinks, configs and everything else without modifying packages 226 | - `./install --pull` 227 | - Pulls in the latest remote commits but doesn't run the install script 228 | - Lets you review any changes locally before the install script runs 229 | - `./install --update` 230 | - Pulls in the latest remote commits and runs the install script 231 | - Shortcut to pull and run the install script together 232 | - `./install --diff-config` 233 | - Compare your local `install-config` to the local `install-config.example` 234 | - Helps keep your git ignored `install-config` in sync with new options 235 | - `./install --diff` 236 | - Compare what you have locally vs the latest remote commits 237 | - See what will change if you `--update` without modifying your git tree 238 | - `./install --new-commits` 239 | - Show new remote commits that do not exist locally 240 | - Present a quick list of what's available to pull locally 241 | - `./install --changelog` 242 | - Show all remote commits 243 | - Present a quick list of all commits to see what has changed 244 | - `./install --local-files` 245 | - Show all local git ignored files such as configs, history and scripts 246 | - Useful to see everything not committed and for optionally backing up those files 247 | - Example: `./install --local-files | xargs zip dotfiles-personal.zip` 248 | 249 | *There's also a `LOCAL=1` environment variable you can set when bootstrapping 250 | or running the other install commands. This is handy for doing local tests 251 | in containers without needing to commit, push and pull changes.* 252 | 253 | ### 🛠 Make it your own 254 | 255 | If you just ran the install script and haven't done so already please close 256 | your terminal and open a new one. 257 | 258 | There's a few ways to customize these dotfiles ranging from forking this repo 259 | to customizing [install-config](./install-config.example) which is git ignored. 260 | The second option lets you adjust which packages and programming languages get 261 | installed as well as configure a number of other things. 262 | 263 | Before you start customizing other files, please take a look at the 264 | [personalization question in the FAQ](#how-to-personalize-these-dotfiles). 265 | 266 | ### 🪟 Extra WSL 2 steps 267 | 268 | In addition to the Linux side of things, there's a few config files that I have 269 | in various directories of this dotfiles repo. These have long Windows paths and 270 | are in the `mnt/c/` directory. 271 | 272 | It would be expected that you copy those over to your system while replacing 273 | "Nick" with your Windows user name if you want to use those things. The 274 | Microsoft Terminal config will automatically be copied over to your user's 275 | path. 276 | 277 | It's expected you're running WSL 2 with WSLg support to get clipboard sharing 278 | to work between Windows and WSL 2. You can run `wsl.exe --version` from WSL 2 279 | to check if WSLg is listed. Chances are you have it since it has been supported 280 | since 2022! All of this should "just work". If clipboard sharing isn't working, 281 | check your `.wslconfig` file in your Windows user's directory and make sure 282 | `guiApplications=false` isn't set. 283 | 284 | *If you see `^M` characters when pasting into Neovim, that's a Windows line 285 | ending. That's because WSLg's clipboard feature doesn't seem to handle this 286 | automatically. If you paste with `CTRL+SHIFT+v` instead of `p` it'll be ok. I 287 | guess the Microsoft Terminal does extra processing to fix it for you.* 288 | 289 | Pay very close attention to the `mnt/c/Users/Nick/.wslconfig` file because it 290 | has values in there that you will very likely want to change before using it. 291 | [This commit 292 | message](https://github.com/nickjj/dotfiles/commit/d0f1fc2622204b809cf7fcbb1a82d45b451064c4) 293 | goes into the details. 294 | 295 | Also, you should reboot or from PowerShell run `wsl --shutdown` and then 296 | re-open your WSL instance to activate your `/etc/wsl.conf` file (the install 297 | script created this). 298 | 299 | You may have noticed I don't enable systemd within WSL 2. That is on purpose. 300 | I've found it delays opening WSL 2 by ~10-15 seconds and also any systemd 301 | services were delayed from starting by ~2 minutes. 302 | 303 | ## 🔍 FAQ 304 | 305 | ### How to personalize these dotfiles? 306 | 307 | The [install-config](./install-config.example) lets you customize a few things 308 | but chances are you'll want to personalize more than what's there, such as 309 | various Neovim settings. Since this is a git repo you can always do a `git 310 | pull` to get the most up to date copy of these dotfiles, but then you may find 311 | yourself clobbering over your own personal changes. 312 | 313 | Since we're using git here, we have a few reasonable options. 314 | 315 | For example, from within this dotfiles git repo you can run `git checkout -b 316 | personalized` and now you are free to make whatever changes that you want on 317 | your custom branch. When it comes time to pull down future updates you can run 318 | a `git pull origin master` and then `git rebase master` to integrate any 319 | updates into your branch. 320 | 321 | Another option is to fork this repo and use that, then periodically pull and 322 | merge updates. It's really up to you. By default these dotfiles will add an 323 | `upstream` git remote that points to this repo. 324 | 325 | ### How to theme custom apps? 326 | 327 | You'd add its theme file to each theme in [themes/](./themes) and update the 328 | [install](./install) script's `set_theme` function to symlink the config. If 329 | your app has no dedicated config file, you can copy what I did for the 330 | Microsoft Terminal in `set_theme`. 331 | 332 | Happy to assist in your issue / PR to answer questions if you want to 333 | contribute your change. 334 | 335 | ### How to add custom themes? 336 | 337 | 1. Locate the [themes/](./themes) directory in this repo 338 | 2. Copy one of the existing themes' directory 339 | 3. Rename your directory, this will be your theme's name 340 | 4. Adjust all of the colors as you see fit 341 | 342 | Switch to it by running `dot-theme-set NEW_THEME_NAME` and use the name you 343 | picked in step 3. 344 | 345 | If you added a theme with good contrast ratios please open a pull request to 346 | get it added to this project. 347 | 348 | ### Where is the original Vim config? 349 | 350 | I've made dozens of [blog posts and 351 | videos](https://nickjanetakis.com/blog/tag/vim-tips-tricks-and-tutorials) about 352 | Vim. Sometimes I linked directly to a commit so there's a permalink to it but 353 | other times I did not. 354 | 355 | Before switching to Neovim I made a `vim` git tag. You can check out the state 356 | of the repo for that tag by [going 357 | here](https://github.com/nickjj/dotfiles/tree/vim). You'll see `.vimrc` in the 358 | root directory. If you cloned these dotfiles locally you can `git checkout 359 | vim`. Keep in mind that's frozen to that point in time. Future updates 360 | unrelated to Vim will not be included in that tag. 361 | 362 | ## 👀 About the Author 363 | 364 | I'm a self taught developer and have been freelancing for the last ~20 years. 365 | You can read about everything I've learned along the way on my site at 366 | [https://nickjanetakis.com](https://nickjanetakis.com/). There's hundreds of 367 | [blog posts](https://nickjanetakis.com/blog/) and a couple of [video 368 | courses](https://nickjanetakis.com/courses/) on web development and deployment 369 | topics. I also have a [podcast](https://runninginproduction.com) where I talk 370 | to folks about running web apps in production. 371 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/data/github-markdown.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Taken from https://github.com/sindresorhus/github-markdown-css on 2025-03-10 3 | * 4 | * But I manually edited .markdown-body to add these so it's a closer match: 5 | * padding: 16px; 6 | * max-width: 820px; 7 | */ 8 | 9 | .markdown-body { 10 | padding: 16px; 11 | max-width: 820px; 12 | --base-size-4: 0.25rem; 13 | --base-size-8: 0.5rem; 14 | --base-size-16: 1rem; 15 | --base-size-24: 1.5rem; 16 | --base-size-40: 2.5rem; 17 | --base-text-weight-normal: 400; 18 | --base-text-weight-medium: 500; 19 | --base-text-weight-semibold: 600; 20 | --fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; 21 | --fgColor-accent: Highlight; 22 | } 23 | @media (prefers-color-scheme: dark) { 24 | .markdown-body, [data-theme="dark"] { 25 | /* dark */ 26 | color-scheme: dark; 27 | --focus-outlineColor: #1f6feb; 28 | --fgColor-default: #f0f6fc; 29 | --fgColor-muted: #9198a1; 30 | --fgColor-accent: #4493f8; 31 | --fgColor-success: #3fb950; 32 | --fgColor-attention: #d29922; 33 | --fgColor-danger: #f85149; 34 | --fgColor-done: #ab7df8; 35 | --bgColor-default: #0d1117; 36 | --bgColor-muted: #151b23; 37 | --bgColor-neutral-muted: #656c7633; 38 | --bgColor-attention-muted: #bb800926; 39 | --borderColor-default: #3d444d; 40 | --borderColor-muted: #3d444db3; 41 | --borderColor-neutral-muted: #3d444db3; 42 | --borderColor-accent-emphasis: #1f6feb; 43 | --borderColor-success-emphasis: #238636; 44 | --borderColor-attention-emphasis: #9e6a03; 45 | --borderColor-danger-emphasis: #da3633; 46 | --borderColor-done-emphasis: #8957e5; 47 | --color-prettylights-syntax-comment: #9198a1; 48 | --color-prettylights-syntax-constant: #79c0ff; 49 | --color-prettylights-syntax-constant-other-reference-link: #a5d6ff; 50 | --color-prettylights-syntax-entity: #d2a8ff; 51 | --color-prettylights-syntax-storage-modifier-import: #f0f6fc; 52 | --color-prettylights-syntax-entity-tag: #7ee787; 53 | --color-prettylights-syntax-keyword: #ff7b72; 54 | --color-prettylights-syntax-string: #a5d6ff; 55 | --color-prettylights-syntax-variable: #ffa657; 56 | --color-prettylights-syntax-brackethighlighter-unmatched: #f85149; 57 | --color-prettylights-syntax-brackethighlighter-angle: #9198a1; 58 | --color-prettylights-syntax-invalid-illegal-text: #f0f6fc; 59 | --color-prettylights-syntax-invalid-illegal-bg: #8e1519; 60 | --color-prettylights-syntax-carriage-return-text: #f0f6fc; 61 | --color-prettylights-syntax-carriage-return-bg: #b62324; 62 | --color-prettylights-syntax-string-regexp: #7ee787; 63 | --color-prettylights-syntax-markup-list: #f2cc60; 64 | --color-prettylights-syntax-markup-heading: #1f6feb; 65 | --color-prettylights-syntax-markup-italic: #f0f6fc; 66 | --color-prettylights-syntax-markup-bold: #f0f6fc; 67 | --color-prettylights-syntax-markup-deleted-text: #ffdcd7; 68 | --color-prettylights-syntax-markup-deleted-bg: #67060c; 69 | --color-prettylights-syntax-markup-inserted-text: #aff5b4; 70 | --color-prettylights-syntax-markup-inserted-bg: #033a16; 71 | --color-prettylights-syntax-markup-changed-text: #ffdfb6; 72 | --color-prettylights-syntax-markup-changed-bg: #5a1e02; 73 | --color-prettylights-syntax-markup-ignored-text: #f0f6fc; 74 | --color-prettylights-syntax-markup-ignored-bg: #1158c7; 75 | --color-prettylights-syntax-meta-diff-range: #d2a8ff; 76 | --color-prettylights-syntax-sublimelinter-gutter-mark: #3d444d; 77 | } 78 | } 79 | @media (prefers-color-scheme: light) { 80 | .markdown-body, [data-theme="light"] { 81 | /* light */ 82 | color-scheme: light; 83 | --focus-outlineColor: #0969da; 84 | --fgColor-default: #1f2328; 85 | --fgColor-muted: #59636e; 86 | --fgColor-accent: #0969da; 87 | --fgColor-success: #1a7f37; 88 | --fgColor-attention: #9a6700; 89 | --fgColor-danger: #d1242f; 90 | --fgColor-done: #8250df; 91 | --bgColor-default: #ffffff; 92 | --bgColor-muted: #f6f8fa; 93 | --bgColor-neutral-muted: #818b981f; 94 | --bgColor-attention-muted: #fff8c5; 95 | --borderColor-default: #d1d9e0; 96 | --borderColor-muted: #d1d9e0b3; 97 | --borderColor-neutral-muted: #d1d9e0b3; 98 | --borderColor-accent-emphasis: #0969da; 99 | --borderColor-success-emphasis: #1a7f37; 100 | --borderColor-attention-emphasis: #9a6700; 101 | --borderColor-danger-emphasis: #cf222e; 102 | --borderColor-done-emphasis: #8250df; 103 | --color-prettylights-syntax-comment: #59636e; 104 | --color-prettylights-syntax-constant: #0550ae; 105 | --color-prettylights-syntax-constant-other-reference-link: #0a3069; 106 | --color-prettylights-syntax-entity: #6639ba; 107 | --color-prettylights-syntax-storage-modifier-import: #1f2328; 108 | --color-prettylights-syntax-entity-tag: #0550ae; 109 | --color-prettylights-syntax-keyword: #cf222e; 110 | --color-prettylights-syntax-string: #0a3069; 111 | --color-prettylights-syntax-variable: #953800; 112 | --color-prettylights-syntax-brackethighlighter-unmatched: #82071e; 113 | --color-prettylights-syntax-brackethighlighter-angle: #59636e; 114 | --color-prettylights-syntax-invalid-illegal-text: #f6f8fa; 115 | --color-prettylights-syntax-invalid-illegal-bg: #82071e; 116 | --color-prettylights-syntax-carriage-return-text: #f6f8fa; 117 | --color-prettylights-syntax-carriage-return-bg: #cf222e; 118 | --color-prettylights-syntax-string-regexp: #116329; 119 | --color-prettylights-syntax-markup-list: #3b2300; 120 | --color-prettylights-syntax-markup-heading: #0550ae; 121 | --color-prettylights-syntax-markup-italic: #1f2328; 122 | --color-prettylights-syntax-markup-bold: #1f2328; 123 | --color-prettylights-syntax-markup-deleted-text: #82071e; 124 | --color-prettylights-syntax-markup-deleted-bg: #ffebe9; 125 | --color-prettylights-syntax-markup-inserted-text: #116329; 126 | --color-prettylights-syntax-markup-inserted-bg: #dafbe1; 127 | --color-prettylights-syntax-markup-changed-text: #953800; 128 | --color-prettylights-syntax-markup-changed-bg: #ffd8b5; 129 | --color-prettylights-syntax-markup-ignored-text: #d1d9e0; 130 | --color-prettylights-syntax-markup-ignored-bg: #0550ae; 131 | --color-prettylights-syntax-meta-diff-range: #8250df; 132 | --color-prettylights-syntax-sublimelinter-gutter-mark: #818b98; 133 | } 134 | } 135 | 136 | .markdown-body { 137 | -ms-text-size-adjust: 100%; 138 | -webkit-text-size-adjust: 100%; 139 | margin: 0; 140 | color: var(--fgColor-default); 141 | background-color: var(--bgColor-default); 142 | font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; 143 | font-size: 16px; 144 | line-height: 1.5; 145 | word-wrap: break-word; 146 | } 147 | 148 | .markdown-body .octicon { 149 | display: inline-block; 150 | fill: currentColor; 151 | vertical-align: text-bottom; 152 | } 153 | 154 | .markdown-body h1:hover .anchor .octicon-link:before, 155 | .markdown-body h2:hover .anchor .octicon-link:before, 156 | .markdown-body h3:hover .anchor .octicon-link:before, 157 | .markdown-body h4:hover .anchor .octicon-link:before, 158 | .markdown-body h5:hover .anchor .octicon-link:before, 159 | .markdown-body h6:hover .anchor .octicon-link:before { 160 | width: 16px; 161 | height: 16px; 162 | content: ' '; 163 | display: inline-block; 164 | background-color: currentColor; 165 | -webkit-mask-image: url("data:image/svg+xml,"); 166 | mask-image: url("data:image/svg+xml,"); 167 | } 168 | 169 | .markdown-body details, 170 | .markdown-body figcaption, 171 | .markdown-body figure { 172 | display: block; 173 | } 174 | 175 | .markdown-body summary { 176 | display: list-item; 177 | } 178 | 179 | .markdown-body [hidden] { 180 | display: none !important; 181 | } 182 | 183 | .markdown-body a { 184 | background-color: transparent; 185 | color: var(--fgColor-accent); 186 | text-decoration: none; 187 | } 188 | 189 | .markdown-body abbr[title] { 190 | border-bottom: none; 191 | -webkit-text-decoration: underline dotted; 192 | text-decoration: underline dotted; 193 | } 194 | 195 | .markdown-body b, 196 | .markdown-body strong { 197 | font-weight: var(--base-text-weight-semibold, 600); 198 | } 199 | 200 | .markdown-body dfn { 201 | font-style: italic; 202 | } 203 | 204 | .markdown-body h1 { 205 | margin: .67em 0; 206 | font-weight: var(--base-text-weight-semibold, 600); 207 | padding-bottom: .3em; 208 | font-size: 2em; 209 | border-bottom: 1px solid var(--borderColor-muted); 210 | } 211 | 212 | .markdown-body mark { 213 | background-color: var(--bgColor-attention-muted); 214 | color: var(--fgColor-default); 215 | } 216 | 217 | .markdown-body small { 218 | font-size: 90%; 219 | } 220 | 221 | .markdown-body sub, 222 | .markdown-body sup { 223 | font-size: 75%; 224 | line-height: 0; 225 | position: relative; 226 | vertical-align: baseline; 227 | } 228 | 229 | .markdown-body sub { 230 | bottom: -0.25em; 231 | } 232 | 233 | .markdown-body sup { 234 | top: -0.5em; 235 | } 236 | 237 | .markdown-body img { 238 | border-style: none; 239 | max-width: 100%; 240 | box-sizing: content-box; 241 | } 242 | 243 | .markdown-body code, 244 | .markdown-body kbd, 245 | .markdown-body pre, 246 | .markdown-body samp { 247 | font-family: monospace; 248 | font-size: 1em; 249 | } 250 | 251 | .markdown-body figure { 252 | margin: 1em var(--base-size-40); 253 | } 254 | 255 | .markdown-body hr { 256 | box-sizing: content-box; 257 | overflow: hidden; 258 | background: transparent; 259 | border-bottom: 1px solid var(--borderColor-muted); 260 | height: .25em; 261 | padding: 0; 262 | margin: var(--base-size-24) 0; 263 | background-color: var(--borderColor-default); 264 | border: 0; 265 | } 266 | 267 | .markdown-body input { 268 | font: inherit; 269 | margin: 0; 270 | overflow: visible; 271 | font-family: inherit; 272 | font-size: inherit; 273 | line-height: inherit; 274 | } 275 | 276 | .markdown-body [type=button], 277 | .markdown-body [type=reset], 278 | .markdown-body [type=submit] { 279 | -webkit-appearance: button; 280 | appearance: button; 281 | } 282 | 283 | .markdown-body [type=checkbox], 284 | .markdown-body [type=radio] { 285 | box-sizing: border-box; 286 | padding: 0; 287 | } 288 | 289 | .markdown-body [type=number]::-webkit-inner-spin-button, 290 | .markdown-body [type=number]::-webkit-outer-spin-button { 291 | height: auto; 292 | } 293 | 294 | .markdown-body [type=search]::-webkit-search-cancel-button, 295 | .markdown-body [type=search]::-webkit-search-decoration { 296 | -webkit-appearance: none; 297 | appearance: none; 298 | } 299 | 300 | .markdown-body ::-webkit-input-placeholder { 301 | color: inherit; 302 | opacity: .54; 303 | } 304 | 305 | .markdown-body ::-webkit-file-upload-button { 306 | -webkit-appearance: button; 307 | appearance: button; 308 | font: inherit; 309 | } 310 | 311 | .markdown-body a:hover { 312 | text-decoration: underline; 313 | } 314 | 315 | .markdown-body ::placeholder { 316 | color: var(--fgColor-muted); 317 | opacity: 1; 318 | } 319 | 320 | .markdown-body hr::before { 321 | display: table; 322 | content: ""; 323 | } 324 | 325 | .markdown-body hr::after { 326 | display: table; 327 | clear: both; 328 | content: ""; 329 | } 330 | 331 | .markdown-body table { 332 | border-spacing: 0; 333 | border-collapse: collapse; 334 | display: block; 335 | width: max-content; 336 | max-width: 100%; 337 | overflow: auto; 338 | font-variant: tabular-nums; 339 | } 340 | 341 | .markdown-body td, 342 | .markdown-body th { 343 | padding: 0; 344 | } 345 | 346 | .markdown-body details summary { 347 | cursor: pointer; 348 | } 349 | 350 | .markdown-body a:focus, 351 | .markdown-body [role=button]:focus, 352 | .markdown-body input[type=radio]:focus, 353 | .markdown-body input[type=checkbox]:focus { 354 | outline: 2px solid var(--focus-outlineColor); 355 | outline-offset: -2px; 356 | box-shadow: none; 357 | } 358 | 359 | .markdown-body a:focus:not(:focus-visible), 360 | .markdown-body [role=button]:focus:not(:focus-visible), 361 | .markdown-body input[type=radio]:focus:not(:focus-visible), 362 | .markdown-body input[type=checkbox]:focus:not(:focus-visible) { 363 | outline: solid 1px transparent; 364 | } 365 | 366 | .markdown-body a:focus-visible, 367 | .markdown-body [role=button]:focus-visible, 368 | .markdown-body input[type=radio]:focus-visible, 369 | .markdown-body input[type=checkbox]:focus-visible { 370 | outline: 2px solid var(--focus-outlineColor); 371 | outline-offset: -2px; 372 | box-shadow: none; 373 | } 374 | 375 | .markdown-body a:not([class]):focus, 376 | .markdown-body a:not([class]):focus-visible, 377 | .markdown-body input[type=radio]:focus, 378 | .markdown-body input[type=radio]:focus-visible, 379 | .markdown-body input[type=checkbox]:focus, 380 | .markdown-body input[type=checkbox]:focus-visible { 381 | outline-offset: 0; 382 | } 383 | 384 | .markdown-body kbd { 385 | display: inline-block; 386 | padding: var(--base-size-4); 387 | font: 11px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); 388 | line-height: 10px; 389 | color: var(--fgColor-default); 390 | vertical-align: middle; 391 | background-color: var(--bgColor-muted); 392 | border: solid 1px var(--borderColor-neutral-muted); 393 | border-bottom-color: var(--borderColor-neutral-muted); 394 | border-radius: 6px; 395 | box-shadow: inset 0 -1px 0 var(--borderColor-neutral-muted); 396 | } 397 | 398 | .markdown-body h1, 399 | .markdown-body h2, 400 | .markdown-body h3, 401 | .markdown-body h4, 402 | .markdown-body h5, 403 | .markdown-body h6 { 404 | margin-top: var(--base-size-24); 405 | margin-bottom: var(--base-size-16); 406 | font-weight: var(--base-text-weight-semibold, 600); 407 | line-height: 1.25; 408 | } 409 | 410 | .markdown-body h2 { 411 | font-weight: var(--base-text-weight-semibold, 600); 412 | padding-bottom: .3em; 413 | font-size: 1.5em; 414 | border-bottom: 1px solid var(--borderColor-muted); 415 | } 416 | 417 | .markdown-body h3 { 418 | font-weight: var(--base-text-weight-semibold, 600); 419 | font-size: 1.25em; 420 | } 421 | 422 | .markdown-body h4 { 423 | font-weight: var(--base-text-weight-semibold, 600); 424 | font-size: 1em; 425 | } 426 | 427 | .markdown-body h5 { 428 | font-weight: var(--base-text-weight-semibold, 600); 429 | font-size: .875em; 430 | } 431 | 432 | .markdown-body h6 { 433 | font-weight: var(--base-text-weight-semibold, 600); 434 | font-size: .85em; 435 | color: var(--fgColor-muted); 436 | } 437 | 438 | .markdown-body p { 439 | margin-top: 0; 440 | margin-bottom: 10px; 441 | } 442 | 443 | .markdown-body blockquote { 444 | margin: 0; 445 | padding: 0 1em; 446 | color: var(--fgColor-muted); 447 | border-left: .25em solid var(--borderColor-default); 448 | } 449 | 450 | .markdown-body ul, 451 | .markdown-body ol { 452 | margin-top: 0; 453 | margin-bottom: 0; 454 | padding-left: 2em; 455 | } 456 | 457 | .markdown-body ol ol, 458 | .markdown-body ul ol { 459 | list-style-type: lower-roman; 460 | } 461 | 462 | .markdown-body ul ul ol, 463 | .markdown-body ul ol ol, 464 | .markdown-body ol ul ol, 465 | .markdown-body ol ol ol { 466 | list-style-type: lower-alpha; 467 | } 468 | 469 | .markdown-body dd { 470 | margin-left: 0; 471 | } 472 | 473 | .markdown-body tt, 474 | .markdown-body code, 475 | .markdown-body samp { 476 | font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); 477 | font-size: 12px; 478 | } 479 | 480 | .markdown-body pre { 481 | margin-top: 0; 482 | margin-bottom: 0; 483 | font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); 484 | font-size: 12px; 485 | word-wrap: normal; 486 | } 487 | 488 | .markdown-body .octicon { 489 | display: inline-block; 490 | overflow: visible !important; 491 | vertical-align: text-bottom; 492 | fill: currentColor; 493 | } 494 | 495 | .markdown-body input::-webkit-outer-spin-button, 496 | .markdown-body input::-webkit-inner-spin-button { 497 | margin: 0; 498 | appearance: none; 499 | } 500 | 501 | .markdown-body .mr-2 { 502 | margin-right: var(--base-size-8, 8px) !important; 503 | } 504 | 505 | .markdown-body::before { 506 | display: table; 507 | content: ""; 508 | } 509 | 510 | .markdown-body::after { 511 | display: table; 512 | clear: both; 513 | content: ""; 514 | } 515 | 516 | .markdown-body>*:first-child { 517 | margin-top: 0 !important; 518 | } 519 | 520 | .markdown-body>*:last-child { 521 | margin-bottom: 0 !important; 522 | } 523 | 524 | .markdown-body a:not([href]) { 525 | color: inherit; 526 | text-decoration: none; 527 | } 528 | 529 | .markdown-body .absent { 530 | color: var(--fgColor-danger); 531 | } 532 | 533 | .markdown-body .anchor { 534 | float: left; 535 | padding-right: var(--base-size-4); 536 | margin-left: -20px; 537 | line-height: 1; 538 | } 539 | 540 | .markdown-body .anchor:focus { 541 | outline: none; 542 | } 543 | 544 | .markdown-body p, 545 | .markdown-body blockquote, 546 | .markdown-body ul, 547 | .markdown-body ol, 548 | .markdown-body dl, 549 | .markdown-body table, 550 | .markdown-body pre, 551 | .markdown-body details { 552 | margin-top: 0; 553 | margin-bottom: var(--base-size-16); 554 | } 555 | 556 | .markdown-body blockquote>:first-child { 557 | margin-top: 0; 558 | } 559 | 560 | .markdown-body blockquote>:last-child { 561 | margin-bottom: 0; 562 | } 563 | 564 | .markdown-body h1 .octicon-link, 565 | .markdown-body h2 .octicon-link, 566 | .markdown-body h3 .octicon-link, 567 | .markdown-body h4 .octicon-link, 568 | .markdown-body h5 .octicon-link, 569 | .markdown-body h6 .octicon-link { 570 | color: var(--fgColor-default); 571 | vertical-align: middle; 572 | visibility: hidden; 573 | } 574 | 575 | .markdown-body h1:hover .anchor, 576 | .markdown-body h2:hover .anchor, 577 | .markdown-body h3:hover .anchor, 578 | .markdown-body h4:hover .anchor, 579 | .markdown-body h5:hover .anchor, 580 | .markdown-body h6:hover .anchor { 581 | text-decoration: none; 582 | } 583 | 584 | .markdown-body h1:hover .anchor .octicon-link, 585 | .markdown-body h2:hover .anchor .octicon-link, 586 | .markdown-body h3:hover .anchor .octicon-link, 587 | .markdown-body h4:hover .anchor .octicon-link, 588 | .markdown-body h5:hover .anchor .octicon-link, 589 | .markdown-body h6:hover .anchor .octicon-link { 590 | visibility: visible; 591 | } 592 | 593 | .markdown-body h1 tt, 594 | .markdown-body h1 code, 595 | .markdown-body h2 tt, 596 | .markdown-body h2 code, 597 | .markdown-body h3 tt, 598 | .markdown-body h3 code, 599 | .markdown-body h4 tt, 600 | .markdown-body h4 code, 601 | .markdown-body h5 tt, 602 | .markdown-body h5 code, 603 | .markdown-body h6 tt, 604 | .markdown-body h6 code { 605 | padding: 0 .2em; 606 | font-size: inherit; 607 | } 608 | 609 | .markdown-body summary h1, 610 | .markdown-body summary h2, 611 | .markdown-body summary h3, 612 | .markdown-body summary h4, 613 | .markdown-body summary h5, 614 | .markdown-body summary h6 { 615 | display: inline-block; 616 | } 617 | 618 | .markdown-body summary h1 .anchor, 619 | .markdown-body summary h2 .anchor, 620 | .markdown-body summary h3 .anchor, 621 | .markdown-body summary h4 .anchor, 622 | .markdown-body summary h5 .anchor, 623 | .markdown-body summary h6 .anchor { 624 | margin-left: -40px; 625 | } 626 | 627 | .markdown-body summary h1, 628 | .markdown-body summary h2 { 629 | padding-bottom: 0; 630 | border-bottom: 0; 631 | } 632 | 633 | .markdown-body ul.no-list, 634 | .markdown-body ol.no-list { 635 | padding: 0; 636 | list-style-type: none; 637 | } 638 | 639 | .markdown-body ol[type="a s"] { 640 | list-style-type: lower-alpha; 641 | } 642 | 643 | .markdown-body ol[type="A s"] { 644 | list-style-type: upper-alpha; 645 | } 646 | 647 | .markdown-body ol[type="i s"] { 648 | list-style-type: lower-roman; 649 | } 650 | 651 | .markdown-body ol[type="I s"] { 652 | list-style-type: upper-roman; 653 | } 654 | 655 | .markdown-body ol[type="1"] { 656 | list-style-type: decimal; 657 | } 658 | 659 | .markdown-body div>ol:not([type]) { 660 | list-style-type: decimal; 661 | } 662 | 663 | .markdown-body ul ul, 664 | .markdown-body ul ol, 665 | .markdown-body ol ol, 666 | .markdown-body ol ul { 667 | margin-top: 0; 668 | margin-bottom: 0; 669 | } 670 | 671 | .markdown-body li>p { 672 | margin-top: var(--base-size-16); 673 | } 674 | 675 | .markdown-body li+li { 676 | margin-top: .25em; 677 | } 678 | 679 | .markdown-body dl { 680 | padding: 0; 681 | } 682 | 683 | .markdown-body dl dt { 684 | padding: 0; 685 | margin-top: var(--base-size-16); 686 | font-size: 1em; 687 | font-style: italic; 688 | font-weight: var(--base-text-weight-semibold, 600); 689 | } 690 | 691 | .markdown-body dl dd { 692 | padding: 0 var(--base-size-16); 693 | margin-bottom: var(--base-size-16); 694 | } 695 | 696 | .markdown-body table th { 697 | font-weight: var(--base-text-weight-semibold, 600); 698 | } 699 | 700 | .markdown-body table th, 701 | .markdown-body table td { 702 | padding: 6px 13px; 703 | border: 1px solid var(--borderColor-default); 704 | } 705 | 706 | .markdown-body table td>:last-child { 707 | margin-bottom: 0; 708 | } 709 | 710 | .markdown-body table tr { 711 | background-color: var(--bgColor-default); 712 | border-top: 1px solid var(--borderColor-muted); 713 | } 714 | 715 | .markdown-body table tr:nth-child(2n) { 716 | background-color: var(--bgColor-muted); 717 | } 718 | 719 | .markdown-body table img { 720 | background-color: transparent; 721 | } 722 | 723 | .markdown-body img[align=right] { 724 | padding-left: 20px; 725 | } 726 | 727 | .markdown-body img[align=left] { 728 | padding-right: 20px; 729 | } 730 | 731 | .markdown-body .emoji { 732 | max-width: none; 733 | vertical-align: text-top; 734 | background-color: transparent; 735 | } 736 | 737 | .markdown-body span.frame { 738 | display: block; 739 | overflow: hidden; 740 | } 741 | 742 | .markdown-body span.frame>span { 743 | display: block; 744 | float: left; 745 | width: auto; 746 | padding: 7px; 747 | margin: 13px 0 0; 748 | overflow: hidden; 749 | border: 1px solid var(--borderColor-default); 750 | } 751 | 752 | .markdown-body span.frame span img { 753 | display: block; 754 | float: left; 755 | } 756 | 757 | .markdown-body span.frame span span { 758 | display: block; 759 | padding: 5px 0 0; 760 | clear: both; 761 | color: var(--fgColor-default); 762 | } 763 | 764 | .markdown-body span.align-center { 765 | display: block; 766 | overflow: hidden; 767 | clear: both; 768 | } 769 | 770 | .markdown-body span.align-center>span { 771 | display: block; 772 | margin: 13px auto 0; 773 | overflow: hidden; 774 | text-align: center; 775 | } 776 | 777 | .markdown-body span.align-center span img { 778 | margin: 0 auto; 779 | text-align: center; 780 | } 781 | 782 | .markdown-body span.align-right { 783 | display: block; 784 | overflow: hidden; 785 | clear: both; 786 | } 787 | 788 | .markdown-body span.align-right>span { 789 | display: block; 790 | margin: 13px 0 0; 791 | overflow: hidden; 792 | text-align: right; 793 | } 794 | 795 | .markdown-body span.align-right span img { 796 | margin: 0; 797 | text-align: right; 798 | } 799 | 800 | .markdown-body span.float-left { 801 | display: block; 802 | float: left; 803 | margin-right: 13px; 804 | overflow: hidden; 805 | } 806 | 807 | .markdown-body span.float-left span { 808 | margin: 13px 0 0; 809 | } 810 | 811 | .markdown-body span.float-right { 812 | display: block; 813 | float: right; 814 | margin-left: 13px; 815 | overflow: hidden; 816 | } 817 | 818 | .markdown-body span.float-right>span { 819 | display: block; 820 | margin: 13px auto 0; 821 | overflow: hidden; 822 | text-align: right; 823 | } 824 | 825 | .markdown-body code, 826 | .markdown-body tt { 827 | padding: .2em .4em; 828 | margin: 0; 829 | font-size: 85%; 830 | white-space: break-spaces; 831 | background-color: var(--bgColor-neutral-muted); 832 | border-radius: 6px; 833 | } 834 | 835 | .markdown-body code br, 836 | .markdown-body tt br { 837 | display: none; 838 | } 839 | 840 | .markdown-body del code { 841 | text-decoration: inherit; 842 | } 843 | 844 | .markdown-body samp { 845 | font-size: 85%; 846 | } 847 | 848 | .markdown-body pre code { 849 | font-size: 100%; 850 | } 851 | 852 | .markdown-body pre>code { 853 | padding: 0; 854 | margin: 0; 855 | word-break: normal; 856 | white-space: pre; 857 | background: transparent; 858 | border: 0; 859 | } 860 | 861 | .markdown-body .highlight { 862 | margin-bottom: var(--base-size-16); 863 | } 864 | 865 | .markdown-body .highlight pre { 866 | margin-bottom: 0; 867 | word-break: normal; 868 | } 869 | 870 | .markdown-body .highlight pre, 871 | .markdown-body pre { 872 | padding: var(--base-size-16); 873 | overflow: auto; 874 | font-size: 85%; 875 | line-height: 1.45; 876 | color: var(--fgColor-default); 877 | background-color: var(--bgColor-muted); 878 | border-radius: 6px; 879 | } 880 | 881 | .markdown-body pre code, 882 | .markdown-body pre tt { 883 | display: inline; 884 | max-width: auto; 885 | padding: 0; 886 | margin: 0; 887 | overflow: visible; 888 | line-height: inherit; 889 | word-wrap: normal; 890 | background-color: transparent; 891 | border: 0; 892 | } 893 | 894 | .markdown-body .csv-data td, 895 | .markdown-body .csv-data th { 896 | padding: 5px; 897 | overflow: hidden; 898 | font-size: 12px; 899 | line-height: 1; 900 | text-align: left; 901 | white-space: nowrap; 902 | } 903 | 904 | .markdown-body .csv-data .blob-num { 905 | padding: 10px var(--base-size-8) 9px; 906 | text-align: right; 907 | background: var(--bgColor-default); 908 | border: 0; 909 | } 910 | 911 | .markdown-body .csv-data tr { 912 | border-top: 0; 913 | } 914 | 915 | .markdown-body .csv-data th { 916 | font-weight: var(--base-text-weight-semibold, 600); 917 | background: var(--bgColor-muted); 918 | border-top: 0; 919 | } 920 | 921 | .markdown-body [data-footnote-ref]::before { 922 | content: "["; 923 | } 924 | 925 | .markdown-body [data-footnote-ref]::after { 926 | content: "]"; 927 | } 928 | 929 | .markdown-body .footnotes { 930 | font-size: 12px; 931 | color: var(--fgColor-muted); 932 | border-top: 1px solid var(--borderColor-default); 933 | } 934 | 935 | .markdown-body .footnotes ol { 936 | padding-left: var(--base-size-16); 937 | } 938 | 939 | .markdown-body .footnotes ol ul { 940 | display: inline-block; 941 | padding-left: var(--base-size-16); 942 | margin-top: var(--base-size-16); 943 | } 944 | 945 | .markdown-body .footnotes li { 946 | position: relative; 947 | } 948 | 949 | .markdown-body .footnotes li:target::before { 950 | position: absolute; 951 | top: calc(var(--base-size-8)*-1); 952 | right: calc(var(--base-size-8)*-1); 953 | bottom: calc(var(--base-size-8)*-1); 954 | left: calc(var(--base-size-24)*-1); 955 | pointer-events: none; 956 | content: ""; 957 | border: 2px solid var(--borderColor-accent-emphasis); 958 | border-radius: 6px; 959 | } 960 | 961 | .markdown-body .footnotes li:target { 962 | color: var(--fgColor-default); 963 | } 964 | 965 | .markdown-body .footnotes .data-footnote-backref g-emoji { 966 | font-family: monospace; 967 | } 968 | 969 | .markdown-body body:has(:modal) { 970 | padding-right: var(--dialog-scrollgutter) !important; 971 | } 972 | 973 | .markdown-body .pl-c { 974 | color: var(--color-prettylights-syntax-comment); 975 | } 976 | 977 | .markdown-body .pl-c1, 978 | .markdown-body .pl-s .pl-v { 979 | color: var(--color-prettylights-syntax-constant); 980 | } 981 | 982 | .markdown-body .pl-e, 983 | .markdown-body .pl-en { 984 | color: var(--color-prettylights-syntax-entity); 985 | } 986 | 987 | .markdown-body .pl-smi, 988 | .markdown-body .pl-s .pl-s1 { 989 | color: var(--color-prettylights-syntax-storage-modifier-import); 990 | } 991 | 992 | .markdown-body .pl-ent { 993 | color: var(--color-prettylights-syntax-entity-tag); 994 | } 995 | 996 | .markdown-body .pl-k { 997 | color: var(--color-prettylights-syntax-keyword); 998 | } 999 | 1000 | .markdown-body .pl-s, 1001 | .markdown-body .pl-pds, 1002 | .markdown-body .pl-s .pl-pse .pl-s1, 1003 | .markdown-body .pl-sr, 1004 | .markdown-body .pl-sr .pl-cce, 1005 | .markdown-body .pl-sr .pl-sre, 1006 | .markdown-body .pl-sr .pl-sra { 1007 | color: var(--color-prettylights-syntax-string); 1008 | } 1009 | 1010 | .markdown-body .pl-v, 1011 | .markdown-body .pl-smw { 1012 | color: var(--color-prettylights-syntax-variable); 1013 | } 1014 | 1015 | .markdown-body .pl-bu { 1016 | color: var(--color-prettylights-syntax-brackethighlighter-unmatched); 1017 | } 1018 | 1019 | .markdown-body .pl-ii { 1020 | color: var(--color-prettylights-syntax-invalid-illegal-text); 1021 | background-color: var(--color-prettylights-syntax-invalid-illegal-bg); 1022 | } 1023 | 1024 | .markdown-body .pl-c2 { 1025 | color: var(--color-prettylights-syntax-carriage-return-text); 1026 | background-color: var(--color-prettylights-syntax-carriage-return-bg); 1027 | } 1028 | 1029 | .markdown-body .pl-sr .pl-cce { 1030 | font-weight: bold; 1031 | color: var(--color-prettylights-syntax-string-regexp); 1032 | } 1033 | 1034 | .markdown-body .pl-ml { 1035 | color: var(--color-prettylights-syntax-markup-list); 1036 | } 1037 | 1038 | .markdown-body .pl-mh, 1039 | .markdown-body .pl-mh .pl-en, 1040 | .markdown-body .pl-ms { 1041 | font-weight: bold; 1042 | color: var(--color-prettylights-syntax-markup-heading); 1043 | } 1044 | 1045 | .markdown-body .pl-mi { 1046 | font-style: italic; 1047 | color: var(--color-prettylights-syntax-markup-italic); 1048 | } 1049 | 1050 | .markdown-body .pl-mb { 1051 | font-weight: bold; 1052 | color: var(--color-prettylights-syntax-markup-bold); 1053 | } 1054 | 1055 | .markdown-body .pl-md { 1056 | color: var(--color-prettylights-syntax-markup-deleted-text); 1057 | background-color: var(--color-prettylights-syntax-markup-deleted-bg); 1058 | } 1059 | 1060 | .markdown-body .pl-mi1 { 1061 | color: var(--color-prettylights-syntax-markup-inserted-text); 1062 | background-color: var(--color-prettylights-syntax-markup-inserted-bg); 1063 | } 1064 | 1065 | .markdown-body .pl-mc { 1066 | color: var(--color-prettylights-syntax-markup-changed-text); 1067 | background-color: var(--color-prettylights-syntax-markup-changed-bg); 1068 | } 1069 | 1070 | .markdown-body .pl-mi2 { 1071 | color: var(--color-prettylights-syntax-markup-ignored-text); 1072 | background-color: var(--color-prettylights-syntax-markup-ignored-bg); 1073 | } 1074 | 1075 | .markdown-body .pl-mdr { 1076 | font-weight: bold; 1077 | color: var(--color-prettylights-syntax-meta-diff-range); 1078 | } 1079 | 1080 | .markdown-body .pl-ba { 1081 | color: var(--color-prettylights-syntax-brackethighlighter-angle); 1082 | } 1083 | 1084 | .markdown-body .pl-sg { 1085 | color: var(--color-prettylights-syntax-sublimelinter-gutter-mark); 1086 | } 1087 | 1088 | .markdown-body .pl-corl { 1089 | text-decoration: underline; 1090 | color: var(--color-prettylights-syntax-constant-other-reference-link); 1091 | } 1092 | 1093 | .markdown-body [role=button]:focus:not(:focus-visible), 1094 | .markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible), 1095 | .markdown-body button:focus:not(:focus-visible), 1096 | .markdown-body summary:focus:not(:focus-visible), 1097 | .markdown-body a:focus:not(:focus-visible) { 1098 | outline: none; 1099 | box-shadow: none; 1100 | } 1101 | 1102 | .markdown-body [tabindex="0"]:focus:not(:focus-visible), 1103 | .markdown-body details-dialog:focus:not(:focus-visible) { 1104 | outline: none; 1105 | } 1106 | 1107 | .markdown-body g-emoji { 1108 | display: inline-block; 1109 | min-width: 1ch; 1110 | font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; 1111 | font-size: 1em; 1112 | font-style: normal !important; 1113 | font-weight: var(--base-text-weight-normal, 400); 1114 | line-height: 1; 1115 | vertical-align: -0.075em; 1116 | } 1117 | 1118 | .markdown-body g-emoji img { 1119 | width: 1em; 1120 | height: 1em; 1121 | } 1122 | 1123 | .markdown-body .task-list-item { 1124 | list-style-type: none; 1125 | } 1126 | 1127 | .markdown-body .task-list-item label { 1128 | font-weight: var(--base-text-weight-normal, 400); 1129 | } 1130 | 1131 | .markdown-body .task-list-item.enabled label { 1132 | cursor: pointer; 1133 | } 1134 | 1135 | .markdown-body .task-list-item+.task-list-item { 1136 | margin-top: var(--base-size-4); 1137 | } 1138 | 1139 | .markdown-body .task-list-item .handle { 1140 | display: none; 1141 | } 1142 | 1143 | .markdown-body .task-list-item-checkbox { 1144 | margin: 0 .2em .25em -1.4em; 1145 | vertical-align: middle; 1146 | } 1147 | 1148 | .markdown-body ul:dir(rtl) .task-list-item-checkbox { 1149 | margin: 0 -1.6em .25em .2em; 1150 | } 1151 | 1152 | .markdown-body ol:dir(rtl) .task-list-item-checkbox { 1153 | margin: 0 -1.6em .25em .2em; 1154 | } 1155 | 1156 | .markdown-body .contains-task-list:hover .task-list-item-convert-container, 1157 | .markdown-body .contains-task-list:focus-within .task-list-item-convert-container { 1158 | display: block; 1159 | width: auto; 1160 | height: 24px; 1161 | overflow: visible; 1162 | clip: auto; 1163 | } 1164 | 1165 | .markdown-body ::-webkit-calendar-picker-indicator { 1166 | filter: invert(50%); 1167 | } 1168 | 1169 | .markdown-body .markdown-alert { 1170 | padding: var(--base-size-8) var(--base-size-16); 1171 | margin-bottom: var(--base-size-16); 1172 | color: inherit; 1173 | border-left: .25em solid var(--borderColor-default); 1174 | } 1175 | 1176 | .markdown-body .markdown-alert>:first-child { 1177 | margin-top: 0; 1178 | } 1179 | 1180 | .markdown-body .markdown-alert>:last-child { 1181 | margin-bottom: 0; 1182 | } 1183 | 1184 | .markdown-body .markdown-alert .markdown-alert-title { 1185 | display: flex; 1186 | font-weight: var(--base-text-weight-medium, 500); 1187 | align-items: center; 1188 | line-height: 1; 1189 | } 1190 | 1191 | .markdown-body .markdown-alert.markdown-alert-note { 1192 | border-left-color: var(--borderColor-accent-emphasis); 1193 | } 1194 | 1195 | .markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title { 1196 | color: var(--fgColor-accent); 1197 | } 1198 | 1199 | .markdown-body .markdown-alert.markdown-alert-important { 1200 | border-left-color: var(--borderColor-done-emphasis); 1201 | } 1202 | 1203 | .markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title { 1204 | color: var(--fgColor-done); 1205 | } 1206 | 1207 | .markdown-body .markdown-alert.markdown-alert-warning { 1208 | border-left-color: var(--borderColor-attention-emphasis); 1209 | } 1210 | 1211 | .markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title { 1212 | color: var(--fgColor-attention); 1213 | } 1214 | 1215 | .markdown-body .markdown-alert.markdown-alert-tip { 1216 | border-left-color: var(--borderColor-success-emphasis); 1217 | } 1218 | 1219 | .markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title { 1220 | color: var(--fgColor-success); 1221 | } 1222 | 1223 | .markdown-body .markdown-alert.markdown-alert-caution { 1224 | border-left-color: var(--borderColor-danger-emphasis); 1225 | } 1226 | 1227 | .markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title { 1228 | color: var(--fgColor-danger); 1229 | } 1230 | 1231 | .markdown-body>*:first-child>.heading-element:first-child { 1232 | margin-top: 0 !important; 1233 | } 1234 | 1235 | .markdown-body .highlight pre:has(+.zeroclipboard-container) { 1236 | min-height: 52px; 1237 | } 1238 | --------------------------------------------------------------------------------