├── .chezmoiremove ├── .chezmoiversion ├── dot_cache └── private_neomutt │ ├── bodies │ └── .keep │ └── headers │ └── .keep ├── private_dot_config ├── ghostty │ ├── linux.config │ ├── darwin.config │ ├── config.tmpl │ └── themes │ │ └── gruvbox-dark ├── nvim │ ├── snippets │ │ ├── .lsp │ │ │ ├── all.json │ │ │ ├── go.json │ │ │ ├── package.json │ │ │ ├── lua.json │ │ │ ├── javascript.json │ │ │ └── javascriptreact.json │ │ ├── symlink_lsp.tmpl │ │ ├── symlink_luasnip.tmpl │ │ └── .luasnip │ │ │ ├── lua.lua │ │ │ └── typescript.lua │ ├── lua │ │ ├── config │ │ │ ├── init.lua │ │ │ ├── lazy.lua │ │ │ ├── utils.lua │ │ │ └── color.lua │ │ ├── plugins │ │ │ ├── libs.lua │ │ │ ├── ui │ │ │ │ ├── indent-blankline.lua │ │ │ │ ├── init.lua │ │ │ │ ├── alpha.lua │ │ │ │ └── nui.lua │ │ │ ├── treesitter │ │ │ │ ├── comment.lua │ │ │ │ ├── context.lua │ │ │ │ ├── init.lua │ │ │ │ └── base.lua │ │ │ ├── toggleterm.lua │ │ │ ├── luasnip │ │ │ │ ├── store.lua │ │ │ │ └── init.lua │ │ │ ├── lsp │ │ │ │ ├── custom │ │ │ │ │ ├── init.lua │ │ │ │ │ ├── format.lua │ │ │ │ │ ├── rename.lua │ │ │ │ │ └── code_action.lua │ │ │ │ ├── lightbulb.lua │ │ │ │ ├── null-ls.lua │ │ │ │ ├── init.lua │ │ │ │ ├── utils │ │ │ │ │ └── lua_ls.lua │ │ │ │ └── base.lua │ │ │ ├── cellular-automaton.lua │ │ │ ├── copilot.lua │ │ │ ├── flash.lua │ │ │ ├── autopairs.lua │ │ │ ├── gitlinker.lua │ │ │ ├── git.lua │ │ │ ├── dap │ │ │ │ ├── javascript.lua │ │ │ │ ├── init.lua │ │ │ │ └── base.lua │ │ │ ├── which-key.lua │ │ │ ├── init.lua │ │ │ └── cmp.lua │ │ └── nougat │ │ │ └── color │ │ │ └── gruvbox.lua │ ├── after │ │ └── queries │ │ │ ├── comment │ │ │ └── highlights.scm │ │ │ ├── ecma │ │ │ └── highlights.scm │ │ │ └── css │ │ │ └── highlights.scm │ ├── syntax │ │ └── qf.vim │ ├── coc-settings.json │ └── vscode.vim ├── fd │ └── ignore ├── kitty │ ├── linux.conf │ ├── macos.conf │ └── startup.session ├── git │ └── ignore ├── neomutt │ ├── signatures │ │ ├── personal │ │ └── shopup │ ├── scripts │ │ └── executable_switch_account.sh │ ├── accounts │ │ ├── personal │ │ │ ├── native-connection.tmpl │ │ │ └── config.tmpl │ │ └── shopup │ │ │ └── config.tmpl │ ├── colors │ ├── bindings │ └── muttrc ├── pypoetry │ └── private_config.toml ├── alacritty │ ├── linux.toml │ ├── alacritty.toml.tmpl │ ├── colors.gruvbox_dark.toml │ └── darwin.toml ├── hammerspoon │ ├── .luarc.lua │ ├── config-loader.lua │ ├── utils.lua │ └── init.lua ├── personal │ └── default_node_global_packages ├── rofunicode │ └── config.sh ├── zsh │ ├── dot_zlogout │ ├── dot_zprofile │ └── dot_zshenv ├── lf │ ├── executable_cleaner │ ├── executable_compress │ ├── executable_extract │ ├── executable_trash │ ├── executable_previewer │ └── lfrc ├── gh │ └── config.yml ├── surfingkeys │ └── config.js ├── msmtp │ └── private_config.tmpl ├── bat │ └── config ├── private_gtk-3.0 │ └── gtk.css ├── mpdscribble │ └── mpdscribble.conf.tmpl ├── starship │ └── config.toml └── rofi │ └── config.rasi ├── .modules ├── zsh │ ├── plugins │ │ ├── atuin │ │ │ ├── .gitignore │ │ │ ├── generate.sh │ │ │ └── atuin.plugin.zsh │ │ ├── python │ │ │ ├── .gitignore │ │ │ ├── generate.sh │ │ │ └── python.plugin.zsh │ │ ├── rbenv │ │ │ ├── .gitignore │ │ │ ├── generate.sh │ │ │ └── rbenv.plugin.zsh │ │ ├── terminal │ │ │ └── terminal.plugin.zsh │ │ └── os.darwin │ │ │ └── generate.sh │ └── completions │ │ └── _keybase ├── os.linux.plugin.sh ├── gpg.plugin.sh ├── bash │ ├── plugins │ │ ├── hub.plugin.bash │ │ ├── tilix.plugin.bash │ │ ├── umake.plugin.bash │ │ ├── composer.plugin.bash │ │ ├── pacman.plugin.bash │ │ └── luver.plugin.bash │ └── completions │ │ └── keybase ├── android.plugin.sh ├── ruby.plugin.sh ├── rust.plugin.sh ├── node.plugin.sh ├── lf.plugin.sh ├── go.plugin.sh ├── python.plugin.sh ├── aliases.sh ├── fzf.plugin.sh ├── helpers.sh └── os.darwin.plugin.sh ├── private_dot_ssh ├── create_config_misc ├── private_id_rsa.tmpl ├── private_garb.age.pub.tmpl ├── private_id_rsa.pub.tmpl ├── private_garb.age.tmpl ├── config.tmpl └── config_tailscale.tmpl ├── dot_vim ├── symlink_vimrc.tmpl └── symlink_coc-settings.json.tmpl ├── dot_gitconfig.optimizely.tmpl ├── dot_local ├── share │ └── chezmoi │ │ └── dot_modules │ │ └── create_machine.local.plugin.sh └── bin │ ├── executable_run_rofi.sh │ ├── executable_open.tmpl │ └── executable_music-terminal ├── .gitignore ├── .chezmoitemplates └── bitwarden_chezmoi_config ├── symlink_dot_mpdconf.tmpl ├── dot_bash_profile ├── .stylua.toml ├── dot_zshenv ├── setup.sh ├── dot_bash_logout ├── .chezmoiscripts ├── run_once_after_20_setup.sh.tmpl ├── run_once_before_10_init.sh.tmpl ├── run_once_after_21_settings.sh.tmpl ├── .10_init.linux.sh ├── .10_init.darwin.sh ├── .00_helpers.sh ├── .20_setup.linux.sh ├── .20_setup.darwin.sh └── .21_settings.linux.sh ├── .gitmodules ├── .chezmoiignore ├── .chezmoi.yaml.tmpl ├── README.md ├── dot_inputrc ├── dot_nanorc ├── dot_gitconfig.tmpl ├── .nvim.lua ├── dot_mbsyncrc.tmpl └── dot_bashrc /.chezmoiremove: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.chezmoiversion: -------------------------------------------------------------------------------- 1 | 2.9.0 2 | -------------------------------------------------------------------------------- /dot_cache/private_neomutt/bodies/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dot_cache/private_neomutt/headers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /private_dot_config/ghostty/linux.config: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/atuin/.gitignore: -------------------------------------------------------------------------------- 1 | _* 2 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/python/.gitignore: -------------------------------------------------------------------------------- 1 | _* 2 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/rbenv/.gitignore: -------------------------------------------------------------------------------- 1 | _* 2 | -------------------------------------------------------------------------------- /.modules/os.linux.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.lsp/all.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /private_dot_config/fd/ignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | -------------------------------------------------------------------------------- /private_dot_config/kitty/linux.conf: -------------------------------------------------------------------------------- 1 | font_size 13.0 2 | -------------------------------------------------------------------------------- /private_dot_config/kitty/macos.conf: -------------------------------------------------------------------------------- 1 | font_size 15.0 2 | -------------------------------------------------------------------------------- /private_dot_config/git/ignore: -------------------------------------------------------------------------------- 1 | .autoenv.in.zsh 2 | .autoenv.out.zsh 3 | -------------------------------------------------------------------------------- /private_dot_ssh/create_config_misc: -------------------------------------------------------------------------------- 1 | # vim: set filetype=sshconfig : 2 | -------------------------------------------------------------------------------- /dot_vim/symlink_vimrc.tmpl: -------------------------------------------------------------------------------- 1 | {{ .chezmoi.homeDir }}/.config/nvim/init.vim 2 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/signatures/personal: -------------------------------------------------------------------------------- 1 | Regards, 2 | Munif Tanjim 3 | -------------------------------------------------------------------------------- /.modules/gpg.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export GPG_TTY=$(tty) 4 | -------------------------------------------------------------------------------- /dot_gitconfig.optimizely.tmpl: -------------------------------------------------------------------------------- 1 | # vim: set filetype=gitconfig foldmethod=indent : 2 | -------------------------------------------------------------------------------- /private_dot_config/pypoetry/private_config.toml: -------------------------------------------------------------------------------- 1 | [virtualenvs] 2 | in-project = true 3 | -------------------------------------------------------------------------------- /dot_local/share/chezmoi/dot_modules/create_machine.local.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .modules/bash/plugins/enabled/* 2 | .modules/temp/* 3 | .modules/*.local.* 4 | *~ 5 | -------------------------------------------------------------------------------- /dot_vim/symlink_coc-settings.json.tmpl: -------------------------------------------------------------------------------- 1 | {{ .chezmoi.homeDir }}/.config/nvim/coc-settings.json 2 | -------------------------------------------------------------------------------- /private_dot_config/ghostty/darwin.config: -------------------------------------------------------------------------------- 1 | macos-auto-secure-input = true 2 | macos-option-as-alt = left 3 | -------------------------------------------------------------------------------- /private_dot_config/kitty/startup.session: -------------------------------------------------------------------------------- 1 | new_tab TMUX 2 | 3 | launch zsh -l -c "tmux attach || tmux" 4 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/config/init.lua: -------------------------------------------------------------------------------- 1 | require("config.appearance") 2 | 3 | require("config.lazy") 4 | -------------------------------------------------------------------------------- /.chezmoitemplates/bitwarden_chezmoi_config: -------------------------------------------------------------------------------- 1 | {{- ( get ( bitwardenFields "item" "io.chezmoi.config") . ).value -}} 2 | -------------------------------------------------------------------------------- /private_dot_ssh/private_id_rsa.tmpl: -------------------------------------------------------------------------------- 1 | {{ ( bitwarden "item" "dev.muniftanjim.ssh.personal.id_rsa.private" ).notes }} 2 | -------------------------------------------------------------------------------- /dot_local/bin/executable_run_rofi.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | rofi -combi-modi window,drun -show combi -modi combi 4 | -------------------------------------------------------------------------------- /private_dot_config/alacritty/linux.toml: -------------------------------------------------------------------------------- 1 | [window] 2 | decorations = "None" # Full / None 3 | 4 | [font] 5 | size = 13.0 6 | -------------------------------------------------------------------------------- /private_dot_ssh/private_garb.age.pub.tmpl: -------------------------------------------------------------------------------- 1 | {{- ( bitwarden "item" "dev.muniftanjim.personal.garb.age.public" ).notes -}} 2 | -------------------------------------------------------------------------------- /private_dot_ssh/private_id_rsa.pub.tmpl: -------------------------------------------------------------------------------- 1 | {{ ( bitwarden "item" "dev.muniftanjim.ssh.personal.id_rsa.public" ).notes }} 2 | -------------------------------------------------------------------------------- /.modules/bash/plugins/hub.plugin.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ( command_exists hub ) && eval "$(hub alias -s)" 4 | 5 | -------------------------------------------------------------------------------- /.modules/bash/plugins/tilix.plugin.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [[ -n $TILIX_ID ]] && source /etc/profile.d/vte-2.91.sh 4 | -------------------------------------------------------------------------------- /symlink_dot_mpdconf.tmpl: -------------------------------------------------------------------------------- 1 | {{- if eq .chezmoi.os "darwin" -}} 2 | {{ .chezmoi.homeDir }}/.config/mpd/mpd.conf 3 | {{- end -}} 4 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/signatures/shopup: -------------------------------------------------------------------------------- 1 | Regards, 2 | Munif Tanjim, 3 | Junior Software Engineer, 4 | ShopUp, 5 | Bangladesh 6 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/libs.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-tree/nvim-web-devicons", 3 | "nvim-lua/plenary.nvim", 4 | } 5 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/symlink_lsp.tmpl: -------------------------------------------------------------------------------- 1 | {{ joinPath .chezmoi.sourceDir "private_dot_config/nvim" "snippets" ".lsp" }} 2 | -------------------------------------------------------------------------------- /private_dot_ssh/private_garb.age.tmpl: -------------------------------------------------------------------------------- 1 | {{- ( bitwarden "item" "dev.muniftanjim.personal.garb.age.private" ).notes | b64dec -}} 2 | -------------------------------------------------------------------------------- /dot_bash_profile: -------------------------------------------------------------------------------- 1 | if [ -n "$BASH_VERSION" ]; then 2 | if [ -f "$HOME/.bashrc" ]; then 3 | source "$HOME/.bashrc" 4 | fi 5 | fi 6 | 7 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/ui/indent-blankline.lua: -------------------------------------------------------------------------------- 1 | require("ibl").setup({ 2 | scope = { 3 | enabled = true, 4 | }, 5 | }) 6 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/symlink_luasnip.tmpl: -------------------------------------------------------------------------------- 1 | {{ joinPath .chezmoi.sourceDir "private_dot_config/nvim" "snippets" ".luasnip" }} 2 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/queries/comment/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | 3 | ("text" @constant 4 | (#lua-match? @constant "^[@][a-zA-Z0-9_-]+$")) 5 | -------------------------------------------------------------------------------- /.modules/bash/plugins/umake.plugin.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/evn bash 2 | 3 | ( ! command_exists umake ) && return 4 | 5 | pathmunge "${HOME}/.local/share/umake/bin" 6 | 7 | -------------------------------------------------------------------------------- /private_dot_config/hammerspoon/.luarc.lua: -------------------------------------------------------------------------------- 1 | return { 2 | workspace = { 3 | library = { "~/.config/hammerspoon/Spoons/EmmyLua.spoon/annotations" }, 4 | }, 5 | } 6 | -------------------------------------------------------------------------------- /.stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 120 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 2 5 | quote_style = "AutoPreferDouble" 6 | no_call_parentheses = false 7 | -------------------------------------------------------------------------------- /private_dot_config/nvim/syntax/qf.vim: -------------------------------------------------------------------------------- 1 | if exists('b:current_syntax') 2 | finish 3 | end 4 | 5 | lua require('plugins.ui.quickfix').syntax() 6 | 7 | let b:current_syntax = 'qf' 8 | -------------------------------------------------------------------------------- /dot_zshenv: -------------------------------------------------------------------------------- 1 | export skip_global_compinit=1 2 | export DEBIAN_PREVENT_KEYBOARD_CHANGES=1 3 | 4 | export ZDOTDIR=$HOME/.config/zsh 5 | . $ZDOTDIR/.zshenv 6 | 7 | # vim: set filetype=sh : 8 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.luasnip/lua.lua: -------------------------------------------------------------------------------- 1 | local store = require("plugins.luasnip.store") 2 | 3 | return { 4 | store.postfix.increment, 5 | store.postfix.decrement, 6 | } 7 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.luasnip/typescript.lua: -------------------------------------------------------------------------------- 1 | local store = require("plugins.luasnip.store") 2 | 3 | return { 4 | store.postfix.increment, 5 | store.postfix.decrement, 6 | } 7 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/treesitter/comment.lua: -------------------------------------------------------------------------------- 1 | require("Comment").setup({ 2 | pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(), 3 | }) 4 | -------------------------------------------------------------------------------- /private_dot_config/personal/default_node_global_packages: -------------------------------------------------------------------------------- 1 | eslint@latest 2 | eslint_d@latest 3 | npmrc@latest 4 | prettier@latest 5 | @fsouza/prettierd@latest 6 | typescript@latest 7 | zx@latest 8 | -------------------------------------------------------------------------------- /.modules/android.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export ANDROID_SDK_ROOT="${HOME}/.local/share/android/sdk" 4 | 5 | pathmunge "${ANDROID_SDK_ROOT}/tools" 6 | pathmunge "${ANDROID_SDK_ROOT}/platform-tools" 7 | -------------------------------------------------------------------------------- /.modules/bash/plugins/composer.plugin.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ( ! command_exists composer ) && return 4 | 5 | export COMPOSER_HOME=${COMPOSER_HOME:-"${HOME}/.composer"} 6 | pathmunge "${COMPOSER_HOME}/vendor/bin" 7 | 8 | -------------------------------------------------------------------------------- /.modules/ruby.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export RBENV_ROOT=${RBENV_ROOT:-"$HOME/.rbenv"} 4 | 5 | pathmunge "${RBENV_ROOT}/bin" 6 | pathmunge "${RBENV_ROOT}/plugins/ruby-build/bin" 7 | 8 | eval "$(rbenv init -)" 9 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | curl -fsSL https://raw.githubusercontent.com/MunifTanjim/scripts.sh/main/setup-chezmoi | bash 6 | 7 | chezmoi init MunifTanjim 8 | 9 | chezmoi apply 10 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/rbenv/generate.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | __generated_file="$(dirname $(realpath $0))/_generated.zsh" 4 | 5 | rm -f "${__generated_file}" 6 | rbenv init - zsh >> "${__generated_file}" 7 | 8 | unset __generated_file 9 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/queries/ecma/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | 3 | [ 4 | "new" 5 | "delete" 6 | ] @keyword 7 | 8 | ((identifier) @constant 9 | (#lua-match? @constant "^_*[A-Z][A-Z%d_]*$") 10 | (#set! "priority" 200)) 11 | -------------------------------------------------------------------------------- /private_dot_config/rofunicode/config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | export ROFUNICODE_DATA_FILENAMES="emojis" 4 | export ROFUNICODE_PROMPT="Emoji" 5 | export ROFUNICODE_SKIN_TONE="medium-light" # neutral/light/medium-light/medium/medium-dark/dark 6 | -------------------------------------------------------------------------------- /.modules/bash/plugins/pacman.plugin.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ( ! command_exists pacman ) && return 4 | 5 | # Aliases 6 | alias pacman-remove-orphans='sudo pacman -Rns $(pacman -Qtdq)' 7 | alias pacman-unlock='sudo rm /var/lib/pacman/db.lck' 8 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/atuin/generate.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | __generated_file="$(dirname $(realpath $0))/_generated.zsh" 4 | 5 | rm -f "${__generated_file}" 6 | ATUIN_NOBIND=true atuin init zsh >>"${__generated_file}" 7 | 8 | unset __generated_file 9 | -------------------------------------------------------------------------------- /dot_bash_logout: -------------------------------------------------------------------------------- 1 | # ~/.bash_logout: executed by bash(1) when login shell exits. 2 | 3 | # when leaving the console clear the screen to increase privacy 4 | 5 | if [ "$SHLVL" = 1 ]; then 6 | [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q 7 | fi 8 | -------------------------------------------------------------------------------- /private_dot_config/zsh/dot_zlogout: -------------------------------------------------------------------------------- 1 | # vim: set filetype=sh : 2 | 3 | if test -n "${FNM_MULTISHELL_PATH}"; then 4 | rm -f "${FNM_MULTISHELL_PATH}" 5 | fi 6 | 7 | if test -n "${LUVER_CURRENT_DIR}"; then 8 | rm -f "${LUVER_CURRENT_DIR}" 9 | fi 10 | -------------------------------------------------------------------------------- /private_dot_config/zsh/dot_zprofile: -------------------------------------------------------------------------------- 1 | typeset -U path 2 | 3 | export DOTFILES="${HOME}/.local/share/chezmoi" 4 | export DOTFILES_MODULES="${DOTFILES}/.modules" 5 | 6 | path=("${HOME}/.local/bin" "${DOTFILES}/.scripts.sh" ${path[@]}) 7 | 8 | # vim: set filetype=zsh : 9 | -------------------------------------------------------------------------------- /.modules/rust.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export CARGO_HOME=${CARGO_HOME:-"${HOME}/.local/share/cargo"} 4 | export RUSTUP_HOME=${RUSTUP_HOME:-"${HOME}/.local/share/rustup"} 5 | 6 | if directory_exists "${CARGO_HOME}"; then 7 | . "${CARGO_HOME}/env" 8 | fi 9 | -------------------------------------------------------------------------------- /private_dot_config/nvim/after/queries/css/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | 3 | [ 4 | (class_name) 5 | (id_name) 6 | ] @type 7 | 8 | (nesting_selector) @punctuation.special 9 | (class_selector "." @punctuation.special) 10 | (id_selector "#" @punctuation.special) 11 | -------------------------------------------------------------------------------- /.modules/node.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export FNM_DIR="${FNM_DIR:-"${XDG_DATA_HOME:-"${HOME}/.local/share"}/fnm"}" 4 | eval "$(fnm env --use-on-cd --resolve-engines --corepack-enabled --log-level error)" 5 | 6 | export COREPACK_ENABLE_AUTO_PIN=0 7 | 8 | PATH="./node_modules/.bin:${PATH}" 9 | -------------------------------------------------------------------------------- /private_dot_config/lf/executable_cleaner: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | has_kitty_protocol() { 6 | test -z "${TMUX:-}" && test -n "${KITTY_PID:-}" 7 | } 8 | 9 | if has_kitty_protocol; then 10 | kitty +kitten icat --clear --silent --stdin no --transfer-mode file < /dev/null > /dev/tty 11 | fi 12 | -------------------------------------------------------------------------------- /.modules/bash/plugins/luver.plugin.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export LUVER_DIR="${LUVER_DIR:-"${XDG_DATA_HOME:-"${HOME}/.local/share"}/luver"}" 4 | 5 | if [[ ! -d "${LUVER_DIR}/self" ]]; then 6 | git clone https://github.com/MunifTanjim/luver.git "${LUVER_DIR}/self" 7 | fi 8 | 9 | source "${LUVER_DIR}/self/luver.bash" 10 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/rbenv/rbenv.plugin.zsh: -------------------------------------------------------------------------------- 1 | export RBENV_ROOT=${RBENV_ROOT:-"$HOME/.rbenv"} 2 | 3 | if [[ -d "${RBENV_ROOT}/bin" ]]; then 4 | PATH="${RBENV_ROOT}/bin:${PATH}" 5 | fi 6 | 7 | PATH="${RBENV_ROOT}/plugins/ruby-build/bin:${PATH}" 8 | 9 | if (( ${+commands[rbenv]} )); then 10 | source "${0:A:h}/_generated.zsh" 11 | fi 12 | -------------------------------------------------------------------------------- /.chezmoiscripts/run_once_after_20_setup.sh.tmpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=gotexttmpl.sh : */}} 2 | 3 | {{- $scriptName := ( list ".20_setup" .chezmoi.os "sh" | join "." ) -}} 4 | {{- $scriptPath := ( joinPath ( toString .chezmoi.sourceDir ) ".chezmoiscripts" $scriptName ) -}} 5 | 6 | {{- if stat $scriptPath -}} 7 | {{ include $scriptPath }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /.chezmoiscripts/run_once_before_10_init.sh.tmpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=gotexttmpl.sh : */}} 2 | 3 | {{- $scriptName := ( list ".10_init" .chezmoi.os "sh" | join "." ) -}} 4 | {{- $scriptPath := ( joinPath ( toString .chezmoi.sourceDir ) ".chezmoiscripts" $scriptName ) -}} 5 | 6 | {{- if stat $scriptPath -}} 7 | {{ include $scriptPath }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /.chezmoiscripts/run_once_after_21_settings.sh.tmpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=gotexttmpl.sh : */}} 2 | 3 | {{- $scriptName := ( list ".21_settings" .chezmoi.os "sh" | join "." ) -}} 4 | {{- $scriptPath := ( joinPath ( toString .chezmoi.sourceDir ) ".chezmoiscripts" $scriptName ) -}} 5 | 6 | {{- if stat $scriptPath -}} 7 | {{ include $scriptPath }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/python/generate.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | __generated_file="$(dirname $(realpath $0))/_generated.zsh" 4 | 5 | rm -f "${__generated_file}" 6 | pyenv init --path zsh >> "${__generated_file}" 7 | pyenv init - --no-rehash zsh >> "${__generated_file}" 8 | pyenv virtualenv-init - zsh >> "${__generated_file}" 9 | 10 | unset __generated_file 11 | -------------------------------------------------------------------------------- /private_dot_config/ghostty/config.tmpl: -------------------------------------------------------------------------------- 1 | window-decoration = false 2 | window-padding-balance = true 3 | 4 | mouse-hide-while-typing = true 5 | 6 | theme = gruvbox-dark 7 | cursor-invert-fg-bg = true 8 | selection-invert-fg-bg = true 9 | 10 | font-size = 15 11 | 12 | initial-command = zsh -l -c "tmux attach || tmux" 13 | 14 | config-file = {{ .chezmoi.os }}.config 15 | -------------------------------------------------------------------------------- /.modules/lf.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | if ! command_exists lf; then 4 | return 5 | fi 6 | 7 | lfcd() { 8 | tmp="$(mktemp)" 9 | command lf -last-dir-path="$tmp" "$@" 10 | if [ -f "$tmp" ]; then 11 | dir="$(cat "$tmp")" 12 | rm -f "$tmp" 13 | if [ -d "$dir" ]; then 14 | if [ "$dir" != "$(pwd)" ]; then 15 | cd "$dir" 16 | fi 17 | fi 18 | fi 19 | } 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule ".modules/.bash-sensible"] 2 | path = .modules/.bash-sensible 3 | url = https://github.com/mrzool/bash-sensible 4 | [submodule ".modules/.dircolors-solarized"] 5 | path = .modules/.dircolors-solarized 6 | url = https://github.com/seebi/dircolors-solarized 7 | [submodule ".scripts.sh"] 8 | path = .scripts.sh 9 | url = https://github.com/MunifTanjim/scripts.sh 10 | shallow = true 11 | -------------------------------------------------------------------------------- /private_dot_ssh/config.tmpl: -------------------------------------------------------------------------------- 1 | {{- /* vim: set filetype=sshconfig : */ -}} 2 | 3 | Include config_tailscale 4 | 5 | Include config_misc 6 | 7 | Host * 8 | User {{ "c2hhaWthdA==" | b64dec }} 9 | ControlMaster auto 10 | ControlPath ~/.ssh/control/%C.sock 11 | AddKeysToAgent yes 12 | IgnoreUnknown UseKeychain 13 | UseKeychain yes 14 | IdentityFile ~/.ssh/id_rsa 15 | KeepAlive yes 16 | ServerAliveInterval 60 17 | ServerAliveCountMax 6 18 | -------------------------------------------------------------------------------- /.modules/go.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | if command_exists go; then 4 | export GOROOT="${GOROOT:-"$(go env GOROOT)"}" 5 | else 6 | GOLANG_DIR="${GOLANG_DIR:-"${XDG_DATA_HOME:-"${HOME}/.local/share"}/golang"}" 7 | export GOROOT="${GOROOT:-"${GOLANG_DIR}/current"}" 8 | fi 9 | 10 | export GOPATH="${GOPATH:-"${XDG_DATA_HOME:-"${HOME}/.local/share"}/go"}" 11 | 12 | pathmunge "${GOROOT}/bin" 13 | pathmunge "${GOPATH}/bin" 14 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/terminal/terminal.plugin.zsh: -------------------------------------------------------------------------------- 1 | if test -n "${GHOSTTY_RESOURCES_DIR}"; then 2 | builtin source "${GHOSTTY_RESOURCES_DIR}/shell-integration/zsh/ghostty-integration" 3 | elif test -n "${KITTY_INSTALLATION_DIR}"; then 4 | export KITTY_SHELL_INTEGRATION="enabled" 5 | autoload -Uz -- "${KITTY_INSTALLATION_DIR}/shell-integration/zsh/kitty-integration" 6 | kitty-integration 7 | unfunction kitty-integration 8 | fi 9 | 10 | -------------------------------------------------------------------------------- /private_dot_config/lf/executable_compress: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euf 4 | 5 | IFS=' 6 | ' 7 | 8 | format="$1" 9 | shift 10 | name="$1" 11 | shift 12 | fs="$@" 13 | 14 | if test -e "${name}"; then 15 | exit 1 16 | fi 17 | 18 | mkdir "${name}" 19 | cp -r $fs "${name}" 20 | 21 | case "${format}" in 22 | tar) tar czf "${name}.tar.gz" "${name}";; 23 | zip) zip -r "${name}.zip" "${name}";; 24 | *) exit 1;; 25 | esac 26 | 27 | rm -rf "${name}" 28 | -------------------------------------------------------------------------------- /private_dot_config/lf/executable_extract: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euf 4 | 5 | f="$1" 6 | 7 | case "$f" in 8 | *.tar.bz|*.tar.bz2|*.tbz|*.tbz2) tar xjvf "$f";; 9 | *.tar.gz|*.tgz) tar xzvf "$f";; 10 | *.tar.xz|*.txz) tar xJvf "$f";; 11 | *.zip) 12 | if type ditto >/dev/null 2>&1; then 13 | ditto -V -x -k "$f" . 14 | else 15 | unzip "$f" 16 | fi 17 | ;; 18 | *.rar) unrar x "$f";; 19 | *.7z|*.z*) 7z x "$f";; 20 | esac 21 | -------------------------------------------------------------------------------- /.chezmoiscripts/.10_init.linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | CHEZMOI_SOURCE="${HOME}/.local/share/chezmoi" 6 | source "${CHEZMOI_SOURCE}/.chezmoiscripts/.00_helpers.sh" 7 | 8 | install_basic_tools() { 9 | echo "installing basic tools..." 10 | sudo apt install curl git 11 | 12 | setup-git-credential-libsecret 13 | } 14 | 15 | ensure_linux 16 | ask_sudo 17 | 18 | install_basic_tools 19 | ensure_secret_manager 20 | ensure_github_cli_login 21 | -------------------------------------------------------------------------------- /private_dot_config/ghostty/themes/gruvbox-dark: -------------------------------------------------------------------------------- 1 | palette = 0=#3c3836 2 | palette = 1=#cc241d 3 | palette = 2=#98971a 4 | palette = 3=#d79921 5 | palette = 4=#458588 6 | palette = 5=#b16286 7 | palette = 6=#689d6a 8 | palette = 7=#fbf1c7 9 | 10 | palette = 8=#7c6f64 11 | palette = 9=#fb4934 12 | palette = 10=#b8bb26 13 | palette = 11=#fabd2f 14 | palette = 12=#83a598 15 | palette = 13=#d3869b 16 | palette = 14=#8ec07c 17 | palette = 15=#f9f5d7 18 | 19 | background = 1d2021 20 | foreground = ebdbb2 21 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.lsp/go.json: -------------------------------------------------------------------------------- 1 | { 2 | "function": { 3 | "prefix": "fn", 4 | "body": ["func ${1}($2) $3 {", " $0", "}"] 5 | }, 6 | "struct function": { 7 | "prefix": "sfn", 8 | "body": ["func (${1}) ${2}($3) $4 {", " $0", "}"] 9 | }, 10 | "go func": { 11 | "prefix": "gofn", 12 | "body": ["go func () {", " $0", "}()"] 13 | }, 14 | "if err return": { 15 | "prefix": "ier", 16 | "body": ["if err != nil {", " return $0err","}"] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /private_dot_config/lf/executable_trash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euf 4 | 5 | command_exists() { 6 | type "${1}" >/dev/null 2>&1 7 | } 8 | 9 | is_mac() { 10 | [[ $OSTYPE = darwin* ]] 11 | } 12 | 13 | IFS=' 14 | ' 15 | 16 | fs="$@" 17 | 18 | if is_mac; then 19 | if command_exists trash; then 20 | trash -F $fs 21 | exit 0 22 | fi 23 | else 24 | if command_exists gio; then 25 | gio trash $fs 26 | exit 0 27 | fi 28 | fi 29 | 30 | for f in $fs; do 31 | mv "$f" "${HOME}/.trash/$(printf $f | tr '/' '%')" 32 | done 33 | -------------------------------------------------------------------------------- /.modules/zsh/completions/_keybase: -------------------------------------------------------------------------------- 1 | #compdef _keybase keybase 2 | 3 | _keybase() { 4 | local -a opts 5 | local cur 6 | cur=${words[-1]} 7 | if [[ "$cur" == "-"* ]]; then 8 | opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}") 9 | else 10 | opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-bash-completion)}") 11 | fi 12 | 13 | if [[ "${opts[1]}" != "" ]]; then 14 | _describe 'values' opts 15 | else 16 | _files 17 | fi 18 | 19 | return 20 | } 21 | -------------------------------------------------------------------------------- /.modules/python.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export POETRY_CACHE_DIR="${XDG_CACHE_HOME:-"${HOME}/.cache"}/pypoetry" 4 | export POETRY_CONFIG_DIR="${XDG_CONFIG_HOME:-"${HOME}/.config"}/pypoetry" 5 | export POETRY_DATA_DIR="${XDG_DATA_HOME:-"${HOME}/.local/share"}/pypoetry" 6 | 7 | export PYENV_ROOT=${PYENV_ROOT:-"${HOME}/.pyenv"} 8 | export PYENV_VIRTUALENV_DISABLE_PROMPT=1 9 | export VIRTUAL_ENV_DISABLE_PROMPT=1 10 | 11 | pathmunge "${PYENV_ROOT}/bin" 12 | pathmunge "${PYENV_ROOT}/shims" 13 | 14 | eval "$(pyenv init -)" 15 | eval "$(pyenv virtualenv-init -)" 16 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/python/python.plugin.zsh: -------------------------------------------------------------------------------- 1 | export POETRY_CACHE_DIR="${XDG_CACHE_HOME:-"${HOME}/.cache"}/pypoetry" 2 | export POETRY_CONFIG_DIR="${XDG_CONFIG_HOME:-"${HOME}/.config"}/pypoetry" 3 | export POETRY_DATA_DIR="${XDG_DATA_HOME:-"${HOME}/.local/share"}/pypoetry" 4 | 5 | export PYENV_ROOT=${PYENV_ROOT:-"${HOME}/.pyenv"} 6 | export PYENV_VIRTUALENV_DISABLE_PROMPT=1 7 | export VIRTUAL_ENV_DISABLE_PROMPT=1 8 | 9 | if [[ -d "${PYENV_ROOT}/bin" ]]; then 10 | export PATH="${PYENV_ROOT}/bin:${PATH}" 11 | fi 12 | 13 | if (( ${+commands[pyenv]} )); then 14 | source "${0:A:h}/_generated.zsh" 15 | fi 16 | -------------------------------------------------------------------------------- /.chezmoiignore: -------------------------------------------------------------------------------- 1 | README.md 2 | setup.sh 3 | 4 | {{ if not .meta.is.personal_machine }} 5 | .cache/neomutt 6 | .config/msmtp 7 | .config/neomutt 8 | .mbsyncrc 9 | {{ end }} 10 | 11 | {{ if .meta.is.headless_machine }} 12 | .config/mpd 13 | .config/mpdscribble 14 | .config/ncmpcpp 15 | .mpdconf 16 | {{ end }} 17 | 18 | {{ if not .meta.should.include_secrets }} 19 | .config/mpdscribble 20 | .config/msmtp 21 | .config/neomutt 22 | .mbsyncrc 23 | .ssh/garb.age 24 | .ssh/garb.age.pub 25 | .ssh/id_rsa 26 | .ssh/id_rsa.pub 27 | {{ end }} 28 | 29 | {{ if ne .chezmoi.os "darwin" }} 30 | .config/karabiner.edn 31 | {{ end }} 32 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/toggleterm.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "akinsho/toggleterm.nvim", 3 | version = "*", 4 | opts = { 5 | open_mapping = [[]], 6 | shade_terminals = false, 7 | on_open = function(term) 8 | local winid, bufnr = term.window, term.bufnr 9 | 10 | vim.wo[winid].signcolumn = "no" 11 | 12 | local opts = { buffer = bufnr, silent = true } 13 | vim.keymap.set("n", [[]], ":ToggleTerm", opts) 14 | vim.keymap.set("t", [[]], [[]], opts) 15 | vim.keymap.set("t", [[]], [[]], opts) 16 | end, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/atuin/atuin.plugin.zsh: -------------------------------------------------------------------------------- 1 | source "${0:A:h}/_generated.zsh" 2 | 3 | _zsh_autosuggest_strategy_atuin() { 4 | suggestion="$(atuin search --cmd-only --limit 1 --search-mode prefix --filter-mode workspace -- "${1}" || \ 5 | atuin search --cmd-only --limit 1 --search-mode prefix -- "${1}")" 6 | } 7 | 8 | bindkey -M emacs '^r' atuin-search 9 | bindkey -M viins '^r' atuin-search-viins 10 | bindkey -M vicmd '/' atuin-search 11 | 12 | # bindkey -M emacs "${key[Up]}" atuin-up-search 13 | # bindkey -M vicmd "${key[Up]}" atuin-up-search-vicmd 14 | # bindkey -M viins "${key[Up]}" atuin-up-search-viins 15 | # bindkey -M vicmd 'k' atuin-up-search-vicmd 16 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/treesitter/context.lua: -------------------------------------------------------------------------------- 1 | local u = require("config.utils") 2 | 3 | local ts_ctx = require("treesitter-context") 4 | 5 | ts_ctx.setup({ 6 | enable = true, 7 | max_lines = 3, 8 | min_window_height = 0, 9 | line_numbers = true, 10 | multiline_threshold = 20, 11 | trim_scope = "outer", 12 | mode = "cursor", 13 | zindex = 20, 14 | }) 15 | 16 | u.set_keymaps("n", { 17 | { 18 | "tsc", 19 | "TSContextToggle", 20 | "[treesitter] toggle context", 21 | }, 22 | { 23 | "gK", 24 | function() 25 | ts_ctx.go_to_context() 26 | end, 27 | "[treesitter] toggle context", 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /.modules/aliases.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | alias c='refresh_and_clear' 4 | alias x='eval "$(__exit_or_tmux_detach)"' 5 | alias :q='eval "$(__exit_or_tmux_detach)"' 6 | alias :w='' 7 | 8 | alias md='mkdir -p' 9 | 10 | # apt 11 | alias apt='sudo apt' 12 | alias apt.i='sudo apt install' 13 | alias apt.ud='sudo apt update' 14 | alias apt.ug='sudo apt upgrade' 15 | alias apt.dug='sudo apt dist-upgrade' 16 | alias apt.ar='sudo apt autoremove' 17 | 18 | # apt-fast 19 | alias aptf='sudo apt-fast' 20 | alias aptf.i='sudo apt-fast install' 21 | alias aptf.ud='sudo apt-fast update' 22 | alias aptf.ug='sudo apt-fast upgrade' 23 | alias aptf.dug='sudo apt-fast dist-upgrade' 24 | 25 | # git 26 | alias g='git' 27 | -------------------------------------------------------------------------------- /.modules/bash/completions/keybase: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # : ${PROG:=$(basename ${BASH_SOURCE})} 4 | PROG=keybase 5 | 6 | _cli_bash_autocomplete() { 7 | if [[ "${COMP_WORDS[0]}" != "source" ]]; then 8 | local cur opts base 9 | COMPREPLY=() 10 | cur="${COMP_WORDS[COMP_CWORD]}" 11 | if [[ "$cur" == "-"* ]]; then 12 | opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion ) 13 | else 14 | opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) 15 | fi 16 | COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) 17 | return 0 18 | fi 19 | } 20 | 21 | complete -o bashdefault -o default -o nospace -F _cli_bash_autocomplete $PROG 22 | unset PROG 23 | -------------------------------------------------------------------------------- /dot_local/bin/executable_open.tmpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=bash : */}} 2 | 3 | {{- if eq .chezmoi.os "linux" -}} 4 | 5 | if grep -q Microsoft /proc/version >/dev/null 2>&1; then 6 | exec explorer.exe $@ 7 | elif type xdg-open >/dev/null 2>&1; then 8 | exec xdg-open $@ 9 | else 10 | echo "[warning] this command does not exist!" 11 | echo 12 | echo "[countdown] self destructing in..." 13 | echo 14 | 15 | secs=$((5)) 16 | while [ $secs -ge 0 ]; do 17 | sleep 1 & 18 | printf "\r %d " $(( secs )) 19 | secs=$(( $secs - 1 )) 20 | wait 21 | done 22 | echo 23 | 24 | mv -f "$0" "$(dirname $0)/__open" 25 | 26 | echo 27 | echo "[done] $0 is gone!" 28 | 29 | exit 127 30 | fi 31 | 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /private_dot_config/gh/config.yml: -------------------------------------------------------------------------------- 1 | version: "1" 2 | # What protocol to use when performing git operations. Supported values: ssh, https 3 | git_protocol: https 4 | # What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment. 5 | editor: 6 | # When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled 7 | prompt: enabled 8 | # A pager program to send command output to, e.g. "less". Set the value to "cat" to disable the pager. 9 | pager: 10 | # Aliases allow you to create nicknames for gh commands 11 | aliases: 12 | whoami: '!gh api graphql -f query="query{viewer{login}}" --jq ".data.viewer.login" | cat' 13 | clone: '!gh-clone ${@}' 14 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/luasnip/store.lua: -------------------------------------------------------------------------------- 1 | local ls = require("luasnip") 2 | local f = ls.function_node 3 | local postfix = require("luasnip.extras.postfix").postfix 4 | 5 | local mod = { 6 | postfix = {}, 7 | } 8 | 9 | mod.postfix.increment = postfix({ 10 | trig = "++", 11 | hidden = true, 12 | }, { 13 | f(function(_, parent) 14 | return string.format("%s = %s + 1", parent.snippet.env.POSTFIX_MATCH, parent.snippet.env.POSTFIX_MATCH) 15 | end, {}), 16 | }) 17 | 18 | mod.postfix.decrement = postfix({ 19 | trig = "--", 20 | hidden = true, 21 | }, { 22 | f(function(_, parent) 23 | return string.format("%s = %s - 1", parent.snippet.env.POSTFIX_MATCH, parent.snippet.env.POSTFIX_MATCH) 24 | end, {}), 25 | }) 26 | 27 | return mod 28 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/custom/init.lua: -------------------------------------------------------------------------------- 1 | local mod = { 2 | format = require("plugins.lsp.custom.format"), 3 | rename = require("plugins.lsp.custom.rename"), 4 | code_action = require("plugins.lsp.custom.code_action"), 5 | } 6 | 7 | ---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' 8 | function mod.document_highlight(offset_encoding) 9 | local params = vim.lsp.util.make_position_params(0, offset_encoding) 10 | vim.lsp.buf_request(0, "textDocument/documentHighlight", params, nil) 11 | end 12 | 13 | ---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' 14 | function mod.hover(offset_encoding) 15 | local params = vim.lsp.util.make_position_params(0, offset_encoding) 16 | vim.lsp.buf_request(0, "textDocument/hover", params, nil) 17 | end 18 | 19 | return mod 20 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/scripts/executable_switch_account.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | folders=$(find ~/.local/share/Mail/ -mindepth 2 -type d -name cur -exec sh -c 'echo $1 | sed "s/^.*Mail\///;s/\/cur.*//"' -- {} \;) 4 | 5 | select_folder() { 6 | local -r title="Select Mail Folder:" 7 | 8 | local folder 9 | 10 | if type "fzf" >/dev/null 2>&1; then 11 | folder=$(echo "${folders}" | fzf --header="${title}" -i --info=hidden --layout=reverse --cycle) 12 | else 13 | PS3="${title} > " 14 | select f in ${folders[@]}; do 15 | folder=${f} 16 | break 17 | done 18 | fi 19 | 20 | 21 | echo "${folder}" 22 | } 23 | 24 | folder=$(select_folder) 25 | 26 | if [ -z "${folder}" ]; then 27 | echo "push !" 28 | else 29 | echo "push =${folder}" 30 | fi 31 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/cellular-automaton.lua: -------------------------------------------------------------------------------- 1 | local u = require("config.utils") 2 | 3 | local plugin = { 4 | "Eandrju/cellular-automaton.nvim", 5 | cmd = "CellularAutomaton", 6 | } 7 | 8 | function plugin.init() 9 | u.set_keymap("n", "fml", "CellularAutomaton make_it_rain", "FML! Make it rain...") 10 | end 11 | 12 | function plugin.config() 13 | local ca = require("cellular-automaton") 14 | 15 | ca.register_animation({ 16 | fps = 50, 17 | name = "slide", 18 | init = function(grid) end, 19 | update = function(grid) 20 | for i = 1, #grid do 21 | local prev = grid[i][#grid[i]] 22 | for j = 1, #grid[i] do 23 | grid[i][j], prev = prev, grid[i][j] 24 | end 25 | end 26 | return true 27 | end, 28 | }) 29 | end 30 | 31 | return plugin 32 | -------------------------------------------------------------------------------- /.modules/fzf.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | current_shell="${current_shell:-"$(ps -p$$ -oucomm= | xargs)"}" 4 | 5 | if [[ -f ~/.config/fzf/fzf.${current_shell} ]]; then 6 | source ~/.config/fzf/fzf.${current_shell} 7 | fi 8 | 9 | export FZF_DEFAULT_OPTS='--color=dark 10 | --color=bg:#1d2021,bg+:#3c3836,fg:#fbf1c7,fg+:#fbf1c7,hl:#d79921,hl+:#d65d0e 11 | --color=gutter:#3c3836,info:#b16286,border:#b16286,prompt:#458588,pointer:#d3869b 12 | --color=marker:#b16286,spinner:#689d6a,header:#458588 13 | --bind ctrl-y:preview-up,ctrl-e:preview-down 14 | --bind ctrl-u:preview-half-page-up,ctrl-d:preview-half-page-down 15 | --bind ctrl-b:preview-page-up,ctrl-f:preview-page-down 16 | ' 17 | 18 | if command_exists fd; then 19 | export FZF_DEFAULT_COMMAND='fd --type f --hidden' 20 | export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" 21 | fi 22 | -------------------------------------------------------------------------------- /private_dot_config/zsh/dot_zshenv: -------------------------------------------------------------------------------- 1 | export XDG_CACHE_HOME="${HOME}/.cache" 2 | export XDG_CONFIG_HOME="${HOME}/.config" 3 | export XDG_DATA_HOME="${HOME}/.local/share" 4 | export XDG_STATE_HOME="${HOME}/.local/state" 5 | 6 | export EDITOR="vim" 7 | export VISUAL="nvim" 8 | export PAGER="less" 9 | export MANPAGER="less -R" 10 | 11 | ZSH_CACHE_DIR="${XDG_CACHE_HOME}/zsh" 12 | ZSH_DATA_DIR="${XDG_DATA_HOME}/zsh" 13 | 14 | export HISTFILE="${ZSH_CACHE_DIR}/history" 15 | HISTSIZE=10000 16 | SAVEHIST=10000 17 | 18 | export CARGO_HOME="${XDG_DATA_HOME}/cargo" 19 | export FNM_DIR="${XDG_DATA_HOME}/fnm" 20 | export GOLANG_DIR="${XDG_DATA_HOME}/golang" 21 | export LUVER_DIR="${XDG_DATA_HOME}/luver" 22 | export PYENV_ROOT="${HOME}/.pyenv" 23 | export RBENV_ROOT="${HOME}/.rbenv" 24 | export RUSTUP_HOME="${XDG_DATA_HOME}/rustup" 25 | 26 | # vim: set filetype=sh : 27 | -------------------------------------------------------------------------------- /.chezmoi.yaml.tmpl: -------------------------------------------------------------------------------- 1 | {{- $is_headless_machine := true -}} 2 | {{- $is_personal_machine := false -}} 3 | {{- $should_include_secrets := false -}} 4 | 5 | {{- $is_github_codespace := empty ( env "CODESPACES" ) | not -}} 6 | 7 | {{- if not $is_github_codespace -}} 8 | {{- $is_headless_machine = promptBool "meta.is.headless_machine" -}} 9 | {{- $is_personal_machine = promptBool "meta.is.personal_machine" -}} 10 | {{- $should_include_secrets = promptBool "meta.should.include_secrets" -}} 11 | {{- end -}} 12 | 13 | sourceDir: {{ .chezmoi.sourceDir }} 14 | 15 | data: 16 | meta: 17 | is: 18 | github_codespace: {{ $is_github_codespace }} 19 | headless_machine: {{ $is_headless_machine }} 20 | personal_machine: {{ $is_personal_machine }} 21 | should: 22 | include_secrets: {{ $should_include_secrets }} 23 | 24 | # vim: set filetype=gotexttmpl.yaml : 25 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/accounts/personal/native-connection.tmpl: -------------------------------------------------------------------------------- 1 | set folder = "imaps://imap.gmail.com:993" 2 | 3 | set imap_authenticators = "oauthbearer" 4 | set imap_user = "{{ template "bitwarden_chezmoi_config" "email.personal" }}" 5 | set imap_oauth_refresh_command = "gmail-oauth2 access_token personal" 6 | 7 | set smtp_url = 'smtps://smtp.gmail.com:465' 8 | set smtp_authenticators = "oauthbearer" 9 | set smtp_user = "{{ template "bitwarden_chezmoi_config" "email.personal" }}" 10 | set smtp_oauth_refresh_command = "gmail-oauth2 access_token personal" 11 | 12 | set spoolfile = "+INBOX" 13 | set mbox = "+[Gmail]/All Mail" 14 | set postponed = "+[Gmail]/Drafts" 15 | set record = "" 16 | set trash = "+[Gmail]/Trash" 17 | 18 | mailboxes $folder 19 | 20 | # vim: filetype=muttrc 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MunifTanjim's dotfiles 2 | 3 | ## Setup 4 | 5 | ```sh 6 | # [READY] setup chezmoi 7 | curl -fsSL https://raw.githubusercontent.com/MunifTanjim/scripts.sh/main/setup-chezmoi | bash 8 | # [SET] initialize 9 | chezmoi init MunifTanjim 10 | # [GO] apply 11 | chezmoi apply 12 | ``` 13 | 14 | ## Notes 15 | 16 | ### macOS Notes 17 | 18 | #### Build with `openssl@1.0` 19 | 20 | Run shell in a clean environment with `DARWIN_OPENSSL_VERSION=1.0`. For example: 21 | 22 | ```sh 23 | env DARWIN_OPENSSL_VERSION=1.0 zsh -i -c 'PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA=openssl@1.0 pyenv install ' 24 | ``` 25 | 26 | _**NOTE**: Not supported on ARM64 (Apple Silicon)._ 27 | 28 | #### Run Command with BSD tools 29 | 30 | ```sh 31 | darwin-no-gnu-run 'npm rebuild --verbose' 32 | ``` 33 | 34 | ## Resources 35 | 36 | - [chezmoi](https://www.chezmoi.io) 37 | - [scripts.sh](https://github.com/MunifTanjim/scripts.sh) 38 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.lsp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "personal-snippets", 3 | "contributes": { 4 | "snippets": [ 5 | { 6 | "language": [ 7 | "all" 8 | ], 9 | "path": "./all.json" 10 | }, 11 | { 12 | "language": [ 13 | "go" 14 | ], 15 | "path": "./go.json" 16 | }, 17 | { 18 | "language": [ 19 | "javascript", 20 | "javascriptreact", 21 | "typescript", 22 | "typescriptreact" 23 | ], 24 | "path": "./javascript.json" 25 | }, 26 | { 27 | "language": [ 28 | "javascriptreact", 29 | "typescriptreact" 30 | ], 31 | "path": "./javascriptreact.json" 32 | }, 33 | { 34 | "language": [ 35 | "lua" 36 | ], 37 | "path": "./lua.json" 38 | } 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /private_dot_config/surfingkeys/config.js: -------------------------------------------------------------------------------- 1 | settings.hintAlign = 'left'; 2 | settings.modeAfterYank = 'Normal'; 3 | settings.omnibarPosition = 'bottom'; 4 | 5 | settings.theme = ` 6 | .sk_theme { 7 | font-family: JetBrainsMono Nerd Font, JetBrainsMono, Ubuntu Mono, monospace; 8 | font-size: 14px; 9 | background: #282828; 10 | color: #ebdbb2; 11 | } 12 | .sk_theme tbody { 13 | color: #b8bb26; 14 | } 15 | .sk_theme input { 16 | color: #d9dce0; 17 | } 18 | .sk_theme .url { 19 | color: #98971a; 20 | } 21 | .sk_theme .annotation { 22 | color: #b16286; 23 | } 24 | .sk_theme .omnibar_highlight { 25 | color: #ebdbb2; 26 | } 27 | .sk_theme #sk_omnibarSearchResult ul li:nth-child(odd) { 28 | background: #282828; 29 | } 30 | .sk_theme #sk_omnibarSearchResult ul li.focused { 31 | background: #d3869b; 32 | } 33 | #sk_status, #sk_find { 34 | font-size: 20pt; 35 | } 36 | `; 37 | 38 | // disable emoji completion 39 | iunmap(':'); 40 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/lightbulb.lua: -------------------------------------------------------------------------------- 1 | vim.fn.sign_define("LightBulbSign", { 2 | text = "󰌶", 3 | texthl = "DiagnosticSignHint", 4 | }) 5 | 6 | local lightbulb = require("nvim-lightbulb") 7 | 8 | lightbulb.setup({ 9 | sign = { 10 | enabled = true, 11 | priority = 10, 12 | }, 13 | }) 14 | 15 | -- disabled because of unusual offset_encoding of `clangd` server causing warning in: 16 | -- https://github.com/neovim/neovim/blob/88c32b5/runtime/lua/vim/lsp/util.lua#L1882-L1886 17 | local is_disabled_filetype = { 18 | c = true, 19 | cpp = true, 20 | } 21 | 22 | vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { 23 | pattern = { "*" }, 24 | group = vim.api.nvim_create_augroup("LightBulb", { clear = true }), 25 | desc = "lua require('nvim-lightbulb').update_lightbulb()", 26 | callback = function(params) 27 | if not is_disabled_filetype[vim.bo[params.buf].filetype] then 28 | lightbulb.update_lightbulb() 29 | end 30 | end, 31 | }) 32 | -------------------------------------------------------------------------------- /dot_inputrc: -------------------------------------------------------------------------------- 1 | # vim: set filetype=readline foldmethod=marker : 2 | 3 | set colored-completion-prefix on 4 | set colored-stats on 5 | set completion-ignore-case on 6 | set completion-map-case on 7 | set echo-control-characters off 8 | set expand-tilde on 9 | set mark-symlinked-directories on 10 | set menu-complete-display-prefix on 11 | set skip-completed-text on 12 | set visible-stats on 13 | 14 | # {{{ vi 15 | set editing-mode vi 16 | set show-mode-in-prompt on 17 | 18 | $if term=linux 19 | set vi-ins-mode-string \1\e[?0c\2 20 | set vi-cmd-mode-string \1\e[?8c\2 21 | $else 22 | set vi-ins-mode-string \1\e[6 q\2 23 | set vi-cmd-mode-string \1\e[2 q\2 24 | $endif 25 | 26 | $if mode=vi 27 | set keymap vi-command 28 | "\e[A": history-search-backward 29 | "\e[B": history-search-forward 30 | j: history-search-forward 31 | k: history-search-backward 32 | 33 | set keymap vi-insert 34 | "\e[A": history-search-backward 35 | "\e[B": history-search-forward 36 | $endif 37 | # vi }}} 38 | -------------------------------------------------------------------------------- /private_dot_config/msmtp/private_config.tmpl: -------------------------------------------------------------------------------- 1 | defaults 2 | auth on 3 | tls on 4 | tls_starttls off 5 | tls_trust_file /etc/ssl/certs/ca-certificates.crt 6 | logfile ~/.cache/msmtp/msmtp.log 7 | 8 | account personal 9 | host smtp.gmail.com 10 | port 465 11 | tls_fingerprint D6:75:EC:30:6C:71:36:35:7E:FA:A3:77:5F:93:B9:6A:C2:06:54:47 12 | auth oauthbearer 13 | user {{ template "bitwarden_chezmoi_config" "email.personal" }} 14 | passwordeval "gmail-oauth2 access_token personal" 15 | from {{ template "bitwarden_chezmoi_config" "email.personal.from" }} 16 | 17 | account shopup 18 | host smtp.gmail.com 19 | port 465 20 | tls_fingerprint D6:75:EC:30:6C:71:36:35:7E:FA:A3:77:5F:93:B9:6A:C2:06:54:47 21 | auth oauthbearer 22 | user {{ template "bitwarden_chezmoi_config" "email.shopup" }} 23 | passwordeval "gmail-oauth2 access_token {{ template "bitwarden_chezmoi_config" "email.shopup" }}" 24 | from {{ template "bitwarden_chezmoi_config" "email.shopup" }} 25 | 26 | account default : personal 27 | 28 | # vim: filetype=msmtp 29 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | local lazy_path = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 2 | 3 | if not vim.loop.fs_stat(lazy_path) then 4 | vim.fn.system({ 5 | "git", 6 | "clone", 7 | "--filter=blob:none", 8 | "https://github.com/folke/lazy.nvim.git", 9 | "--branch=stable", 10 | lazy_path, 11 | }) 12 | end 13 | 14 | vim.opt.runtimepath:prepend(lazy_path) 15 | 16 | require("lazy").setup("plugins", { 17 | checker = { 18 | enabled = true, 19 | concurrency = 8, 20 | frequency = 24 * 60 * 60, -- 24h 21 | notify = false, 22 | }, 23 | concurrency = 8, 24 | dev = { 25 | fallback = true, 26 | }, 27 | performance = { 28 | rtp = { 29 | disabled_plugins = { 30 | "gzip", 31 | "matchit", 32 | "matchparen", 33 | "netrwPlugin", 34 | "tarPlugin", 35 | "tohtml", 36 | "tutor", 37 | "zipPlugin", 38 | }, 39 | }, 40 | }, 41 | ui = { 42 | border = "rounded", 43 | }, 44 | }) 45 | -------------------------------------------------------------------------------- /private_dot_config/alacritty/alacritty.toml.tmpl: -------------------------------------------------------------------------------- 1 | [general] 2 | import = [ 3 | "~/.config/alacritty/colors.gruvbox_dark.toml", 4 | "~/.config/alacritty/{{ .chezmoi.os }}.toml" 5 | ] 6 | live_config_reload = true 7 | 8 | [colors] 9 | draw_bold_text_with_bright_colors = false 10 | 11 | [cursor] 12 | blink_interval = 500 13 | blink_timeout = 5 14 | unfocused_hollow = true 15 | 16 | [cursor.style] 17 | blinking = "Off" 18 | shape = "Block" 19 | 20 | [env] 21 | TERM = "xterm-256color" 22 | 23 | [font.normal] 24 | family = "JetBrainsMono Nerd Font Mono" 25 | style = "Regular" 26 | 27 | [scrolling] 28 | history = 100000 29 | multiplier = 3 30 | 31 | [selection] 32 | save_to_clipboard = true 33 | 34 | [terminal.shell] 35 | args = ["-l", "-c", "tmux attach || tmux"] 36 | program = "{{ env "SHELL" }}" 37 | 38 | [window] 39 | dynamic_padding = true 40 | dynamic_title = true 41 | opacity = 1.0 42 | startup_mode = "Maximized" 43 | 44 | [window.dimensions] 45 | columns = 120 46 | lines = 40 47 | 48 | # vim: set filetype=toml.gotexttmpl foldmethod=indent : 49 | -------------------------------------------------------------------------------- /private_dot_config/alacritty/colors.gruvbox_dark.toml: -------------------------------------------------------------------------------- 1 | [colors.primary] 2 | background = "#1d2021" 3 | bright_foreground = "#fbf1c7" 4 | dim_foreground = "#a89984" 5 | foreground = "#ebdbb2" 6 | 7 | [colors.cursor] 8 | cursor = "CellForeground" 9 | text = "CellBackground" 10 | 11 | [colors.vi_mode_cursor] 12 | cursor = "CellForeground" 13 | text = "CellBackground" 14 | 15 | [colors.selection] 16 | background = "CellForeground" 17 | text = "CellBackground" 18 | 19 | [colors.bright] 20 | black = "#7c6f64" 21 | blue = "#83a598" 22 | cyan = "#8ec07c" 23 | green = "#b8bb26" 24 | magenta = "#d3869b" 25 | red = "#fb4934" 26 | white = "#f9f5d7" 27 | yellow = "#fabd2f" 28 | 29 | [colors.normal] 30 | black = "#3c3836" 31 | blue = "#458588" 32 | cyan = "#689d6a" 33 | green = "#98971a" 34 | magenta = "#b16286" 35 | red = "#cc241d" 36 | white = "#fbf1c7" 37 | yellow = "#d79921" 38 | 39 | [colors.dim] 40 | black = "#282828" 41 | blue = "#076678" 42 | cyan = "#427b58" 43 | green = "#79740e" 44 | magenta = "#8f3f71" 45 | red = "#9d0006" 46 | white = "#a89984" 47 | yellow = "#b57614" 48 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/custom/format.lua: -------------------------------------------------------------------------------- 1 | local denylist = { 2 | clangd = true, 3 | html = true, 4 | jsonls = true, 5 | pyright = true, 6 | vtsls = true, 7 | stylelint_lsp = true, 8 | } 9 | 10 | local denylist_by_filetype = { 11 | lua = { 12 | lua_ls = true, 13 | }, 14 | } 15 | 16 | local function get_filter(bufnr) 17 | return function(client) 18 | if denylist[client.name] then 19 | return false 20 | end 21 | 22 | local filetype = vim.api.nvim_get_option_value("filetype", { buf = bufnr or 0 }) 23 | local denylist_for_filetype = denylist_by_filetype[filetype] 24 | if not denylist_for_filetype then 25 | return true 26 | end 27 | 28 | return not denylist_for_filetype[client.name] 29 | end 30 | end 31 | 32 | ---@param options? vim.lsp.buf.format.Opts 33 | local function format(options) 34 | options = options or {} 35 | options.bufnr = options.bufnr or vim.api.nvim_get_current_buf() 36 | options.filter = get_filter(options.bufnr) 37 | vim.lsp.buf.format(options) 38 | end 39 | 40 | return format 41 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/copilot.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "zbirenbaum/copilot.lua", 3 | cmd = "Copilot", 4 | event = "InsertEnter", 5 | } 6 | 7 | function plugin.config() 8 | local u = require("config.utils") 9 | 10 | require("copilot").setup({ 11 | panel = { 12 | auto_refresh = false, 13 | keymap = { 14 | accept = "", 15 | jump_prev = "[[", 16 | jump_next = "]]", 17 | refresh = "gr", 18 | open = "", 19 | }, 20 | }, 21 | suggestion = { 22 | auto_trigger = false, 23 | keymap = { 24 | accept = false, 25 | accept_word = "", 26 | accept_line = "", 27 | prev = "", 28 | next = "", 29 | dismiss = false, 30 | }, 31 | }, 32 | }) 33 | 34 | local suggestion = require("copilot.suggestion") 35 | 36 | u.set_keymap("i", "", function() 37 | if suggestion.is_visible() then 38 | suggestion.accept() 39 | else 40 | suggestion.next() 41 | end 42 | end, "[copilot] accept or next suggestion") 43 | end 44 | 45 | return plugin 46 | -------------------------------------------------------------------------------- /.modules/zsh/plugins/os.darwin/generate.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=zsh 2 | 3 | __generated_file="$(dirname $(realpath $0))/os.darwin.plugin.zsh" 4 | 5 | rm -f "${__generated_file}" 6 | touch "${__generated_file}" 7 | 8 | if test "$(uname -m)" != "arm64"; then 9 | exit 0 10 | fi 11 | 12 | homebrew_setup_on_arm64() { 13 | local -r marker_start=" ## {{{ start: homebrew on arm64" 14 | local -r marker_end=" ## end: homebrew on arm64 }}}" 15 | 16 | sed -e "/${marker_start}/,/${marker_end}/{//!d;}" -i -- "${__generated_file}" 17 | 18 | local -r homebrew="/opt/homebrew/bin/brew" 19 | 20 | local marker_start_linenr=$(($(sed -n "/${marker_start}/=" "${__generated_file}"))) 21 | 22 | local content="$({ 23 | head -n $((marker_start_linenr)) "${__generated_file}" 24 | echo "$( 25 | env -u MANPATH $homebrew shellenv | sed 's/^/ /' 26 | )" 27 | tail -n +$((marker_start_linenr + 1)) ${__generated_file} 28 | })" 29 | 30 | echo "${content}" >"${__generated_file}" 31 | } 32 | 33 | cat "${DOTFILES_MODULES}/os.darwin.plugin.sh" >"${__generated_file}" 34 | 35 | homebrew_setup_on_arm64 36 | 37 | unset __generated_file 38 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/nougat/color/gruvbox.lua: -------------------------------------------------------------------------------- 1 | local color = require("config.color").dark 2 | 3 | local mod = {} 4 | 5 | function mod.get() 6 | ---@class nougat.color.gruvbox: nougat.color 7 | local gruvbox = { 8 | red = color.red, 9 | green = color.green, 10 | yellow = color.yellow, 11 | blue = color.blue, 12 | magenta = color.purple, 13 | cyan = color.aqua, 14 | 15 | orange = color.orange, 16 | 17 | bg = color.bg, 18 | bg0 = color.bg0, 19 | bg1 = color.bg1, 20 | bg2 = color.bg2, 21 | bg3 = color.bg3, 22 | bg4 = color.bg4, 23 | 24 | fg = color.fg, 25 | fg0 = color.fg0, 26 | fg1 = color.fg1, 27 | fg2 = color.fg2, 28 | fg3 = color.fg3, 29 | fg4 = color.fg4, 30 | 31 | accent = { 32 | red = color.accent.red, 33 | green = color.accent.green, 34 | yellow = color.accent.yellow, 35 | blue = color.accent.blue, 36 | magenta = color.accent.purple, 37 | cyan = color.accent.aqua, 38 | 39 | orange = color.accent.orange, 40 | 41 | bg = color.gray, 42 | fg = color.lightgray, 43 | }, 44 | } 45 | 46 | return gruvbox 47 | end 48 | 49 | return mod 50 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/accounts/shopup/config.tmpl: -------------------------------------------------------------------------------- 1 | set folder = "~/.local/share/Mail" 2 | 3 | set sendmail = "msmtp -a shopup" 4 | 5 | set spoolfile = "+shopup/Inbox" 6 | set mbox = "+shopup/Archive" 7 | set postponed = "+shopup/Drafts" 8 | set record = "+shopup/Sent" 9 | set trash = "+shopup/Trash" 10 | 11 | unmailboxes * 12 | mailboxes =shopup/Inbox =shopup/Starred 13 | mailboxes =shopup/Sent =shopup/Drafts 14 | mailboxes =shopup/Trash =shopup/Archive 15 | mailboxes =shopup/Spam 16 | 17 | set realname = "Munif Tanjim" 18 | set from = "{{ template "bitwarden_chezmoi_config" "email.shopup" }}" 19 | alternates {{ template "bitwarden_chezmoi_config" "email.shopup.mutt.alternates" }} 20 | 21 | set signature = "~/.config/neomutt/signatures/shopup" 22 | 23 | set copy = no 24 | set delete = yes 25 | set move = no 26 | 27 | macro index gu "mbsync shopup" "run mbsync to sync mail for this account" 28 | 29 | macro index,pager mA "+shopup/Archive" "move message to the archive" 30 | macro index,pager mI "+shopup/Inbox" "move message to the inbox" 31 | 32 | color status cyan default 33 | 34 | # vim: filetype=muttrc 35 | -------------------------------------------------------------------------------- /private_dot_config/bat/config: -------------------------------------------------------------------------------- 1 | # This is `bat`s configuration file. Each line either contains a comment or 2 | # a command-line option that you want to pass to `bat` by default. You can 3 | # run `bat --help` to get a list of all possible configuration options. 4 | 5 | # Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes` 6 | # for a list of all available themes 7 | --theme="gruvbox-dark" 8 | 9 | # Enable this to use italic text on the terminal. This is not supported on all 10 | # terminal emulators (like tmux, by default): 11 | --italic-text=always 12 | 13 | # Uncomment the following line to disable automatic paging: 14 | #--paging=never 15 | 16 | # Uncomment the following line if you are using less version >= 551 and want to 17 | # enable mouse scrolling support in `bat` when running inside tmux. This might 18 | # disable text selection, unless you press shift. 19 | #--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse" 20 | 21 | # Syntax mappings: map a certain filename pattern to a language. 22 | # Example 1: use the C++ syntax for .ino files 23 | # Example 2: Use ".gitignore"-style highlighting for ".ignore" files 24 | #--map-syntax "*.ino:C++" 25 | #--map-syntax ".ignore:Git Ignore" 26 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/accounts/personal/config.tmpl: -------------------------------------------------------------------------------- 1 | set folder = "~/.local/share/Mail" 2 | 3 | set sendmail = "echo msmtp -a personal" 4 | 5 | set spoolfile = "+personal/Inbox" 6 | set mbox = "+personal/Archive" 7 | set postponed = "+personal/Drafts" 8 | set record = "+personal/Sent" 9 | set trash = "+personal/Trash" 10 | 11 | unmailboxes * 12 | mailboxes =personal/Inbox =personal/Starred 13 | mailboxes =personal/Sent =personal/Drafts 14 | mailboxes =personal/Trash =personal/Archive 15 | mailboxes =personal/Spam 16 | 17 | set realname = "Munif Tanjim" 18 | set from = "{{ template "bitwarden_chezmoi_config" "email.personal.from" }}" 19 | alternates {{ template "bitwarden_chezmoi_config" "email.personal.mutt.alternates" }} 20 | 21 | set signature = "~/.config/neomutt/signatures/personal" 22 | 23 | set copy = no 24 | set delete = yes 25 | set move = no 26 | 27 | macro index gu "mbsync personal" "run mbsync to sync mail for this account" 28 | 29 | macro index,pager mA "+personal/Archive" "move message to the archive" 30 | macro index,pager mI "+personal/Inbox" "move message to the inbox" 31 | 32 | color status cyan default 33 | 34 | # vim: filetype=muttrc 35 | -------------------------------------------------------------------------------- /private_dot_config/hammerspoon/config-loader.lua: -------------------------------------------------------------------------------- 1 | local mod = {} 2 | mod.__index = mod 3 | 4 | mod.name = "ConfigLoader" 5 | mod.version = "0.0.0" 6 | mod.author = "Munif Tanjim" 7 | mod.homepage = "" 8 | mod.license = "MIT (https://opensource.org/licenses/MIT)" 9 | 10 | mod.logger = hs.logger.new(mod.name) 11 | 12 | function mod.reload() 13 | hs.notify.new({ title = "Hammerspoon", informativeText = "Reloading Config...", withdrawAfter = 1 }):send() 14 | hs.timer.doAfter(1, hs.reload) 15 | end 16 | 17 | local watcher = hs.pathwatcher.new(hs.configdir, function(paths) 18 | for _, path in ipairs(paths) do 19 | if path:sub(-4) == ".lua" then 20 | mod.reload() 21 | break 22 | end 23 | end 24 | end) 25 | 26 | function mod:bindHotkeys(mapping) 27 | local spec = { 28 | reload = mod.reload, 29 | } 30 | hs.spoons.bindHotkeysToSpec(spec, mapping) 31 | return self 32 | end 33 | 34 | function mod:start() 35 | self.logger.d("starting pathwatcher") 36 | watcher:start() 37 | return self 38 | end 39 | 40 | function mod:stop() 41 | self.logger.d("stopping pathwatcher") 42 | watcher:stop() 43 | return self 44 | end 45 | 46 | function mod:init() 47 | self.logger.i("Loading " .. self.name) 48 | end 49 | 50 | return mod 51 | -------------------------------------------------------------------------------- /.chezmoiscripts/.10_init.darwin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | CHEZMOI_SOURCE="${HOME}/.local/share/chezmoi" 6 | source "${CHEZMOI_SOURCE}/.chezmoiscripts/.00_helpers.sh" 7 | 8 | ensure_command_line_tools() { 9 | if ! xcode-select -p >/dev/null 2>&1 || ! test -f "$(xcode-select -p)/usr/bin/git"; then 10 | echo "installing command line tools" 11 | xcode-select --install 12 | fi 13 | 14 | if is_arm64; then 15 | if ! arch -x86_64 /usr/bin/true 2>/dev/null; then 16 | echo "installing rosetta" 17 | /usr/sbin/softwareupdate --install-rosetta --agree-to-license 18 | fi 19 | fi 20 | } 21 | 22 | ensure_homebrew() { 23 | if ! command_exists brew; then 24 | echo "installing homebrew" 25 | bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 26 | fi 27 | 28 | if is_arm64; then 29 | local homebrew_bin="/opt/homebrew/bin" 30 | if ! cat /etc/paths | grep -q "${homebrew_bin}"; then 31 | echo "setting up homebrew binary path for gui apps" 32 | echo -e "${homebrew_bin}\n$(cat /etc/paths)" | sudo tee /etc/paths >/dev/null 33 | fi 34 | fi 35 | } 36 | 37 | ensure_darwin 38 | ask_sudo 39 | 40 | ensure_command_line_tools 41 | ensure_homebrew 42 | ensure_secret_manager 43 | -------------------------------------------------------------------------------- /dot_nanorc: -------------------------------------------------------------------------------- 1 | # set quiet 2 | set autoindent 3 | set backup 4 | set backupdir "~/.cache/nano/backup" 5 | # set backwards 6 | # set boldtext 7 | # set brackets ""')>]}" 8 | # set casesensitive 9 | # set constantshow 10 | # set cut 11 | # set fill -8 12 | set historylog 13 | # set justifytrim 14 | # set matchbrackets "(<[{)>]}" 15 | # set morespace 16 | # set mouse 17 | # set multibuffer 18 | # set noconvert 19 | # set nohelp 20 | # set nonewlines 21 | set nowrap 22 | # set operatingdir "" 23 | # set positionlog 24 | # set preserve 25 | # set punct "!.?" 26 | # set quickblank 27 | # set quotestr "^([ ]*[#:>\|}])+" 28 | # set quotestr "> " 29 | # set rebinddelete 30 | # set rebindkeypad 31 | # set regexp 32 | # set smarthome 33 | # set smooth 34 | set softwrap 35 | # set speller "aspell -x -c" 36 | set suspend 37 | set tabsize 2 38 | # set tabstospaces 39 | # set tempfile 40 | # set view 41 | # set whitespace "»·" 42 | # set whitespace ">." 43 | # set wordbounds 44 | # set wordchars "<_>." 45 | # set titlecolor brightwhite,blue 46 | # set statuscolor brightwhite,green 47 | # set keycolor green 48 | # set functioncolor yellow 49 | # bind ^S savefile main 50 | # bind M-Q findprevious main 51 | # bind M-W findnext main 52 | # bind M-B cutwordleft main 53 | # bind M-N cutwordright main 54 | # bind Del backspace all 55 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/flash.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "folke/flash.nvim", 3 | event = "VeryLazy", 4 | ---@type Flash.Config 5 | opts = { 6 | highlight = { 7 | backdrop = false, 8 | }, 9 | label = { 10 | style = "eol", 11 | }, 12 | modes = { 13 | char = { 14 | highlight = { 15 | backdrop = false, 16 | groups = { 17 | label = "FlashMatch", 18 | }, 19 | }, 20 | }, 21 | search = { 22 | enabled = false, 23 | }, 24 | }, 25 | }, 26 | config = function(_, opts) 27 | require("flash").setup(opts) 28 | 29 | local augroup = vim.api.nvim_create_augroup("plugins.flash", { clear = true }) 30 | 31 | vim.api.nvim_create_autocmd("CmdlineLeave", { 32 | group = augroup, 33 | pattern = "/", 34 | callback = function() 35 | require("flash").toggle(false) 36 | end, 37 | }) 38 | end, 39 | keys = { 40 | { 41 | "", 42 | mode = { "n", "x", "o" }, 43 | function() 44 | require("flash").jump() 45 | end, 46 | desc = "[flash] search", 47 | }, 48 | { 49 | "", 50 | mode = { "c" }, 51 | function() 52 | require("flash").toggle() 53 | end, 54 | desc = "[flash] toggle search", 55 | }, 56 | }, 57 | } 58 | 59 | return plugin 60 | -------------------------------------------------------------------------------- /private_dot_config/hammerspoon/utils.lua: -------------------------------------------------------------------------------- 1 | local mod = {} 2 | 3 | function mod.ensure_spoon_installer() 4 | local function exec(cmd, failure_message) 5 | local stdout, ok = hs.execute(cmd) 6 | if ok then 7 | return string.gsub(stdout, "\n*$", "") 8 | end 9 | error(failure_message) 10 | end 11 | 12 | local spoons_dir = hs.configdir .. "/Spoons" 13 | 14 | if not hs.fs.attributes(table.concat({ spoons_dir, "SpoonInstall.spoon" }, "/")) then 15 | local tmpdir = exec("mktemp -d -t hammerspoon-XXX", "failed to create temporary directory") 16 | 17 | local archive_filename = "SpoonInstall.spoon.zip" 18 | local archive_url = "https://github.com/Hammerspoon/Spoons/raw/master/Spoons/" .. archive_filename 19 | local archive_path = table.concat({ tmpdir, archive_filename }) 20 | 21 | local status, body = hs.http.get(archive_url) 22 | if status >= 400 then 23 | error("failed to download: " .. archive_url) 24 | end 25 | 26 | local file = assert(io.open(archive_path, "w")) 27 | file:write(body) 28 | file:close() 29 | 30 | exec(string.format("unzip -o %s -d %s 2>&1", archive_path, spoons_dir), "failed to extract: " .. archive_path) 31 | exec(string.format("rm -rf '%s'", tmpdir), "failed to cleanup: " .. tmpdir) 32 | 33 | print("successfully installed: SpoonInstall.spoon") 34 | end 35 | 36 | hs.loadSpoon("SpoonInstall") 37 | end 38 | 39 | return mod 40 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/autopairs.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "windwp/nvim-autopairs", 3 | event = "InsertEnter", 4 | dependencies = { 5 | "hrsh7th/nvim-cmp", 6 | }, 7 | } 8 | 9 | function plugin.config() 10 | local autopairs = require("nvim-autopairs") 11 | 12 | autopairs.setup({ 13 | enable_check_bracket_line = false, 14 | }) 15 | 16 | local cmp = require("cmp") 17 | local cmp_autopairs = require("nvim-autopairs.completion.cmp") 18 | local ts_utils = require("nvim-treesitter.ts_utils") 19 | 20 | local ts_node_func_parens_disabled = { 21 | -- ecma 22 | named_imports = true, 23 | export_clause = true, 24 | -- rust 25 | use_declaration = true, 26 | } 27 | 28 | local default_handler = cmp_autopairs.filetypes["*"]["("].handler 29 | cmp_autopairs.filetypes["*"]["("].handler = function(char, item, bufnr, rules, commit_character) 30 | local node_type = ts_utils.get_node_at_cursor():type() 31 | if ts_node_func_parens_disabled[node_type] then 32 | if item.data then 33 | item.data.funcParensDisabled = true 34 | else 35 | char = "" 36 | end 37 | end 38 | default_handler(char, item, bufnr, rules, commit_character) 39 | end 40 | 41 | cmp.event:on( 42 | "confirm_done", 43 | cmp_autopairs.on_confirm_done({ 44 | filetypes = { 45 | sh = false, 46 | }, 47 | }) 48 | ) 49 | end 50 | 51 | return plugin 52 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/colors: -------------------------------------------------------------------------------- 1 | # from: https://github.com/sheoak/neomutt-powerline-nerdfonts 2 | 3 | # cancel theme colors 4 | color index color223 color234 ~Q 5 | color index color223 color234 ~P 6 | color index color223 color234 ~T 7 | color index color223 color234 ~O 8 | color index color223 color234 ~F 9 | color index color223 color234 ~N 10 | 11 | # add some nice custom coloring to the message list 12 | # thanks to new neomutt features 13 | # http://www.mutt.org/doc/manual/#patterns 14 | # https://neomutt.org/feature/index-color 15 | color index_subject color109 color234 "~P !~T !~D" 16 | color index_author color109 color234 "~P !~T !~D" 17 | color index_subject color243 color234 "~Q !~T !~D" 18 | color index_author color243 color234 "~Q !~T !~D" 19 | color index_subject brightcolor142 color234 "~N !~T !~D" 20 | color index_author brightcolor142 color234 "~N !~T !~D" 21 | color index_subject color142 color234 "~O !~T !~D" 22 | color index_author color142 color234 "~O !~T !~D" 23 | color index_subject color214 color234 "~F !~T !~D" 24 | color index_author color214 color234 "~F !~T !~D" 25 | color index_subject brightcolor214 color234 "~F ~N !~T !~D" 26 | color index_author brightcolor214 color234 "~F ~N !~T !~D" 27 | color index_subject color167 color234 "~= !~T !~D" 28 | color index_author color167 color234 "~= !~T !~D" 29 | color index_subject brightcolor109 color234 "~P ~N !~T !~D" 30 | color index_author brightcolor109 color234 "~P ~N !~T !~D" 31 | color index color234 color223 "~T" 32 | color index color229 color124 "~D" 33 | 34 | # vim: filetype=muttrc 35 | -------------------------------------------------------------------------------- /private_dot_config/lf/executable_previewer: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euf 4 | 5 | declare ft 6 | declare f="${1}" 7 | declare w="${2}" 8 | declare h="${3}" 9 | declare x="${4}" 10 | declare y="${5}" 11 | 12 | command_exists() { 13 | type "${1}" >/dev/null 2>&1 14 | } 15 | 16 | has_kitty_protocol() { 17 | test -z "${TMUX:-}" && test -n "${KITTY_PID:-}" 18 | } 19 | 20 | preview_image() { 21 | if has_kitty_protocol; then 22 | kitty +kitten icat --silent --stdin no --transfer-mode file --place "${w}x${h}@${x}x${y}" "${f}" < /dev/null > /dev/tty 23 | exit 1 24 | fi 25 | 26 | case "${f}" in 27 | *.jpg|*.jpeg|*.png) 28 | if command_exists chafa; then 29 | chafa --colors=256 "${f}" 30 | elif command_exists viu; then 31 | echo viu -w "${w}" "${f}" 32 | fi 33 | ;; 34 | esac 35 | } 36 | 37 | preview_video() { 38 | echo "Not Implemented!" 39 | # if has_kitty_protocol; then 40 | # kitty +icat --silent --transfer-mode file --place "${w}x${h}@${x}x${y}" "$(thumbnailer "$f")" 41 | # exit 1 42 | # fi 43 | } 44 | 45 | case "${f}" in 46 | *.tar*) 47 | tar tf "${f}" 48 | ;; 49 | *.zip) 50 | unzip -l "${f}" 51 | ;; 52 | *.rar) 53 | unrar l "${f}" 54 | ;; 55 | *.7z) 56 | 7z l -p "${f}" 57 | ;; 58 | *.pdf) 59 | pdftotext "${f}" - 60 | ;; 61 | *) 62 | ft="$(file -Lb --mime-type "$f")" 63 | if [[ "${ft}" =~ ^image ]]; then 64 | preview_image 65 | elif [[ "${ft}" =~ ^video ]]; then 66 | preview_video 67 | else 68 | unset COLORTERM 69 | bat --color=always --line-range=0:"${w}" --paging=never --plain "${f}" 70 | fi 71 | ;; 72 | esac 73 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/treesitter/init.lua: -------------------------------------------------------------------------------- 1 | local u = require("config.utils") 2 | 3 | local plugins = { 4 | { 5 | "nvim-treesitter/playground", 6 | cmd = { "TSPlaygroundToggle", "TSHighlightCapturesUnderCursor" }, 7 | init = function() 8 | u.set_keymaps("n", { 9 | { 10 | "ghg", 11 | "TSHighlightCapturesUnderCursor", 12 | "[treesitter] show hl captures", 13 | }, 14 | { 15 | "gtr", 16 | "TSPlaygroundToggle", 17 | "[treesitter] toggle playground", 18 | }, 19 | }) 20 | end, 21 | }, 22 | { 23 | "nvim-treesitter/nvim-treesitter", 24 | build = ":TSUpdate", 25 | dependencies = { 26 | "nvim-treesitter/nvim-treesitter-textobjects", 27 | "RRethy/nvim-treesitter-textsubjects", 28 | }, 29 | event = "BufReadPost", 30 | config = function() 31 | require("plugins.treesitter.base") 32 | end, 33 | }, 34 | { 35 | "nvim-treesitter/nvim-treesitter-context", 36 | event = "BufReadPost", 37 | config = function() 38 | require("plugins.treesitter.context") 39 | end, 40 | }, 41 | { 42 | "numToStr/Comment.nvim", 43 | event = "BufReadPost", 44 | dependencies = { 45 | { 46 | "JoosepAlviste/nvim-ts-context-commentstring", 47 | opts = { 48 | enable_autocmd = false, 49 | }, 50 | }, 51 | }, 52 | config = function() 53 | require("plugins.treesitter.comment") 54 | end, 55 | }, 56 | { 57 | "windwp/nvim-ts-autotag", 58 | event = { "BufReadPre", "BufNewFile" }, 59 | opts = {}, 60 | }, 61 | } 62 | 63 | return plugins 64 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/gitlinker.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | -- "ruifm/gitlinker.nvim", 3 | "MunifTanjim/gitlinker.nvim", 4 | branch = "patched", 5 | dependencies = { 6 | "nvim-lua/plenary.nvim", 7 | }, 8 | event = "BufReadPost", 9 | } 10 | function plugin.config() 11 | local function detect_git_remote() 12 | local gh_default_repo = vim.fn.system({ 13 | "gh", 14 | "repo", 15 | "view", 16 | "--json=nameWithOwner", 17 | "--template={{.nameWithOwner}}", 18 | }) 19 | 20 | local remotes = vim.fn.systemlist({ "git", "remote", "-v" }) 21 | for _, remote in ipairs(remotes) do 22 | local name, url = string.match(remote, "(.+)\t(.+) %((.+)%)") 23 | if string.find(url, gh_default_repo, 1, true) then 24 | return name 25 | end 26 | end 27 | end 28 | 29 | local function get_remote() 30 | local remote = vim.t.gitlinker_remote_override 31 | if remote == nil then 32 | local ok, value = pcall(detect_git_remote) 33 | remote = ok and value or false 34 | vim.t.gitlinker_remote_override = remote 35 | end 36 | return remote 37 | end 38 | 39 | require("gitlinker").setup({ 40 | opts = { 41 | mappings = false, 42 | remote = get_remote, 43 | }, 44 | }) 45 | 46 | require("config.utils").set_keymaps("n", { 47 | { 48 | "gy", 49 | function() 50 | require("gitlinker").get_buf_range_url("n") 51 | end, 52 | "[git] generate file link", 53 | }, 54 | { 55 | "gy", 56 | function() 57 | require("gitlinker").get_buf_range_url("v") 58 | end, 59 | "[git] generate file link", 60 | mode = "v", 61 | }, 62 | }) 63 | end 64 | 65 | return plugin 66 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/treesitter/base.lua: -------------------------------------------------------------------------------- 1 | local treesitter_configs = require("nvim-treesitter.configs") 2 | 3 | local parser_config = require("nvim-treesitter.parsers").get_parser_configs() 4 | 5 | -- disable treesitter for zsh 6 | parser_config.zsh = { 7 | install_info = {}, 8 | used_by = {}, 9 | maintainers = {}, 10 | } 11 | 12 | treesitter_configs.setup({ 13 | ensure_installed = { 14 | "comment", 15 | "css", 16 | "go", 17 | "graphql", 18 | "html", 19 | "javascript", 20 | "jsdoc", 21 | "json", 22 | "jsonc", 23 | "lua", 24 | "markdown", 25 | "markdown_inline", 26 | "python", 27 | "query", 28 | "regex", 29 | "ruby", 30 | "rust", 31 | "scss", 32 | "toml", 33 | "tsx", 34 | "typescript", 35 | "vim", 36 | "vimdoc", 37 | "yaml", 38 | }, 39 | highlight = { 40 | enable = true, 41 | }, 42 | indent = { 43 | enable = true, 44 | disable = { "yaml" }, 45 | }, 46 | matchup = { 47 | enable = true, 48 | include_match_words = true, 49 | }, 50 | playground = { 51 | enable = true, 52 | }, 53 | textobjects = { 54 | select = { 55 | enable = true, 56 | lookahead = true, 57 | keymaps = { 58 | ["af"] = "@function.outer", 59 | ["if"] = "@function.inner", 60 | ["ac"] = "@class.outer", 61 | ["ic"] = "@class.inner", 62 | }, 63 | }, 64 | }, 65 | textsubjects = { 66 | enable = true, 67 | keymaps = { 68 | ["."] = "textsubjects-smart", 69 | }, 70 | }, 71 | }) 72 | 73 | vim.cmd([[ 74 | autocmd FileType css,go,html,javascript,javascriptreact,json,lua,python,ruby,rust,toml,typescript,typescriptreact,yaml 75 | \ set foldmethod=expr foldexpr=nvim_treesitter#foldexpr() 76 | ]]) 77 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/git.lua: -------------------------------------------------------------------------------- 1 | local plugin_gitsigns = { 2 | "lewis6991/gitsigns.nvim", 3 | event = "BufReadPre", 4 | dependencies = { 5 | "nvim-lua/plenary.nvim", 6 | }, 7 | } 8 | 9 | function plugin_gitsigns.config() 10 | local u = require("config.utils") 11 | local gitsigns = require("gitsigns") 12 | 13 | gitsigns.setup({ 14 | signs = { 15 | add = { text = "▎" }, 16 | change = { text = "▎" }, 17 | delete = { text = "▁" }, 18 | topdelete = { text = "▔" }, 19 | changedelete = { text = "▎" }, 20 | }, 21 | on_attach = function(bufnr) 22 | u.set_keymaps("n", { 23 | { 24 | "[c", 25 | function() 26 | if vim.wo.diff then 27 | return "[c" 28 | end 29 | 30 | vim.schedule(function() 31 | gitsigns.prev_hunk() 32 | end) 33 | 34 | return "" 35 | end, 36 | "[git] prev change", 37 | }, 38 | { 39 | "]c", 40 | function() 41 | if vim.wo.diff then 42 | return "]c" 43 | end 44 | 45 | vim.schedule(function() 46 | gitsigns.next_hunk() 47 | end) 48 | 49 | return "" 50 | end, 51 | "[git] next change", 52 | }, 53 | }, { 54 | buffer = bufnr, 55 | expr = true, 56 | }) 57 | 58 | u.set_keymap("v", "gs", "Gitsigns stage_hunk", { 59 | buffer = bufnr, 60 | desc = "[git] stage change", 61 | }) 62 | end, 63 | }) 64 | end 65 | 66 | local plugins = { 67 | plugin_gitsigns, 68 | { "rhysd/git-messenger.vim" }, 69 | { "tpope/vim-fugitive" }, 70 | } 71 | 72 | return plugins 73 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/dap/javascript.lua: -------------------------------------------------------------------------------- 1 | local dap = require("dap") 2 | 3 | -- https://github.com/microsoft/vscode-node-debug2 4 | dap.adapters.node2 = { 5 | type = "executable", 6 | command = "node", 7 | args = { vim.fn.stdpath("data") .. "/mason/packages/node-debug2-adapter/out/src/nodeDebug.js" }, 8 | } 9 | 10 | -- https://github.com/Microsoft/vscode-chrome-debug 11 | dap.adapters.chrome = { 12 | type = "executable", 13 | command = "node", 14 | args = { vim.fn.stdpath("data") .. "/mason/packages/chrome-debug-adapter/out/src/chromeDebug.js" }, 15 | } 16 | 17 | dap.configurations.javascript = { 18 | { 19 | name = "Launch", 20 | type = "node2", 21 | request = "launch", 22 | program = "${file}", 23 | cwd = vim.fn.getcwd(), 24 | sourceMaps = true, 25 | protocol = "inspector", 26 | console = "integratedTerminal", 27 | }, 28 | { 29 | -- For this to work you need to make sure the node process is started with the `--inspect` flag. 30 | name = "Attach to process", 31 | type = "node2", 32 | request = "attach", 33 | processId = require("dap.utils").pick_process, 34 | }, 35 | } 36 | 37 | dap.configurations.javascriptreact = { -- change this to javascript if needed 38 | { 39 | type = "chrome", 40 | request = "attach", 41 | program = "${file}", 42 | cwd = vim.fn.getcwd(), 43 | sourceMaps = true, 44 | protocol = "inspector", 45 | port = 9222, 46 | webRoot = "${workspaceFolder}", 47 | }, 48 | } 49 | 50 | dap.configurations.typescriptreact = { -- change to typescript if needed 51 | { 52 | type = "chrome", 53 | request = "attach", 54 | program = "${file}", 55 | cwd = vim.fn.getcwd(), 56 | sourceMaps = true, 57 | protocol = "inspector", 58 | port = 9222, 59 | webRoot = "${workspaceFolder}", 60 | }, 61 | } 62 | -------------------------------------------------------------------------------- /private_dot_config/hammerspoon/init.lua: -------------------------------------------------------------------------------- 1 | -- Need to run the following command for Hammerspoon to use this config file 2 | -- $ defaults write org.hammerspoon.hammerspoon MJConfigFile "~/.config/hammerspoon/init.lua" 3 | 4 | local utils = require("utils") 5 | 6 | utils.ensure_spoon_installer() 7 | 8 | spoon.SpoonInstall.use_syncinstall = true 9 | 10 | spoon.SpoonInstall:andUse("EmmyLua") 11 | 12 | hs.window.animationDuration = 0 13 | 14 | local modifier = { 15 | blank = "", 16 | cmd = { "cmd" }, 17 | cmd_shift = { "cmd", "shift" }, 18 | cmd_alt = { "cmd", "alt" }, 19 | cmd_alt_shift = { "cmd", "alt", "shift" }, 20 | ctrl = { "ctrl" }, 21 | ctrl_shift = { "ctrl", "shift" }, 22 | } 23 | 24 | local wm = require("window-manager") 25 | -- wm.logger.setLogLevel('debug') 26 | wm:set_grid(6, 6):set_margins(hs.geometry.point(0, 0)) 27 | wm:bindHotkeys({ 28 | up = { modifier.cmd_alt, "up" }, 29 | right = { modifier.cmd_alt, "right" }, 30 | down = { modifier.cmd_alt, "down" }, 31 | left = { modifier.cmd_alt, "left" }, 32 | center = { modifier.cmd_alt, "c" }, 33 | switch_screen = { modifier.cmd_alt, "z" }, 34 | }) 35 | 36 | local config_loader = require("config-loader") 37 | -- config_loader.logger.setLogLevel('debug') 38 | config_loader:start() 39 | config_loader:bindHotkeys({ 40 | reload = { modifier.cmd_alt_shift, "r" }, 41 | }) 42 | 43 | -- MPD, MPC, MPDSCRIBBLE, NCMPCPP 44 | hs.hotkey.bind(modifier.cmd_alt, "m", function() 45 | os.execute("~/.local/bin/music-terminal") 46 | end) 47 | hs.hotkey.bind(modifier.cmd_alt, ",", function() 48 | os.execute("/usr/local/bin/mpc prev") 49 | end) 50 | hs.hotkey.bind(modifier.cmd_alt, ".", function() 51 | os.execute("/usr/local/bin/mpc next") 52 | end) 53 | 54 | -- Screenshot (f13 = print_screen) 55 | hs.hotkey.bind(modifier.blank, "f13", function() 56 | hs.application.open("com.apple.screenshot.launcher") 57 | end) 58 | -------------------------------------------------------------------------------- /private_dot_ssh/config_tailscale.tmpl: -------------------------------------------------------------------------------- 1 | # vim: set filetype=sshconfig : 2 | 3 | Host omega 4 | HostName omega.tailscale.muniftanjim.dev 5 | 6 | Host gamma 7 | User {{ "bXVuaWZ0YW5qaW0=" | b64dec }} 8 | HostName gamma.tailscale.muniftanjim.dev 9 | 10 | Host optimizely-muniftanjim 11 | User {{ "bXVuaWYudGFuamlt" | b64dec }} 12 | HostName optimizely-muniftanjim.tailscale.muniftanjim.dev 13 | 14 | Host box 15 | User {{ "bXVuaWZ0YW5qaW0=" | b64dec }} 16 | HostName box.tailscale.muniftanjim.dev 17 | RequestTTY yes 18 | RemoteCommand tmux attach-session -t box || tmux new-session -s box 19 | 20 | Host toolbox 21 | User {{ "bXVuaWZ0YW5qaW0=" | b64dec }} 22 | HostName toolbox.tailscale.muniftanjim.dev 23 | RequestTTY yes 24 | RemoteCommand tmux attach-session -t toolbox || tmux new-session -s toolbox 25 | 26 | Host torbox 27 | User {{ "bXVuaWZ0YW5qaW0=" | b64dec }} 28 | HostName torbox.tailscale.muniftanjim.dev 29 | RequestTTY yes 30 | RemoteCommand tmux attach-session -t torbox || tmux new-session -s torbox 31 | 32 | # Host newscred 33 | # HostName newscred.tailscale.muniftanjim.dev 34 | # 35 | # # headless dev machine 36 | # Host dev-newscred* 37 | # HostName newscred.tailscale.muniftanjim.dev 38 | # ForwardAgent yes 39 | # # ForwardX11 yes 40 | # # ForwardX11Trusted yes 41 | # LocalForward 3000 localhost:3000 42 | # LocalForward 3333 localhost:3333 43 | # LocalForward 4000 localhost:4000 44 | # LocalForward 5000 localhost:5000 45 | # LocalForward 5049 localhost:5049 46 | # LocalForward 7848 localhost:7848 47 | # LocalForward 9201 localhost:9201 48 | # LocalForward 9204 localhost:9204 49 | # LocalForward 35729 localhost:35729 50 | # # transmission 51 | # LocalForward 7451 localhost:7451 52 | # Host dev-newscred-bare 53 | # # without tmux 54 | # Host dev-newscred 55 | # RequestTTY yes 56 | # RemoteCommand tmux attach-session -t dev || tmux new-session -s dev 57 | -------------------------------------------------------------------------------- /dot_local/bin/executable_music-terminal: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | is_mac() { 6 | [[ $OSTYPE = darwin* ]] 7 | } 8 | 9 | command_exists() { 10 | type "${1}" >/dev/null 2>&1 11 | } 12 | 13 | process_running() { 14 | pgrep "${1}$" >/dev/null 2>&1 15 | } 16 | 17 | notify() { 18 | local -r title="${1}" 19 | local -r description="${2}" 20 | if is_mac; then 21 | osascript -e "display notification \"${description}\" with title \"${title}\"" 22 | elif command_exists notify-send; then 23 | notify-send --hint=int:transient:1 "${title}" "${description}" 24 | fi 25 | } 26 | 27 | export PATH="/usr/local/bin:${PATH}" 28 | 29 | if is_mac; then 30 | export PATH="/usr/local/opt/util-linux/bin:${PATH}" 31 | fi 32 | 33 | if ! process_running mpd; then 34 | setsid mpd >/dev/null 2>&1 & 35 | killall mpdscribble >/dev/null 2>&1 || true 36 | fi 37 | 38 | if ! process_running mpdscribble; then 39 | setsid mpdscribble --conf "${HOME}/.config/mpdscribble/mpdscribble.conf" >/dev/null 2>&1 & 40 | fi 41 | 42 | if command_exists alacritty; then 43 | terminal_emulator=$(which alacritty) 44 | elif command_exists x-terminal-emulator; then 45 | terminal_emulator=$(readlink -f $(which x-terminal-emulator)) 46 | fi 47 | 48 | if [[ -z "$terminal_emulator" ]]; then 49 | echo "missing terminal emulator" 50 | exit 1 51 | fi 52 | 53 | terminal_name=$(basename ${terminal_emulator}) 54 | 55 | terminal_command="" 56 | 57 | case ${terminal_name} in 58 | alacritty) 59 | terminal_command="${terminal_emulator}";; 60 | tilix) 61 | terminal_command="${terminal_emulator} --window-style=disable-csd";; 62 | mate-terminal) 63 | terminal_command="${terminal_emulator} --hide-menubar";; 64 | *) 65 | terminal_command="${terminal_emulator}";; 66 | esac 67 | 68 | if process_running ncmpcpp; then 69 | mpc toggle 70 | else 71 | notify "Music Player" "Loading..." 72 | setsid ${terminal_command} --command ncmpcpp $* & 73 | fi 74 | -------------------------------------------------------------------------------- /private_dot_config/private_gtk-3.0/gtk.css: -------------------------------------------------------------------------------- 1 | /* focused window */ 2 | decoration { 3 | border: 2px solid #b16286; 4 | background: #b16286; 5 | 6 | /* switch colors smoothly with a transition animation */ 7 | transition: border-color ease-in 0.2s, background-color ease-in 0.2s; 8 | } 9 | 10 | /* unfocused window */ 11 | decoration:backdrop { 12 | border-color: #988374; 13 | background-color: #988374; 14 | } 15 | 16 | /* focused window (server-side rendering hack) */ 17 | .ssd .titlebar { 18 | border: 2px solid #b16286; 19 | border-bottom: none; 20 | 21 | /* transition animation does not seem to work with server-side rendering */ 22 | /* transition: border-color ease-in 0.2s; */ 23 | } 24 | 25 | /* unfocused window (server-side rendering hack) */ 26 | .ssd .titlebar:backdrop { 27 | border-color: #988374; 28 | } 29 | 30 | /* remove borders of maximized windows */ 31 | .maximized decoration, 32 | .ssd.maximized .titlebar { 33 | border: none; 34 | } 35 | 36 | /* shrink headerbars */ 37 | headerbar { 38 | min-height: 0px; 39 | padding-left: 2px; /* same as childrens vertical margins for nicer proportions */ 40 | padding-right: 2px; 41 | } 42 | 43 | headerbar entry, 44 | headerbar spinbutton, 45 | headerbar button, 46 | headerbar separator { 47 | margin-top: 2px; /* same as headerbar side padding for nicer proportions */ 48 | margin-bottom: 2px; 49 | } 50 | 51 | /* shrink ssd titlebars */ 52 | .default-decoration { 53 | min-height: 0; /* let the entry and button drive the titlebar size */ 54 | padding: 2px; 55 | } 56 | 57 | .default-decoration .titlebutton { 58 | min-height: 16px; /* tweak these two props to reduce button size */ 59 | min-width: 16px; 60 | } 61 | 62 | window.ssd headerbar.titlebar { 63 | padding-top: 1px; 64 | padding-bottom: 1px; 65 | min-height: 0; 66 | } 67 | 68 | window.ssd headerbar.titlebar button.titlebutton { 69 | padding-top: 1px; 70 | padding-bottom: 1px; 71 | min-height: 0; 72 | } 73 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/ui/init.lua: -------------------------------------------------------------------------------- 1 | local u = require("config.utils") 2 | 3 | local plugins = { 4 | { 5 | "goolord/alpha-nvim", 6 | config = function() 7 | require("plugins.ui.alpha") 8 | end, 9 | }, 10 | 11 | u.dev_plugin({ 12 | "MunifTanjim/nui.nvim", 13 | event = "VeryLazy", 14 | config = function() 15 | require("plugins.ui.nui") 16 | end, 17 | }), 18 | 19 | u.dev_plugin({ 20 | "MunifTanjim/nougat.nvim", 21 | event = "VeryLazy", 22 | config = function() 23 | require("plugins.ui.nougat") 24 | end, 25 | }), 26 | 27 | { 28 | "nvim-neo-tree/neo-tree.nvim", 29 | branch = "main", 30 | dependencies = { 31 | "s1n7ax/nvim-window-picker", 32 | }, 33 | cmd = "Neotree", 34 | init = function() 35 | u.set_keymap("n", "e", "Neotree toggle", "toggle file tree") 36 | end, 37 | config = function() 38 | require("plugins.ui.neo-tree") 39 | end, 40 | }, 41 | 42 | { 43 | "MagicDuck/grug-far.nvim", 44 | cmd = "GrugFar", 45 | init = function() 46 | u.set_keymap("n", "S", "GrugFar", "toggle grug-far") 47 | end, 48 | config = function() 49 | require("grug-far").setup({}) 50 | end, 51 | }, 52 | 53 | { 54 | "lukas-reineke/indent-blankline.nvim", 55 | main = "ibl", 56 | event = "BufReadPre", 57 | config = function() 58 | require("plugins.ui.indent-blankline") 59 | end, 60 | }, 61 | 62 | { 63 | "kevinhwang91/nvim-bqf", 64 | event = "VeryLazy", 65 | config = function() 66 | require("plugins.ui.quickfix") 67 | end, 68 | }, 69 | } 70 | 71 | local fzf_root = vim.fn.fnamemodify(vim.fn.stdpath("data"), ":h") .. "/fzf" 72 | if vim.fn.isdirectory(fzf_root) == 1 then 73 | table.insert(plugins, { 74 | "junegunn/fzf", 75 | dev = true, 76 | dir = fzf_root, 77 | }) 78 | table.insert(plugins, { "junegunn/fzf.vim" }) 79 | end 80 | 81 | return plugins 82 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/custom/rename.lua: -------------------------------------------------------------------------------- 1 | local Input = require("nui.input") 2 | local event = require("nui.utils.autocmd").event 3 | 4 | local function rename() 5 | local curr_name = vim.fn.expand("") 6 | 7 | local params = vim.lsp.util.make_position_params() 8 | 9 | local function on_submit(new_name) 10 | if not new_name or #new_name == 0 or curr_name == new_name then 11 | return 12 | end 13 | 14 | params.newName = new_name 15 | 16 | vim.lsp.buf_request(0, "textDocument/rename", params, function(_, result, ctx, _) 17 | if not result then 18 | return 19 | end 20 | 21 | local total_files = vim.tbl_count(result.changes or result.documentChanges or {}) 22 | 23 | local client = vim.lsp.get_client_by_id(ctx.client_id) 24 | if not client then 25 | return 26 | end 27 | 28 | vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) 29 | 30 | print(string.format("Changed %s file%s. To save them run ':noa wa'", total_files, total_files > 1 and "s" or "")) 31 | end) 32 | end 33 | 34 | local input = Input({ 35 | border = { 36 | style = "default", 37 | text = { 38 | top = "[Rename]", 39 | top_align = "left", 40 | }, 41 | }, 42 | relative = { 43 | type = "buf", 44 | position = { 45 | row = params.position.line, 46 | col = params.position.character, 47 | }, 48 | }, 49 | position = { 50 | row = 1, 51 | col = 0, 52 | }, 53 | size = { 54 | width = 25, 55 | height = 1, 56 | }, 57 | win_options = { 58 | winhighlight = "NormalFloat:Normal", 59 | }, 60 | }, { 61 | prompt = "", 62 | default_value = curr_name, 63 | on_submit = on_submit, 64 | }) 65 | 66 | input:mount() 67 | 68 | input:on(event.BufLeave, input.input_props.on_close, { once = true }) 69 | 70 | input:map("n", "", input.input_props.on_close, { noremap = true }) 71 | end 72 | 73 | return rename 74 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/custom/code_action.lua: -------------------------------------------------------------------------------- 1 | local Menu = require("nui.menu") 2 | 3 | local code_action_kinds = { 4 | Menu.item("Empty", { value = "" }), 5 | Menu.item("QuickFix", { value = "quickfix" }), 6 | Menu.item("Refactor", { value = "refactor" }), 7 | Menu.item("RefactorExtract", { value = "refactor.extract" }), 8 | Menu.item("RefactorInline", { value = "refactor.inline" }), 9 | Menu.item("RefactorRewrite", { value = "refactor.rewrite" }), 10 | Menu.item("Source", { value = "source" }), 11 | Menu.item("SourceFixAll", { value = "source.fixAll" }), 12 | Menu.item("SourceOrganizeImports", { value = "source.organizeImports" }), 13 | } 14 | 15 | ---@param on_done fun(kind?: string): nil 16 | local function select_code_action_kind(on_done) 17 | local menu = Menu({ 18 | relative = "cursor", 19 | position = { 20 | row = 2, 21 | col = 1, 22 | }, 23 | border = { 24 | style = "rounded", 25 | text = { 26 | top = "[Code Action Kind]", 27 | top_align = "center", 28 | }, 29 | }, 30 | win_options = { 31 | winhighlight = "NormalFloat:Normal", 32 | }, 33 | }, { 34 | lines = code_action_kinds, 35 | on_close = function() 36 | on_done() 37 | end, 38 | on_submit = function(item) 39 | on_done(item.value) 40 | end, 41 | }) 42 | 43 | menu:mount() 44 | end 45 | 46 | ---@param kind? string|string[]|true 47 | local function code_action(kind) 48 | if not kind then 49 | vim.lsp.buf.code_action() 50 | return 51 | end 52 | 53 | local function open_code_actions(only) 54 | only = type(only) == "string" and { only } or only 55 | vim.lsp.buf.code_action({ context = { only = only, diagnostics = {}, triggerKind = 1 } }) 56 | end 57 | 58 | if kind ~= true then 59 | open_code_actions(kind) 60 | return 61 | end 62 | 63 | select_code_action_kind(function(only) 64 | if only then 65 | open_code_actions(only) 66 | end 67 | end) 68 | end 69 | 70 | return code_action 71 | -------------------------------------------------------------------------------- /private_dot_config/mpdscribble/mpdscribble.conf.tmpl: -------------------------------------------------------------------------------- 1 | ## mpdscribble - an audioscrobbler for the Music Player Daemon. 2 | ## https://www.musicpd.org/clients/mpdscribble/ 3 | 4 | # HTTP proxy URL. 5 | #proxy = http://the.proxy.server:3128 6 | 7 | # The location of the pid file. mpdscribble saves its process id there. 8 | pidfile = {{ .chezmoi.homeDir }}/.local/share/mpdscribble/pid 9 | 10 | # Change to this system user after daemonization. 11 | #daemon_user = mpdscribble 12 | 13 | # The location of the mpdscribble log file. The special value 14 | # "syslog" makes mpdscribble use the local syslog daemon. On most 15 | # systems, log messages will appear in /var/log/daemon.log then. 16 | # "-" means log to stderr (the current terminal). 17 | log = {{ .chezmoi.homeDir }}/.local/share/mpdscribble/log 18 | 19 | # How verbose mpdscribble's logging should be. Default is 1. 20 | verbose = 1 21 | 22 | # How often should mpdscribble save the journal file? [seconds] 23 | journal_interval = 240 24 | 25 | # The host running MPD, possibly protected by a password 26 | # ([PASSWORD@]HOSTNAME). Defaults to $MPD_HOST or localhost. 27 | host = localhost 28 | 29 | # The port that the MPD listens on and mpdscribble should try to 30 | # connect to. Defaults to $MPD_PORT or 6600. 31 | port = 6600 32 | 33 | # [last.fm] 34 | # url = http://post.audioscrobbler.com/ 35 | # username = MunifTanjim 36 | # password = 37 | # The file where mpdscribble should store its Last.fm journal in case 38 | # you do not have a connection to the Last.fm server. 39 | # journal = {{ .chezmoi.homeDir }}/.local/share/mpdscribble/lastfm.journal 40 | 41 | # [libre.fm] 42 | # url = http://turtle.libre.fm/ 43 | # username = MunifTanjim 44 | # password = {{ ( bitwarden "item" "libre.fm" ).login.password }} 45 | # journal = {{ .chezmoi.homeDir }}/.local/share/mpdscribble/librefm.journal 46 | 47 | #[jamendo] 48 | #url = http://postaudioscrobbler.jamendo.com/ 49 | #username = my_username 50 | #password = my_password 51 | #journal = {{ .chezmoi.homeDir }}/.local/share/mpdscribble/jamendo.journal 52 | 53 | #[file] 54 | #file = {{ .chezmoi.homeDir }}/.local/share/mpdscribble/file.journal 55 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/null-ls.lua: -------------------------------------------------------------------------------- 1 | local null_ls = require("null-ls") 2 | local helpers = require("null-ls.helpers") 3 | local u = require("plugins.lsp.utils") 4 | 5 | local clang_format = null_ls.builtins.formatting.clang_format.with({ 6 | condition = function(utils) 7 | return utils.root_has_file({ ".clang-format" }) 8 | end, 9 | runtime_condition = helpers.cache.by_bufnr(function(params) 10 | if vim.fn.filereadable(".clang-format-ignore") == 0 then 11 | return false 12 | end 13 | 14 | local ignore_file = ".clang-format-ignore" 15 | local filename = vim.fn.fnamemodify(params.bufname, ":.") 16 | local find_command = string.format("fd --has-results --ignore-file %s --full-path '%s' .", ignore_file, filename) 17 | return os.execute(find_command) == 0 18 | end), 19 | }) 20 | 21 | local function has_no_ruff_config(utils) 22 | return not utils.has_file({ "./ruff.toml" }) and not utils.root_has_file({ "ruff.toml" }) 23 | end 24 | 25 | ---@diagnostic disable-next-line: redundant-parameter 26 | null_ls.setup({ 27 | sources = { 28 | -- c 29 | clang_format, 30 | -- python 31 | require("none-ls.diagnostics.flake8").with({ 32 | condition = has_no_ruff_config, 33 | }), 34 | null_ls.builtins.formatting.black.with({ 35 | condition = has_no_ruff_config, 36 | }), 37 | null_ls.builtins.formatting.isort.with({ 38 | condition = has_no_ruff_config, 39 | }), 40 | -- lua 41 | require("none-ls-luacheck.diagnostics.luacheck").with({ 42 | condition = function(utils) 43 | return utils.root_has_file({ ".luacheckrc" }) 44 | end, 45 | }), 46 | null_ls.builtins.formatting.stylua, 47 | }, 48 | on_attach = function(client, bufnr) 49 | u.setup_keymaps(client, bufnr) 50 | u.setup_format_on_save(client, bufnr) 51 | end, 52 | }) 53 | 54 | require("eslint").setup({ 55 | bin = vim.g.eslint_bin or "eslint_d", 56 | diagnostics = { 57 | enable = true, 58 | report_unused_disable_directives = false, 59 | run_on = "type", 60 | }, 61 | }) 62 | 63 | require("prettier").setup({ 64 | bin = "prettierd", 65 | }) 66 | -------------------------------------------------------------------------------- /.modules/helpers.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | export current_shell="$(ps -p$$ -oucomm= | xargs)" 4 | 5 | command_exists() { 6 | type "${1}" >/dev/null 2>&1 7 | } 8 | 9 | directory_exists() { 10 | [ -d "${1}" ] 11 | } 12 | 13 | pathmunge() { 14 | if ! echo "${PATH}" | grep -Eq "(^|:)${1}($|:)"; then 15 | if directory_exists "${1}"; then 16 | if [ "${2}" = "after" ]; then 17 | export PATH="${PATH}:${1}" 18 | else 19 | export PATH="${1}:${PATH}" 20 | fi 21 | fi 22 | fi 23 | } 24 | 25 | expunge_history() { 26 | if ! command_exists fzf; then 27 | echo "not found: fzf" 28 | fi 29 | 30 | local -r items="$(cat "${HISTFILE}" | nl -b a)" 31 | local -r header="Expunge History (use TAB to select multiple)" 32 | local -r expression="$(echo "${items}" | fzf --multi --header="${header}" | awk '{print $1}' ORS='d;')" 33 | sed -i -e "${expression}" "${HISTFILE}" 34 | } 35 | 36 | refresh_and_clear() { 37 | if test -n "${SSH_CLIENT}" -o -n "${SSH_TTY}"; then 38 | # inside ssh session 39 | if [[ -n "$TMUX" ]] || [[ "$TERM" =~ "^(screen|tmux).*" ]]; then 40 | # inside tmux 41 | if [[ -n "${SSH_AUTH_SOCK}" ]] && [[ ! -S ${SSH_AUTH_SOCK} ]]; then 42 | # has stale ${SSH_AUTH_SOCK} 43 | eval "$(tmux show-environment -s | grep '^SSH_AUTH_SOCK')" 44 | fi 45 | fi 46 | fi 47 | 48 | clear -x 49 | } 50 | 51 | __exit_or_tmux_detach() { 52 | if [[ -n "$LF_LEVEL" ]]; then 53 | # inside lf 54 | echo "exit" 55 | return 56 | fi 57 | 58 | if [[ -z "$TMUX" ]] || [[ ! "$TERM" =~ "^(screen|tmux).*" ]]; then 59 | # outside tmux 60 | echo "exit" 61 | return 62 | fi 63 | 64 | if ! command_exists tmux; then 65 | # no tmux 66 | echo "exit" 67 | return 68 | fi 69 | 70 | # inside tmux 71 | local -r total_windows="$(tmux list-windows | wc -l)" 72 | 73 | if (($total_windows != 1)); then 74 | echo "exit" 75 | return 76 | fi 77 | 78 | local -r total_panes="$(tmux list-panes | wc -l)" 79 | 80 | if (($total_panes != 1)); then 81 | echo "exit" 82 | return 83 | fi 84 | 85 | echo "tmux detach && clear" 86 | } 87 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/which-key.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "folke/which-key.nvim", 3 | } 4 | 5 | ---@module 'which-key' 6 | local wk 7 | 8 | ---@param mode string|string[] 9 | ---@param lhs string 10 | ---@param rhs string|fun():nil 11 | ---@param desc_or_opts string|table 12 | ---@param opts? table 13 | local function set_keymap(mode, lhs, rhs, desc_or_opts, opts) 14 | if opts then 15 | opts.desc = desc_or_opts 16 | else 17 | opts = type(desc_or_opts) == "table" and desc_or_opts or { desc = desc_or_opts } 18 | end 19 | 20 | opts.mode = type(mode) == "table" and mode or { mode } 21 | opts[1] = lhs 22 | opts[2] = rhs 23 | 24 | wk.add(opts) 25 | end 26 | 27 | ---@param default_mode string|string[] 28 | ---@param maps ({[1]: string, [2]: string|(fun():nil), [3]?: string|table, [4]?: table}|table)[] 29 | ---@param fallback_opts? table 30 | local function set_keymaps(default_mode, maps, fallback_opts) 31 | fallback_opts = fallback_opts or {} 32 | 33 | local specs = { len = 0 } 34 | 35 | for _, map in ipairs(maps) do 36 | if not map.mode then 37 | map.mode = default_mode 38 | end 39 | 40 | local desc, opts = map[3], map[4] 41 | map[3], map[4] = nil, nil 42 | 43 | if opts then 44 | opts.desc = desc 45 | else 46 | opts = type(desc) == "table" and desc or { desc = desc } 47 | end 48 | 49 | specs.len = specs.len + 1 50 | specs[specs.len] = vim.tbl_extend("keep", map, opts, fallback_opts) 51 | end 52 | 53 | specs.len = nil 54 | 55 | wk.add(specs) 56 | end 57 | 58 | function plugin.config() 59 | local u = require("config.utils") 60 | 61 | wk = require("which-key") 62 | 63 | wk.setup({ 64 | preset = "helix", 65 | plugins = { 66 | presets = { 67 | -- operators = false, 68 | }, 69 | }, 70 | win = { 71 | border = "single", 72 | padding = { 0, 0 }, 73 | }, 74 | }) 75 | 76 | wk.add({ 77 | { "d", group = "DAP" }, 78 | { "f", group = "Telescope" }, 79 | { "o", group = "Open" }, 80 | }) 81 | 82 | u.set_keymap = set_keymap 83 | u.set_keymaps = set_keymaps 84 | end 85 | 86 | return plugin 87 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/dap/init.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "mfussenegger/nvim-dap", 3 | dependencies = { 4 | "rcarriga/nvim-dap-ui", 5 | "theHamsta/nvim-dap-virtual-text", 6 | }, 7 | lazy = true, 8 | config = function() 9 | require("plugins.dap.base") 10 | end, 11 | } 12 | 13 | function plugin.init() 14 | local u = require("config.utils") 15 | 16 | u.set_keymaps("n", { 17 | { 18 | "db", 19 | function() 20 | require("dap").toggle_breakpoint() 21 | end, 22 | "[dap] Breakpoint", 23 | }, 24 | { 25 | "dB", 26 | function() 27 | local condition = vim.fn.input("Breakpoint condition: ") 28 | local hit_condition = vim.fn.input("Breakpoint hit condition: ") 29 | local log_message = vim.fn.input("Breakpoint log message: ") 30 | require("dap").set_breakpoint(condition, hit_condition, log_message) 31 | end, 32 | "[dap] Conditional Breakpoint", 33 | }, 34 | { 35 | "dc", 36 | function() 37 | require("dap").continue() 38 | end, 39 | "[dap] Continue", 40 | }, 41 | { 42 | "dp", 43 | function() 44 | require("dap").pause() 45 | end, 46 | "[dap] Pause", 47 | }, 48 | { 49 | "dt", 50 | function() 51 | require("dap").terminate() 52 | end, 53 | "[dap] Terminate", 54 | }, 55 | { 56 | "di", 57 | function() 58 | require("dap").step_into() 59 | end, 60 | "[dap] Step Into", 61 | }, 62 | { 63 | "do", 64 | function() 65 | require("dap").step_out() 66 | end, 67 | "[dap] Step Out", 68 | }, 69 | { 70 | "dO", 71 | function() 72 | require("dap").step_over() 73 | end, 74 | "[dap] Step Over", 75 | }, 76 | { 77 | "drc", 78 | function() 79 | require("dap").run_to_cursor() 80 | end, 81 | "[dap] Run to Cursor", 82 | }, 83 | { 84 | "dh", 85 | function() 86 | require("dapui").eval() 87 | end, 88 | "[dap] Eval", 89 | }, 90 | }) 91 | end 92 | 93 | return plugin 94 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.lsp/lua.json: -------------------------------------------------------------------------------- 1 | { 2 | "local_assignment": { 3 | "prefix": "la", 4 | "body": ["local ${1:name} = ${0:value}"], 5 | "description": "local assignment" 6 | }, 7 | "require": { 8 | "prefix": "rq", 9 | "body": ["require(\"${1:mod}\")$0"], 10 | "description": "require module" 11 | }, 12 | "local_require": { 13 | "prefix": "lrq", 14 | "body": ["local ${1:mod} = require(\"${2:${1}}\")$0"], 15 | "description": "require module as local variable" 16 | }, 17 | "function": { 18 | "prefix": ["fn"], 19 | "body": ["function ${1:fn_name}($2)", " $0", "end"], 20 | "description": "function" 21 | }, 22 | "anonymous_function": { 23 | "prefix": ["afn"], 24 | "body": ["function ($1)", " $0", "end"], 25 | "description": "anonymous function" 26 | }, 27 | "local_function": { 28 | "prefix": ["lfn"], 29 | "body": ["local function ${1:fn_name}($2)", " $0", "end"], 30 | "description": "local function" 31 | }, 32 | "method_function": { 33 | "prefix": ["mfn"], 34 | "body": ["function ${1:class_name}:${2:fn_name}($3)", " $0", "end"], 35 | "description": "method function" 36 | }, 37 | "static_function": { 38 | "prefix": ["sfn"], 39 | "body": ["function ${1:object}.${2:fn_name}($3)", " $0", "end"], 40 | "description": "method function" 41 | }, 42 | "print": { 43 | "prefix": "p", 44 | "body": ["print($0)"], 45 | "description": "print" 46 | }, 47 | "print_vim_inspect": { 48 | "prefix": "pvi", 49 | "body": ["print(vim.inspect($0))"], 50 | "description": "print vim.inspect" 51 | }, 52 | "test_describe": { 53 | "prefix": "td", 54 | "body": ["describe(\"$1\", function()", " $0", "end)"], 55 | "description": "test describe block" 56 | }, 57 | "test_it": { 58 | "prefix": "ti", 59 | "body": ["it(\"$1\", function()", " $0", "end)"], 60 | "description": "test it block" 61 | }, 62 | "test_before_each": { 63 | "prefix": "tbe", 64 | "body": ["before_each(function()", " $0", "end)"], 65 | "description": "test before_each block" 66 | }, 67 | "test_after_each": { 68 | "prefix": "tae", 69 | "body": ["after_each(function()", " $0", "end)"], 70 | "description": "test after_each block" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/bindings: -------------------------------------------------------------------------------- 1 | set abort_backspace = yes 2 | set abort_key = "\C[" 3 | 4 | unbind * 5 | 6 | bind attach,browser,index,pager d noop 7 | bind attach,browser,index,pager g noop 8 | bind attach,browser,index,pager m noop 9 | bind attach,browser,index,pager y noop 10 | 11 | # generic 12 | 13 | bind generic help 14 | bind generic gg first-entry 15 | bind generic G last-entry 16 | bind generic j next-entry 17 | bind generic k previous-entry 18 | bind generic G last-entry 19 | bind generic \Cu half-up 20 | bind generic \Cd half-down 21 | bind generic \CF next-page 22 | bind generic \CB previous-page 23 | bind generic \Ce next-line 24 | bind generic \Cy previous-line 25 | bind generic N search-opposite 26 | bind generic ? search-reverse 27 | bind generic gr refresh 28 | bind generic gG jump 29 | bind generic q exit 30 | bind generic ";" tag-prefix 31 | bind generic select-entry 32 | 33 | # index 34 | 35 | bind index "m" mail 36 | bind index gs sync-mailbox 37 | bind index o display-message 38 | bind index \Ce next-line 39 | bind index \Cy previous-line 40 | bind index zA collapse-all 41 | bind index za collapse-thread 42 | bind index q quit 43 | 44 | macro index J "set resolve=noset resolve=yes" "tag current entry and go to next" 45 | macro index K "set resolve=noset resolve=yes" "tag current entry and go to previous" 46 | macro index gc "source '~/.config/neomutt/scripts/switch_account.sh |'" 47 | 48 | bind index B sidebar-toggle-visible 49 | bind index \Ck sidebar-prev 50 | bind index \Cj sidebar-next 51 | bind index \Co sidebar-open 52 | 53 | # pager 54 | 55 | bind pager gg top 56 | bind pager G bottom 57 | bind pager j next-line 58 | bind pager k previous-line 59 | bind pager e edit-or-view-raw-message 60 | 61 | # others 62 | 63 | bind index,pager df delete-message 64 | macro index gU "mbsync -a" "run mbsync to sync mail for all accounts" 65 | macro index,pager y* "" "Toggle Star" 66 | macro index,pager yr "" "Toggle Read Status" 67 | 68 | # vim: filetype=muttrc 69 | -------------------------------------------------------------------------------- /dot_gitconfig.tmpl: -------------------------------------------------------------------------------- 1 | # vim: set filetype=gitconfig foldmethod=indent : 2 | 3 | [user] 4 | name = Munif Tanjim 5 | username = MunifTanjim 6 | email = {{ "aGVsbG9AbXVuaWZ0YW5qaW0uZGV2" | b64dec }} 7 | signingkey = 9FA86B9EC363F224 8 | 9 | [core] 10 | excludesfile = ~/.config/git/ignore 11 | pager = delta 12 | sshCommand = "ssh -o ControlPath=none" 13 | 14 | [diff] 15 | tool = vimdiff 16 | algorithm = histogram 17 | [difftool] 18 | prompt = false 19 | trustExitCode = true 20 | [difftool "code"] 21 | cmd = code --wait --diff "$LOCAL" "$REMOTE" 22 | [difftool "vimdiff"] 23 | cmd = vim -d "$LOCAL" "$REMOTE" 24 | 25 | [interactive] 26 | diffFilter = delta --color-only 27 | 28 | [init] 29 | defaultBranch = main 30 | 31 | [merge] 32 | conflictStyle = merge 33 | tool = vimdiff 34 | [mergetool] 35 | prompt = true 36 | [mergetool "vimdiff"] 37 | cmd = vim -d "$REMOVE" "$MERGED" "$LOCAL" 38 | trustExitCode = true 39 | 40 | [pull] 41 | ff = only 42 | 43 | [push] 44 | autoSetupRemote = true 45 | default = upstream 46 | followTags = true 47 | 48 | [rebase] 49 | autosquash = true 50 | 51 | [alias] 52 | co = checkout 53 | l = log --graph --pretty=oneline --abbrev-commit 54 | pl = pull 55 | ps = push 56 | s = status --short 57 | 58 | [color] 59 | ui = auto 60 | [color "branch"] 61 | current = yellow reverse 62 | local = yellow 63 | remote = green 64 | [color "diff"] 65 | meta = yellow bold 66 | frag = magenta bold 67 | old = red bold 68 | new = green bold 69 | [color "status"] 70 | added = yellow 71 | changed = green 72 | untracked = red 73 | 74 | [delta] 75 | syntax-theme = gruvbox-dark 76 | line-numbers = true 77 | 78 | [hub] 79 | protocol = https 80 | 81 | [credential] 82 | helper = {{ if .meta.is.headless_machine -}} store {{- else if eq .chezmoi.os "darwin" -}} osxkeychain {{- else -}} /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret {{- end }} 83 | [credential "https://github.com"] 84 | username = MunifTanjim 85 | helper = !gh auth git-credential 86 | [credential "https://gist.github.com"] 87 | username = MunifTanjim 88 | helper = !gh auth git-credential 89 | [credential "https://bitbucket.org"] 90 | username = MunifTanjim 91 | [credential "https://gitlab.com"] 92 | username = MunifTanjim 93 | 94 | [includeIf "gitdir:github/newscred/**"] 95 | path = ~/.gitconfig.optimizely 96 | [includeIf "gitdir:github/optimizely/**"] 97 | path = ~/.gitconfig.optimizely 98 | -------------------------------------------------------------------------------- /.nvim.lua: -------------------------------------------------------------------------------- 1 | -- tmux popup 2 | local function try_tmux_popup_exec(cmd) 3 | if vim.fn.exists("$TMUX") == 1 then 4 | vim.system({ "tmux", "display-popup", "-EE", table.concat(cmd, " ") }, { text = true }) 5 | return true 6 | end 7 | end 8 | 9 | -- akinsho/toggleterm.nvim 10 | local function try_toggleterm_exec(cmd) 11 | if vim.fn.exists(":TermExec") == 2 then 12 | vim.schedule(function() 13 | vim.cmd("TermExec cmd='" .. table.concat(cmd, " ") .. "&& exit || read -n 1; exit' direction=float") 14 | end) 15 | return true 16 | end 17 | end 18 | 19 | local chezmoi_ignored_files = {} 20 | local function is_chezmoi_ignored_file(file) 21 | if not chezmoi_ignored_files[0] then 22 | for _, ignored_file in 23 | ipairs( 24 | vim.split( 25 | vim.system({ "chezmoi", "ignored" }, { text = true }):wait().stdout, 26 | "\n", 27 | { plain = true, trimempty = true } 28 | ) 29 | ) 30 | do 31 | chezmoi_ignored_files[ignored_file] = true 32 | end 33 | chezmoi_ignored_files[0] = true 34 | end 35 | 36 | if chezmoi_ignored_files[file] then 37 | return true 38 | end 39 | 40 | local fname = vim.fn.fnamemodify(file, ":.") 41 | while #fname > 1 do 42 | if vim.fn.fnamemodify(fname, ":t"):match("^%.") then 43 | -- starting with `.` 44 | return true 45 | end 46 | fname = vim.fn.fnamemodify(fname, ":h") 47 | end 48 | 49 | return false 50 | end 51 | 52 | --[[ chezmoi ]] 53 | vim.api.nvim_create_autocmd("BufWritePost", { 54 | group = vim.api.nvim_create_augroup("chezmoi-nvim-lua", { clear = true }), 55 | callback = function(info) 56 | if is_chezmoi_ignored_file(info.file) then 57 | return 58 | end 59 | 60 | local chezmoi_apply_cmd = { 61 | "chezmoi", 62 | "apply", 63 | "--parent-dirs", 64 | vim.fn.systemlist({ "chezmoi", "target-path", info.file })[1], 65 | } 66 | 67 | if try_tmux_popup_exec(chezmoi_apply_cmd) then 68 | return 69 | end 70 | 71 | if try_toggleterm_exec(chezmoi_apply_cmd) then 72 | return 73 | end 74 | 75 | if vim.fn.fnamemodify(info.file, ":."):match("%.tmpl$") then 76 | for _, line in ipairs(vim.api.nvim_buf_get_lines(info.buf, 0, -1, false)) do 77 | if string.find(line, "bitwarden") then 78 | -- ignore template files that needs secret 79 | return 80 | end 81 | end 82 | end 83 | 84 | vim.system(chezmoi_apply_cmd, { text = true }):wait() 85 | end, 86 | }) 87 | -------------------------------------------------------------------------------- /.modules/os.darwin.plugin.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | 3 | current_shell="${current_shell:-"$(ps -p$$ -oucomm= | xargs)"}" 4 | 5 | is_arm64() { 6 | test "$(uname -m)" = "arm64" 7 | } 8 | 9 | manpathmunge() { 10 | export MANPATH="${1}:${MANPATH}" 11 | } 12 | 13 | # homebrew 14 | export HOMEBREW_NO_AUTO_UPDATE=1 15 | 16 | if is_arm64; then 17 | if test -z "${DARWIN_NO_GNU}"; then 18 | OLD_PATH="${PATH}" 19 | OLD_MANPATH="${MANPATH}" 20 | OLD_INFOPATH="${INFOPATH}" 21 | ## {{{ start: homebrew on arm64 22 | eval "$(/opt/homebrew/bin/brew shellenv)" 23 | ## end: homebrew on arm64 }}} 24 | export PATH="${OLD_PATH}:${PATH}" 25 | export MANPATH="${OLD_MANPATH}:${MANPATH}" 26 | export INFOPATH="${OLD_INFOPATH}:${INFOPATH}" 27 | else 28 | eval "$(/opt/homebrew/bin/brew shellenv)" 29 | fi 30 | else 31 | export HOMEBREW_PREFIX="$(brew --prefix)" 32 | pathmunge "${HOMEBREW_PREFIX}/sbin" 33 | manpathmunge "${HOMEBREW_PREFIX}/share/man" 34 | fi 35 | 36 | if test -z "${DARWIN_NO_GNU}"; then 37 | # gnu programs/tools binaries 38 | pathmunge "${HOMEBREW_PREFIX}/opt/gnu-getopt/bin" 39 | pathmunge "${HOMEBREW_PREFIX}/opt/util-linux/bin" 40 | pathmunge "${HOMEBREW_PREFIX}/opt/util-linux/sbin" 41 | for gnubin_path in ${HOMEBREW_PREFIX}/opt/*/libexec/gnubin; do 42 | pathmunge "${gnubin_path}" 43 | done 44 | 45 | # gnu programs/tools manpage 46 | manpathmunge "${HOMEBREW_PREFIX}/opt/gnu-getopt/share/man" 47 | manpathmunge "${HOMEBREW_PREFIX}/opt/util-linux/share/man" 48 | for gnuman_path in ${HOMEBREW_PREFIX}/opt/*/libexec/gnuman; do 49 | manpathmunge "${gnuman_path}" 50 | done 51 | fi 52 | 53 | # docker 54 | pathmunge "${HOME}/.docker/bin" 55 | 56 | # google-cloud-sdk 57 | if [[ -d "${HOMEBREW_PREFIX}/Caskroom/google-cloud-sdk" ]]; then 58 | pathmunge "${HOMEBREW_PREFIX}/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin" 59 | . "${HOMEBREW_PREFIX}/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/completion.${current_shell}.inc" 60 | fi 61 | 62 | # openssl 63 | if ! is_arm64; then 64 | DARWIN_OPENSSL_VERSION="${DARWIN_OPENSSL_VERSION:-"1.1"}" 65 | brew_openssl_prefix="$(brew --prefix openssl@${DARWIN_OPENSSL_VERSION})" 66 | pathmunge "${brew_openssl_prefix}/bin" 67 | export CFLAGS="-I${brew_openssl_prefix}/include" 68 | export CPPFLAGS="-I${brew_openssl_prefix}/include" 69 | export LDFLAGS="-L${brew_openssl_prefix}/lib" 70 | export PKG_CONFIG_PATH="${brew_openssl_prefix}/lib/pkgconfig" 71 | unset brew_openssl_prefix 72 | fi 73 | 74 | darwin-no-gnu-run() { 75 | env -u PATH -u MANPATH DARWIN_NO_GNU=1 zsh -lic "$@" 76 | } 77 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.lsp/javascript.json: -------------------------------------------------------------------------------- 1 | { 2 | "const": { 3 | "prefix": "con", 4 | "body": "const ${1:name} = ${0:null}" 5 | }, 6 | "let": { 7 | "prefix": "let", 8 | "body": "let ${1:n} = ${0:null}" 9 | }, 10 | "export": { 11 | "prefix": "exp", 12 | "body": "export " 13 | }, 14 | "export_default": { 15 | "prefix": "expd", 16 | "body": "export default " 17 | }, 18 | "export_from": { 19 | "prefix": "expf", 20 | "body": "export ${2} from '${1}'" 21 | }, 22 | "forof": { 23 | "prefix": "forof", 24 | "body": ["for (const ${1:item} of ${2:${1}s}) {", " $3", "}"] 25 | }, 26 | "import_from": { 27 | "prefix": "impf", 28 | "body": ["import ${2} from '${1}'"] 29 | }, 30 | "import": { 31 | "prefix": "imp", 32 | "body": ["import '${1}'"] 33 | }, 34 | "console_log": { 35 | "prefix": "cl", 36 | "body": "console.log(${1:null})" 37 | }, 38 | "console_log_json_stringify": { 39 | "prefix": "cljs", 40 | "body": "console.log(JSON.stringify(${1:null}, null, 2))" 41 | }, 42 | "console_log_variable": { 43 | "prefix": "clv", 44 | "body": "console.log('${1:null}', $1)" 45 | }, 46 | "function": { 47 | "prefix": "fn", 48 | "body": ["function ${1:name}($2) {", " $3", "}"] 49 | }, 50 | "export_function": { 51 | "prefix": "efn", 52 | "body": ["export function ${1:name}($2) {", " $3", "}"] 53 | }, 54 | "export_default_function": { 55 | "prefix": "edfn", 56 | "body": ["export default function ${1:name}($2) {", " $3", "}"] 57 | }, 58 | "arrow_function": { 59 | "prefix": "afn", 60 | "body": ["($1) => {", " $2", "}"] 61 | }, 62 | "try_catch": { 63 | "prefix": "tryc", 64 | "body": ["try {", " $0", "} catch (${1:err}) {", " $2", "}"] 65 | }, 66 | "try_catch_finally": { 67 | "prefix": "trycf", 68 | "body": [ 69 | "try {", 70 | " $0", 71 | "} catch (${1:err}) {", 72 | " $2", 73 | "} finally {", 74 | " $3", 75 | "}" 76 | ] 77 | }, 78 | "try_finally": { 79 | "prefix": "tryf", 80 | "body": ["try {", " $0", "} finally {", " $1", "}"] 81 | }, 82 | "test_after_each": { 83 | "prefix": "tae", 84 | "body": ["afterEach(async () => {", " $0", "})"] 85 | }, 86 | "test_before_each": { 87 | "prefix": "tbe", 88 | "body": ["beforeEach(async () => {", " $0", "})"] 89 | }, 90 | "test_describe": { 91 | "prefix": "td", 92 | "body": ["describe('${1:name}', () => {", " $0", "})"] 93 | }, 94 | "test_it": { 95 | "prefix": "ti", 96 | "body": ["it('${1:description}', async () => {", " $0", "})"] 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /private_dot_config/nvim/snippets/.lsp/javascriptreact.json: -------------------------------------------------------------------------------- 1 | { 2 | "hook": { 3 | "prefix": "hook", 4 | "body": ["export function use${1:Hook}($2) {", " $3", "}"], 5 | "description": "create new hook" 6 | }, 7 | "jsx map": { 8 | "prefix": "xm", 9 | "body": [ 10 | "{${1:items}.map((${2:item}) => (", 11 | " <${3:Item} key={${4:${2}.id}} $5 />", 12 | "))}$0" 13 | ], 14 | "description": "jsx map return component" 15 | }, 16 | "jsx map including children": { 17 | "prefix": "xmc", 18 | "body": [ 19 | "{${1:items}.map((${2:item}) => (", 20 | " <${3:Item} key={${4:${2}.id}} $5 >$0", 21 | "))}" 22 | ], 23 | "description": "jsx map return component with childen" 24 | }, 25 | "jsx map with body": { 26 | "prefix": "xmb", 27 | "body": [ 28 | "{${1:items}.map((${2:item}) => {", 29 | " $3", 30 | " return (", 31 | " <${4:Item} key={${5:${2}.id}} $6 />", 32 | " )", 33 | "})}$0" 34 | ], 35 | "description": "jsx map (with body) return component" 36 | }, 37 | "jsx map with body including children": { 38 | "prefix": "xmbc", 39 | "body": [ 40 | "{${1:items}.map((${2:item}) => {", 41 | " $3", 42 | " return (", 43 | " <${4:Item} key={${5:${2}.id}} $6 >$0", 44 | " )", 45 | "})}" 46 | ], 47 | "description": "jsx map (with body) return component with children" 48 | }, 49 | "useCallback": { 50 | "prefix": "ucb", 51 | "body": [ 52 | "const ${1:callback} = useCallback(($2) => {", 53 | " $3", 54 | "}, [$4])$0" 55 | ], 56 | "description": "hook: useCallback" 57 | }, 58 | "useContext": { 59 | "prefix": "uc", 60 | "body": [ 61 | "const ${1:name} = useContext(${2:${1/(.*)/${1:/capitalize}/}Context})$0" 62 | ], 63 | "description": "hook: useContext" 64 | }, 65 | "useEffect": { 66 | "prefix": "ue", 67 | "body": ["useEffect(() => {", " $1", "}, [$2])$0"], 68 | "description": "hook: useEffect" 69 | }, 70 | "useEffect with cleanup": { 71 | "prefix": "uec", 72 | "body": [ 73 | "useEffect(() => {", 74 | " $1", 75 | " return () => {", 76 | " $2", 77 | " }", 78 | "}, [$3])$0" 79 | ], 80 | "description": "hook: useEffect with cleanup" 81 | }, 82 | "useMemo": { 83 | "prefix": "um", 84 | "body": ["const ${1:value} = useMemo(() => ${2}, [$3])$0"], 85 | "description": "hook: useMemo" 86 | }, 87 | "useRef": { 88 | "prefix": "ur", 89 | "body": ["const ${1:ref} = useRef(${2:null})$0"], 90 | "description": "hook: useContext" 91 | }, 92 | "useState": { 93 | "prefix": "us", 94 | "body": "const [${1:state}, set${1/(.*)/${1:/capitalize}/}] = useState(${2:initial${1/(.*)/${1:/capitalize}/}})$0", 95 | "description": "hook: useState" 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/dap/base.lua: -------------------------------------------------------------------------------- 1 | local dap = require("dap") 2 | local dap_ui = require("dapui") 3 | local dap_vt = require("nvim-dap-virtual-text") 4 | 5 | dap_vt.setup({ 6 | enabled = true, 7 | enable_commands = true, 8 | highlight_changed_variables = true, 9 | highlight_new_as_changed = false, 10 | show_stop_reason = true, 11 | commented = false, 12 | only_first_definition = false, 13 | all_references = false, 14 | filter_references_pattern = "", "<2-LeftMouse>" }, 29 | open = "o", 30 | remove = "d", 31 | edit = "e", 32 | repl = "r", 33 | toggle = "t", 34 | }, 35 | -- Expand lines larger than the window 36 | -- Requires >= 0.7 37 | expand_lines = vim.fn.has("nvim-0.7") == 1, 38 | -- Layouts define sections of the screen to place windows. 39 | -- The position can be "left", "right", "top" or "bottom". 40 | -- The size specifies the height/width depending on position. It can be an Int 41 | -- or a Float. Integer specifies height/width directly (i.e. 20 lines/columns) while 42 | -- Float value specifies percentage (i.e. 0.3 - 30% of available lines/columns) 43 | -- Elements are the elements shown in the layout (in order). 44 | -- Layouts are opened in order so that earlier layouts take priority in window sizing. 45 | layouts = { 46 | { 47 | elements = { 48 | -- Elements can be strings or table with id and size keys. 49 | { id = "scopes", size = 0.25 }, 50 | "breakpoints", 51 | "stacks", 52 | "watches", 53 | }, 54 | size = 40, -- 40 columns 55 | position = "left", 56 | }, 57 | { 58 | elements = { 59 | "repl", 60 | "console", 61 | }, 62 | size = 0.25, -- 25% of total lines 63 | position = "bottom", 64 | }, 65 | }, 66 | floating = { 67 | max_height = nil, -- These can be integers or a float between 0 and 1. 68 | max_width = nil, -- Floats will be treated as percentage of your screen. 69 | border = "single", -- Border style. Can be "single", "double" or "rounded" 70 | mappings = { 71 | close = { "q", "" }, 72 | }, 73 | }, 74 | windows = { indent = 1 }, 75 | render = { 76 | indent = 1, 77 | }, 78 | }) 79 | 80 | dap.listeners.after.event_initialized["dapui_config"] = function() 81 | dap_ui.open() 82 | end 83 | 84 | dap.listeners.before.event_terminated["dapui_config"] = function() 85 | dap_ui.close() 86 | end 87 | 88 | dap.listeners.before.event_exited["dapui_config"] = function() 89 | dap_ui.close() 90 | end 91 | 92 | require("plugins.dap.javascript") 93 | -------------------------------------------------------------------------------- /private_dot_config/nvim/coc-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "coc.preferences.formatOnSaveFiletypes": [ 3 | "css", 4 | "html", 5 | "javascript", 6 | "javascriptreact", 7 | "json", 8 | "jsonc", 9 | "lua", 10 | "markdown", 11 | "python", 12 | "rust", 13 | "scss", 14 | "typescript", 15 | "typescriptreact" 16 | ], 17 | // eslint 18 | "eslint.run": "onSave", 19 | "eslint.autoFixOnSave": true, 20 | // explorer 21 | "explorer.git.icon.rootStatus.added": "+", 22 | "explorer.git.icon.rootStatus.ahead": "⇡", 23 | "explorer.git.icon.rootStatus.behind": "⇣", 24 | "explorer.git.icon.rootStatus.conflicted": "=", 25 | "explorer.git.icon.rootStatus.deleted": "✘", 26 | "explorer.git.icon.rootStatus.modified": "!", 27 | "explorer.git.icon.rootStatus.renamed": "»", 28 | "explorer.git.icon.rootStatus.stashed": "≡", 29 | "explorer.git.icon.rootStatus.untracked": "?", 30 | "explorer.icon.enableNerdfont": true, 31 | "explorer.keyMappingMode": "none", 32 | "explorer.keyMappings.global": { 33 | "h": "collapse", 34 | "l": ["expandable?", "expand", "open"], 35 | "J": ["toggleSelection", "nodeNext"], 36 | "K": ["toggleSelection", "nodePrev"], 37 | "yn": "copyFilename", 38 | "yp": "copyFilepath", 39 | "yy": "copyFile", 40 | "p": "pasteFile", 41 | "dd": "cutFile", 42 | "df": "delete", 43 | "dF": "deleteForever", 44 | "a": "addFile", 45 | "A": "addDirectory", 46 | "r": "rename", 47 | "gp": "preview:labeling", 48 | "gq": "quit", 49 | "za": ["expanded?", "collapse", "expand"], 50 | "zA": ["expanded?", "collapse:recursive", "expand:recursive"], 51 | "zc": "collapse", 52 | "zC": "collapse:recursive", 53 | "zo": "expand", 54 | "zO": "expand:recursive", 55 | "zz": "reveal:select", 56 | "gr": "refresh", 57 | "g.": "toggleHidden", 58 | "g?": "help", 59 | "[c": "gitPrev", 60 | "]c": "gitNext", 61 | "{": "indentPrev", 62 | "}": "indentNext", 63 | "": "gotoParent", 64 | "": ["expandable?", "cd", "open"], 65 | "": "open:tab", 66 | "": "open:split", 67 | "": "open:vsplit" 68 | }, 69 | "explorer.previewAction.onHover": false, 70 | "explorer.quitOnOpen": true, 71 | "explorer.width": 40, 72 | // javascript 73 | "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, 74 | // lua 75 | "Lua.diagnostics.globals": ["vim"], 76 | "Lua.hint.enable": false, 77 | "Lua.runtime.path": ["?.lua", "lua/?.lua", "lua/?/init.lua"], 78 | "Lua.runtime.version": "LuaJIT", 79 | "Lua.telemetry.enable": false, 80 | "Lua.workspace.maxPreload": 10000, 81 | "Lua.workspace.preloadFileSize": 10000, 82 | // prettier 83 | "prettier.arrowParens": "always", 84 | "prettier.disableSuccessMessage": true, 85 | "prettier.singleQuote": true, 86 | "prettier.trailingComma": "es5", 87 | // python 88 | // typescript 89 | "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true 90 | } 91 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/init.lua: -------------------------------------------------------------------------------- 1 | local plugins = { 2 | -- appearance 3 | { "gruvbox-community/gruvbox" }, 4 | 5 | -- functionality 6 | { 7 | "andymass/vim-matchup", 8 | event = "BufReadPost", 9 | }, 10 | { "bkad/CamelCaseMotion" }, 11 | { 12 | "heavenshell/vim-jsdoc", 13 | ft = { 14 | "javascript", 15 | "javascriptreact", 16 | }, 17 | build = "make install", 18 | }, 19 | { "junegunn/vim-easy-align" }, 20 | { "powerman/vim-plugin-AnsiEsc" }, 21 | { 22 | "rrethy/vim-hexokinase", 23 | build = "make hexokinase", 24 | event = "BufReadPost", 25 | }, 26 | { "szw/vim-maximizer" }, 27 | { "tpope/vim-repeat" }, 28 | { "tpope/vim-sensible" }, 29 | { "tpope/vim-surround" }, 30 | { "tpope/vim-unimpaired" }, 31 | 32 | -- integration 33 | { 34 | "christoomey/vim-tmux-navigator", 35 | event = "VeryLazy", 36 | }, 37 | { 38 | "kristijanhusak/vim-carbon-now-sh", 39 | cmd = "CarbonNowSh", 40 | }, 41 | { 42 | "RyanMillerC/better-vim-tmux-resizer", 43 | event = "VeryLazy", 44 | }, 45 | { 46 | "wakatime/vim-wakatime", 47 | event = "VeryLazy", 48 | }, 49 | 50 | -- language support 51 | { 52 | "bronzehedwick/msmtp-syntax.vim", 53 | ft = "msmtp", 54 | }, 55 | { 56 | "chunkhang/vim-mbsync", 57 | ft = "mbsync", 58 | }, 59 | { 60 | "fladson/vim-kitty", 61 | ft = "kitty*", 62 | }, 63 | { 64 | "Fymyte/rasi.vim", 65 | ft = "rasi", 66 | }, 67 | { 68 | "lifepillar/pgsql.vim", 69 | ft = "sql", 70 | }, 71 | { 72 | "MeanderingProgrammer/render-markdown.nvim", 73 | dependencies = { 74 | "nvim-treesitter/nvim-treesitter", 75 | "nvim-tree/nvim-web-devicons", 76 | }, 77 | ---@type render.md.UserConfig 78 | opts = { 79 | completions = { 80 | lsp = { 81 | enabled = true, 82 | }, 83 | }, 84 | heading = { 85 | width = "block", 86 | }, 87 | sign = { 88 | enabled = false, 89 | }, 90 | }, 91 | }, 92 | { 93 | "mustache/vim-mustache-handlebars", 94 | ft = { "html.handlebars", "html.mustache" }, 95 | }, 96 | { 97 | "neoclide/jsonc.vim", 98 | ft = "jsonc", 99 | }, 100 | { 101 | "neomutt/neomutt.vim", 102 | ft = { "mail", "neomuttlog", "neomuttrc" }, 103 | }, 104 | { 105 | "tmux-plugins/vim-tmux", 106 | ft = "tmux", 107 | }, 108 | { 109 | "tpope/vim-git", 110 | ft = "git*", 111 | }, 112 | { "vitalk/vim-shebang" }, 113 | 114 | { 115 | "mbbill/undotree", 116 | cmd = "UndotreeToggle", 117 | init = function() 118 | vim.g.undotree_DiffAutoOpen = 0 119 | vim.g.undotree_SetFocusWhenToggle = 1 120 | vim.g.undotree_TreeNodeShape = "*" 121 | vim.g.undotree_TreeReturnShape = "╲" 122 | vim.g.undotree_TreeVertShape = "│" 123 | vim.g.undotree_TreeSplitShape = "╱" 124 | vim.g.undotree_ShortIndicators = 1 125 | vim.g.undotree_HelpLine = 0 126 | end, 127 | }, 128 | } 129 | 130 | return plugins 131 | -------------------------------------------------------------------------------- /dot_mbsyncrc.tmpl: -------------------------------------------------------------------------------- 1 | Create Slave 2 | Expunge Slave 3 | SyncState * 4 | 5 | IMAPAccount personal 6 | Host imap.gmail.com 7 | SSLType IMAPS 8 | SSLVersions TLSv1.2 9 | CertificateFile /etc/ssl/certs/ca-certificates.crt 10 | AuthMechs XOAUTH2 11 | User {{ template "bitwarden_chezmoi_config" "email.personal" }} 12 | PassCmd "gmail-oauth2 access_token personal" 13 | PipelineDepth 15 14 | 15 | IMAPStore personal-remote 16 | Account personal 17 | 18 | MaildirStore personal-local 19 | Path ~/.local/share/Mail/personal/ 20 | Inbox ~/.local/share/Mail/personal/Inbox 21 | SubFolders Verbatim 22 | 23 | Channel personal-inbox 24 | Master :personal-remote:"INBOX" 25 | Slave :personal-local:Inbox 26 | 27 | Channel personal-starred 28 | Master :personal-remote:"[Gmail]/Starred" 29 | Slave :personal-local:Starred 30 | 31 | Channel personal-sent 32 | Master :personal-remote:"[Gmail]/Sent Mail" 33 | Slave :personal-local:Sent 34 | 35 | Channel personal-drafts 36 | Master :personal-remote:"[Gmail]/Drafts" 37 | Slave :personal-local:Drafts 38 | 39 | Channel personal-trash 40 | Master :personal-remote:"[Gmail]/Trash" 41 | Slave :personal-local:Trash 42 | 43 | Channel personal-archive 44 | Master :personal-remote:"[Gmail]/All Mail" 45 | Slave :personal-local:Archive 46 | 47 | Channel personal-spam 48 | Master :personal-remote:"[Gmail]/Spam" 49 | Slave :personal-local:Spam 50 | 51 | Group personal 52 | Channel personal-inbox 53 | Channel personal-starred 54 | Channel personal-sent 55 | Channel personal-drafts 56 | Channel personal-trash 57 | Channel personal-archive 58 | Channel personal-spam 59 | 60 | IMAPAccount shopup 61 | Host imap.gmail.com 62 | SSLType IMAPS 63 | SSLVersions TLSv1.2 64 | CertificateFile /etc/ssl/certs/ca-certificates.crt 65 | AuthMechs XOAUTH2 66 | User {{ template "bitwarden_chezmoi_config" "email.shopup" }} 67 | PassCmd "gmail-oauth2 access_token {{ template "bitwarden_chezmoi_config" "email.shopup" }}" 68 | PipelineDepth 15 69 | 70 | IMAPStore shopup-remote 71 | Account shopup 72 | 73 | MaildirStore shopup-local 74 | Path ~/.local/share/Mail/shopup/ 75 | Inbox ~/.local/share/Mail/shopup/Inbox 76 | SubFolders Verbatim 77 | 78 | Channel shopup-inbox 79 | Master :shopup-remote:"INBOX" 80 | Slave :shopup-local:Inbox 81 | 82 | Channel shopup-starred 83 | Master :shopup-remote:"[Gmail]/Starred" 84 | Slave :shopup-local:Starred 85 | 86 | Channel shopup-sent 87 | Master :shopup-remote:"[Gmail]/Sent Mail" 88 | Slave :shopup-local:Sent 89 | 90 | Channel shopup-drafts 91 | Master :shopup-remote:"[Gmail]/Drafts" 92 | Slave :shopup-local:Drafts 93 | 94 | Channel shopup-trash 95 | Master :shopup-remote:"[Gmail]/Trash" 96 | Slave :shopup-local:Trash 97 | 98 | Channel shopup-archive 99 | Master :shopup-remote:"[Gmail]/All Mail" 100 | Slave :shopup-local:Archive 101 | 102 | Channel shopup-spam 103 | Master :shopup-remote:"[Gmail]/Spam" 104 | Slave :shopup-local:Spam 105 | 106 | Group shopup 107 | Channel shopup-inbox 108 | Channel shopup-starred 109 | Channel shopup-sent 110 | Channel shopup-drafts 111 | Channel shopup-trash 112 | Channel shopup-archive 113 | Channel shopup-spam 114 | 115 | # vim: filetype=mbsync 116 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/config/utils.lua: -------------------------------------------------------------------------------- 1 | local u = {} 2 | 3 | local local_git_dir = vim.fn.expand("$HOME/Dev") 4 | local git_host_by_provider = { 5 | github = "github.com", 6 | gitlab = "gitlab.com", 7 | } 8 | 9 | function u.dev_plugin(spec) 10 | if type(spec) == "string" then 11 | spec = { spec } 12 | end 13 | 14 | local git_provider = spec.git_provider 15 | if not git_provider or not git_host_by_provider[git_provider] then 16 | git_provider = "github" 17 | end 18 | 19 | local plugin_dir = string.format("%s/%s/%s", local_git_dir, git_provider, spec[1]) 20 | local plugin_url = string.format("https://%s/%s", git_host_by_provider[git_provider], spec[1]) 21 | if not vim.loop.fs_stat(plugin_dir) then 22 | local output = vim.fn.system({ "git", "clone", plugin_url, plugin_dir }) 23 | if vim.v.shell_error ~= 0 then 24 | vim.notify(output, vim.log.levels.ERROR) 25 | end 26 | end 27 | 28 | spec.dev = true 29 | spec.dir = plugin_dir 30 | spec.url = plugin_url 31 | 32 | return spec 33 | end 34 | 35 | ---@param server_name string 36 | ---@param settings_patcher fun(settings: table): table 37 | function u.patch_lsp_settings(server_name, settings_patcher) 38 | local function patch_settings(client) 39 | client.config.settings = settings_patcher(client.config.settings) 40 | client.notify("workspace/didChangeConfiguration", { 41 | settings = client.config.settings, 42 | }) 43 | end 44 | 45 | local clients = vim.lsp.get_clients({ name = server_name }) 46 | if #clients > 0 then 47 | patch_settings(clients[1]) 48 | return 49 | end 50 | 51 | vim.api.nvim_create_autocmd("LspAttach", { 52 | callback = function(args) 53 | local client = vim.lsp.get_client_by_id(args.data.client_id) 54 | if client and client.name == server_name then 55 | patch_settings(client) 56 | return true 57 | end 58 | end, 59 | }) 60 | end 61 | 62 | ---@param mode string|string[] 63 | ---@param lhs string 64 | ---@param rhs string|fun():nil 65 | ---@param desc_or_opts string|table 66 | ---@param opts? table 67 | function u.set_keymap(mode, lhs, rhs, desc_or_opts, opts) 68 | if not opts then 69 | opts = type(desc_or_opts) == "table" and desc_or_opts or { desc = desc_or_opts } 70 | else 71 | opts.desc = desc_or_opts 72 | end 73 | vim.keymap.set(mode, lhs, rhs, vim.tbl_extend("keep", opts, { silent = true })) 74 | end 75 | 76 | ---@param default_mode string|string[] 77 | ---@param maps ({[1]: string, [2]: string|(fun():nil), [3]?: string|table, [4]?: table}|table)[] 78 | ---@param fallback_opts? table 79 | function u.set_keymaps(default_mode, maps, fallback_opts) 80 | fallback_opts = fallback_opts or {} 81 | for _, map in ipairs(maps) do 82 | local mode, lhs, rhs, desc, opts = map.mode or default_mode, map[1], map[2], map[3], map[4] 83 | if not opts then 84 | opts = type(desc) == "table" and desc or { desc = desc } 85 | else 86 | opts.desc = desc 87 | end 88 | map.mode, map[1], map[2], map[3], map[4] = nil, nil, nil, nil, nil 89 | local ops = vim.tbl_extend("keep", map, opts, fallback_opts, { silent = true }) 90 | u.set_keymap(mode, lhs, rhs, ops) 91 | end 92 | end 93 | 94 | return u 95 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/luasnip/init.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "L3MON4D3/LuaSnip", 3 | build = "make install_jsregexp", 4 | dependencies = { 5 | "saadparwaiz1/cmp_luasnip", 6 | }, 7 | event = "InsertEnter", 8 | } 9 | 10 | function plugin.config() 11 | local u = require("config.utils") 12 | local ls = require("luasnip") 13 | local types = require("luasnip.util.types") 14 | 15 | local ft_extend_map = { 16 | javascriptreact = { "javascript" }, 17 | typescript = { "javascript" }, 18 | typescriptreact = { "javascript", "typescript", "javascriptreact" }, 19 | } 20 | 21 | for ft, extend_fts in pairs(ft_extend_map) do 22 | ls.filetype_extend(ft, extend_fts) 23 | end 24 | 25 | ls.config.setup({ 26 | ext_opts = { 27 | [types.choiceNode] = { 28 | active = { 29 | virt_text = { { "●", "GruvboxOrange" } }, 30 | hl_mode = "combine", 31 | }, 32 | }, 33 | [types.insertNode] = { 34 | active = { 35 | virt_text = { { "●", "GruvboxBlue" } }, 36 | hl_mode = "combine", 37 | }, 38 | }, 39 | }, 40 | region_check_events = "CursorMoved", 41 | update_events = "TextChanged,TextChangedI", 42 | load_ft_func = require("luasnip.extras.filetype_functions").extend_load_ft(ft_extend_map), 43 | }) 44 | 45 | local lsp_snippets_path = vim.fn.resolve(vim.fn.stdpath("config") .. "/snippets/lsp") 46 | if vim.fn.isdirectory(lsp_snippets_path) == 0 then 47 | print("[config] Missing LSP Snippets") 48 | else 49 | require("luasnip.loaders.from_vscode").lazy_load({ 50 | paths = { lsp_snippets_path }, 51 | }) 52 | end 53 | 54 | local luasnip_snippets_path = vim.fn.resolve(vim.fn.stdpath("config") .. "/snippets/luasnip") 55 | if vim.fn.isdirectory(luasnip_snippets_path) == 0 then 56 | print("[config] Missing LuaSnip Snippets") 57 | else 58 | require("luasnip.loaders.from_lua").lazy_load({ 59 | paths = { luasnip_snippets_path }, 60 | }) 61 | end 62 | 63 | u.set_keymaps({ "i", "s" }, { 64 | { 65 | "", 66 | function() 67 | if ls.jumpable(-1) then 68 | return "luasnip-jump-prev" 69 | end 70 | 71 | return "" 72 | end, 73 | "[snip] jump prev", 74 | }, 75 | { 76 | "", 77 | function() 78 | if ls.expand_or_jumpable() then 79 | return "luasnip-expand-or-jump" 80 | end 81 | 82 | return "" 83 | end, 84 | "[snip] expand or jump next", 85 | }, 86 | { 87 | "", 88 | function() 89 | if ls.expandable() then 90 | return "luasnip-expand-snippet" 91 | end 92 | 93 | if ls.choice_active() then 94 | return "luasnip-next-choice" 95 | end 96 | 97 | return "" 98 | end, 99 | "[snip] expand or next choice", 100 | remap = true, 101 | }, 102 | }, { 103 | expr = true, 104 | }) 105 | 106 | vim.api.nvim_create_user_command("LuaSnipEdit", function() 107 | require("luasnip.loaders").edit_snippet_files({}) 108 | end, {}) 109 | end 110 | 111 | return plugin 112 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/ui/alpha.lua: -------------------------------------------------------------------------------- 1 | local alpha = require("alpha") 2 | local fortune = require("alpha.fortune") 3 | 4 | local header = { 5 | type = "text", 6 | val = { 7 | [[ ███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ ]], 8 | [[ ████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║ ]], 9 | [[ ██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║ ]], 10 | [[ ██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ]], 11 | [[ ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ]], 12 | [[ ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ ]], 13 | }, 14 | opts = { 15 | position = "center", 16 | hl = "Identifier", 17 | }, 18 | } 19 | 20 | local footer = { 21 | type = "text", 22 | val = fortune(), 23 | opts = { 24 | position = "center", 25 | hl = "Constant", 26 | }, 27 | } 28 | 29 | local plugin_stats = { 30 | type = "text", 31 | val = {}, 32 | opts = { 33 | position = "center", 34 | hl = "Comment", 35 | }, 36 | } 37 | 38 | local leader = "" 39 | 40 | --- @param shortcut string 41 | --- @param text string 42 | --- @param action? string 43 | --- @param keymap_opts? table 44 | local function button(shortcut, text, action, keymap_opts) 45 | local key = shortcut:gsub("%s", ""):gsub(leader, "") 46 | 47 | local opts = { 48 | position = "center", 49 | shortcut = shortcut, 50 | cursor = 5, 51 | width = 50, 52 | align_shortcut = "right", 53 | hl_shortcut = "Type", 54 | } 55 | 56 | if action then 57 | keymap_opts = keymap_opts or { noremap = true, silent = true, nowait = true } 58 | opts.keymap = { "n", key, action, keymap_opts } 59 | end 60 | 61 | local function on_press() 62 | local key = vim.api.nvim_replace_termcodes(key .. "", true, false, true) 63 | vim.api.nvim_feedkeys(key, "t", false) 64 | end 65 | 66 | return { 67 | type = "button", 68 | val = text, 69 | on_press = on_press, 70 | opts = opts, 71 | } 72 | end 73 | 74 | local buttons = { 75 | type = "group", 76 | val = { 77 | button("e", " Empty File", "ene "), 78 | button("f", "󰱼 Find File", "Telescope find_files"), 79 | button("g", "󱎸 Live Grep", "Telescope live_grep"), 80 | button("o", "󱀲 Recently Opened Files", "Telescope oldfiles only_cwd=true"), 81 | button("p", " Plugins", "Lazy"), 82 | button("q", "✖ Quit", "q"), 83 | }, 84 | opts = { 85 | spacing = 1, 86 | }, 87 | } 88 | 89 | local section = { 90 | header = header, 91 | buttons = buttons, 92 | footer = footer, 93 | } 94 | 95 | local config = { 96 | layout = { 97 | { type = "padding", val = 2 }, 98 | section.header, 99 | { type = "padding", val = 2 }, 100 | section.buttons, 101 | section.footer, 102 | plugin_stats, 103 | }, 104 | opts = { 105 | margin = 5, 106 | }, 107 | } 108 | 109 | alpha.setup(config) 110 | 111 | vim.api.nvim_create_autocmd("User", { 112 | pattern = "LazyVimStarted", 113 | callback = function() 114 | local stats = require("lazy").stats() 115 | local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100) 116 | table.insert(plugin_stats.val, "") 117 | table.insert(plugin_stats.val, "[⚡ loaded " .. stats.count .. " plugins in " .. ms .. "ms]") 118 | pcall(vim.cmd.AlphaRedraw) 119 | end, 120 | }) 121 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/init.lua: -------------------------------------------------------------------------------- 1 | local u = require("config.utils") 2 | 3 | local plugins = { 4 | { 5 | "neovim/nvim-lspconfig", 6 | dependencies = { 7 | "b0o/schemastore.nvim", 8 | "folke/neodev.nvim", 9 | "hrsh7th/cmp-nvim-lsp", 10 | "onsails/lspkind-nvim", 11 | "yioneko/nvim-vtsls", 12 | { 13 | "mrcjkb/rustaceanvim", 14 | version = "^5", 15 | init = function() 16 | vim.g.rustaceanvim = { 17 | dap = { 18 | autoload_configurations = false, 19 | }, 20 | server = { 21 | on_attach = function(client, bufnr) 22 | require("plugins.lsp.utils").default_on_attach(client, bufnr) 23 | 24 | require("config.utils").set_keymaps("n", { 25 | { 26 | "", 27 | ":RustLsp moveItem up", 28 | "[lsp:rust] move up", 29 | }, 30 | { 31 | "", 32 | ":RustLsp moveItem down", 33 | "[lsp:rust] move down", 34 | }, 35 | }) 36 | end, 37 | default_settings = { 38 | ["rust-analyzer"] = {}, 39 | }, 40 | }, 41 | tools = {}, 42 | } 43 | end, 44 | }, 45 | { 46 | "williamboman/mason-lspconfig.nvim", 47 | dependencies = { 48 | "williamboman/mason.nvim", 49 | cmd = "Mason", 50 | opts = { 51 | ui = { border = "rounded" }, 52 | }, 53 | }, 54 | }, 55 | }, 56 | event = { "BufReadPre", "BufNewFile" }, 57 | config = function() 58 | require("plugins.lsp.base") 59 | end, 60 | }, 61 | { 62 | "nvimtools/none-ls.nvim", -- "jose-elias-alvarez/null-ls.nvim" 63 | dependencies = { 64 | "nvimtools/none-ls-extras.nvim", 65 | "gbprod/none-ls-luacheck.nvim", 66 | u.dev_plugin("MunifTanjim/eslint.nvim"), 67 | u.dev_plugin("MunifTanjim/prettier.nvim"), 68 | }, 69 | event = "BufReadPre", 70 | config = function() 71 | require("plugins.lsp.null-ls") 72 | end, 73 | }, 74 | { 75 | "kosayoda/nvim-lightbulb", 76 | event = "LspAttach", 77 | config = function() 78 | require("plugins.lsp.lightbulb") 79 | end, 80 | }, 81 | { 82 | "folke/trouble.nvim", 83 | event = "LspAttach", 84 | keys = { 85 | { 86 | "xx", 87 | "TroubleToggle", 88 | desc = "toggle trouble", 89 | }, 90 | }, 91 | opts = { 92 | action_keys = { 93 | close = "gq", 94 | }, 95 | }, 96 | }, 97 | { 98 | "saecki/crates.nvim", 99 | event = "BufRead Cargo.toml", 100 | config = function() 101 | local crates = require("crates") 102 | crates.setup({ 103 | on_attach = function(bufnr) 104 | require("config.utils").set_keymap("n", "K", function() 105 | if crates.popup_available() then 106 | crates.show_popup() 107 | else 108 | vim.lsp.buf.hover() 109 | end 110 | end, "[lsp] hover", { buffer = bufnr }) 111 | end, 112 | null_ls = { 113 | enabled = true, 114 | name = "crates.nvim", 115 | }, 116 | }) 117 | end, 118 | }, 119 | } 120 | 121 | return plugins 122 | -------------------------------------------------------------------------------- /private_dot_config/nvim/vscode.vim: -------------------------------------------------------------------------------- 1 | " vim: set foldmethod=marker foldmarker=[[[,]]] foldlevel=0 nomodeline : 2 | 3 | set noloadplugins 4 | 5 | " [[[ General Settings 6 | 7 | " and 8 | let mapleader = "\" 9 | let maplocalleader = "\\" 10 | 11 | " General Settings ]]] 12 | 13 | " [[[ General Keymaps 14 | 15 | " beginning/end of line 16 | nnoremap B ^ 17 | nnoremap E $ 18 | onoremap B ^ 19 | onoremap E $ 20 | xnoremap B ^ 21 | xnoremap E $ 22 | 23 | " save 24 | nnoremap s :call VSCodeNotify('workbench.action.files.save') 25 | nnoremap js :call VSCodeNotify('workbench.action.files.saveWithoutFormatting') 26 | 27 | " yank from the cursor position to the end of the line 28 | nnoremap Y y$ 29 | " yank/paste with system clipboard 30 | nnoremap y "+y 31 | vnoremap y "+y 32 | nnoremap Y "+y$ 33 | vnoremap Y "+y$ 34 | nnoremap p "+p 35 | vnoremap p "+p 36 | nnoremap P "+P 37 | vnoremap P "+P 38 | 39 | " General Keymaps ]]] 40 | 41 | " [[[ Plugins 42 | 43 | " install vim-plug automagically 44 | let plug_path = stdpath('data') . '/site/pack/vscode/opt/plug/autoload/plug.vim' 45 | if empty(glob(plug_path)) 46 | silent execute '!curl -fLo ' . plug_path . ' --create-dirs ' 47 | \ . 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' 48 | autocmd VimEnter * packadd plug | PlugInstall --sync | execute 'source ' . expand('') 49 | else 50 | packadd plug 51 | endif 52 | 53 | call plug#begin(stdpath('data') . '/site/pack/vscode/opt') 54 | 55 | Plug 'junegunn/vim-plug' 56 | 57 | Plug 'tpope/vim-sensible' 58 | Plug 'tpope/vim-surround' 59 | 60 | call plug#end() 61 | 62 | " [[[ Plugin: vscode-neovim 63 | 64 | " remove move editor mappings 65 | nunmap 66 | xunmap 67 | nunmap 68 | xunmap 69 | nunmap 70 | xunmap 71 | nunmap 72 | xunmap 73 | 74 | " vim-commentary equivalent 75 | xmap gc VSCodeCommentary 76 | nmap gc VSCodeCommentary 77 | omap gc VSCodeCommentary 78 | nmap gcc VSCodeCommentaryLine 79 | 80 | " Plugin: vscode-neovim ]]] 81 | 82 | " Plugins ]]] 83 | 84 | " [[[ VSCode Keymaps 85 | 86 | noremap e :call VSCodeNotify('workbench.action.toggleSidebarVisibility') 87 | 88 | " window navigation 89 | nnoremap j :call VSCodeNotify('workbench.action.navigateDown') 90 | xnoremap j :call VSCodeNotify('workbench.action.navigateDown') 91 | nnoremap k :call VSCodeNotify('workbench.action.navigateUp') 92 | xnoremap k :call VSCodeNotify('workbench.action.navigateUp') 93 | nnoremap h :call VSCodeNotify('workbench.action.navigateLeft') 94 | xnoremap h :call VSCodeNotify('workbench.action.navigateLeft') 95 | nnoremap l :call VSCodeNotify('workbench.action.navigateRight') 96 | xnoremap l :call VSCodeNotify('workbench.action.navigateRight') 97 | 98 | " window split 99 | nnoremap - :New 100 | xnoremap - :New 101 | nnoremap \ :Vnew 102 | xnoremap \ :Vnew 103 | 104 | " code navigation 105 | nmap gd :call VSCodeNotify('editor.action.revealDefinition') 106 | nmap gy :call VSCodeNotify('editor.action.goToTypeDefinition') 107 | nmap gi :call VSCodeNotify('editor.action.goToImplementation') 108 | nmap gr :call VSCodeNotify('editor.action.goToReferences') 109 | 110 | " rename symbol 111 | nmap rn :call VSCodeNotify('editor.action.rename') 112 | 113 | " VSCode Keymaps ]]] 114 | -------------------------------------------------------------------------------- /private_dot_config/starship/config.toml: -------------------------------------------------------------------------------- 1 | "$schema" = 'https://starship.rs/config-schema.json' 2 | 3 | add_newline = false 4 | format = '$all' 5 | 6 | [aws] 7 | disabled = true 8 | symbol = ' ' 9 | 10 | [battery] 11 | full_symbol = '󰁹' 12 | charging_symbol = '󰂄' 13 | discharging_symbol = '󰂃' 14 | format = '[$symbol\[$percentage\]]($style) ' 15 | 16 | [[battery.display]] 17 | style = 'bold bright-red' 18 | threshold = 15 19 | 20 | [[battery.display]] 21 | style = 'bold bright-yellow' 22 | threshold = 30 23 | 24 | [character] 25 | error_symbol = '[❯](bold bright-red)' 26 | success_symbol = '[❯](bold bright-green)' 27 | vimcmd_symbol = '[❮](bold bright-green)' 28 | 29 | [cmake] 30 | disabled = true 31 | 32 | [cmd_duration] 33 | min_time = 5000 34 | 35 | [conda] 36 | disabled = true 37 | symbol = ' ' 38 | 39 | [crystal] 40 | disabled = true 41 | 42 | [dart] 43 | disabled = true 44 | symbol = ' ' 45 | 46 | [directory] 47 | format = '[$read_only](red)[$path](bold bright-cyan) ' 48 | read_only = ' ' 49 | truncation_symbol = '…/' 50 | 51 | [docker_context] 52 | disabled = true 53 | symbol = ' ' 54 | 55 | [dotnet] 56 | disabled = true 57 | symbol = ' ' 58 | 59 | [elixir] 60 | disabled = true 61 | symbol = ' ' 62 | 63 | [elm] 64 | disabled = true 65 | symbol = ' ' 66 | 67 | [erlang] 68 | disabled = true 69 | symbol = ' ' 70 | 71 | [gcloud] 72 | disabled = true 73 | symbol = ' ' 74 | 75 | [git_branch] 76 | format = '[( $branch )](bold bright-purple)' 77 | 78 | [git_commit] 79 | format = '[( $hash)](bold bright-blue)[($tag) ](bold bright-green)' 80 | commit_hash_length = 8 81 | tag_disabled = false 82 | tag_symbol = ' ' 83 | 84 | [git_state] 85 | format = '[($state\($progress_current/$progress_total\) )](bold bright-red)' 86 | 87 | [git_status] 88 | format = '[(\[$all_status$ahead_behind\] )](bold bright-yellow)' 89 | conflicted = '=${count}' 90 | ahead = '⇡${count}' 91 | behind = '⇣${count}' 92 | diverged = '⇕⇡${ahead_count}⇣${behind_count}' 93 | untracked = '?${count}' 94 | stashed = '≡${count}' 95 | modified = '!${count}' 96 | staged = '+${count}' 97 | renamed = '»${count}' 98 | deleted = '✘${count}' 99 | 100 | [golang] 101 | symbol = ' ' 102 | 103 | [helm] 104 | disabled = true 105 | symbol = '⎈ ' 106 | 107 | [hg_branch] 108 | disabled = true 109 | symbol = ' ' 110 | 111 | [hostname] 112 | trim_at = '' 113 | 114 | [java] 115 | disabled = true 116 | symbol = ' ' 117 | 118 | [jobs] 119 | symbol = ' ' 120 | 121 | [julia] 122 | disabled = true 123 | symbol = ' ' 124 | 125 | [kubernetes] 126 | disabled = true 127 | symbol = '☸ ' 128 | 129 | [memory_usage] 130 | symbol = '󰍛 ' 131 | 132 | [nim] 133 | disabled = true 134 | symbol = ' ' 135 | 136 | [nix_shell] 137 | disabled = true 138 | symbol = ' ' 139 | 140 | [nodejs] 141 | symbol = ' ' 142 | 143 | [package] 144 | symbol = ' ' 145 | 146 | [perl] 147 | disabled = false 148 | symbol = ' ' 149 | 150 | [php] 151 | disabled = true 152 | symbol = ' ' 153 | 154 | [purescript] 155 | disabled = true 156 | 157 | [python] 158 | symbol = ' ' 159 | format = 'via [${symbol}${pyenv_prefix}(${version} )(\(${virtualenv}\) )]($style)' 160 | 161 | [ocaml] 162 | disabled = true 163 | symbol = '🐫 ' 164 | 165 | [ruby] 166 | symbol = ' ' 167 | 168 | [rust] 169 | symbol = ' ' 170 | 171 | [shlvl] 172 | disabled = true 173 | 174 | [singularity] 175 | disabled = true 176 | 177 | [status] 178 | disabled = false 179 | format = '[${status}](bold bright-red) ' 180 | 181 | [swift] 182 | disabled = true 183 | symbol = ' ' 184 | 185 | [terraform] 186 | disabled = true 187 | symbol = '󱁢 ' 188 | 189 | [time] 190 | disabled = true 191 | 192 | [username] 193 | disabled = false 194 | 195 | [zig] 196 | disabled = true 197 | symbol = ' ' 198 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/config/color.lua: -------------------------------------------------------------------------------- 1 | local function get_gruvbox() 2 | local gruvbox = { 3 | dark0_hard = "#1d2021", 4 | dark0 = "#282828", 5 | dark0_soft = "#32302f", 6 | dark1 = "#3c3836", 7 | dark2 = "#504945", 8 | dark3 = "#665c54", 9 | dark4 = "#7c6f64", 10 | 11 | light0_hard = "#f9f5d7", 12 | light0 = "#fbf1c7", 13 | light0_soft = "#f2e5bc", 14 | light1 = "#ebdbb2", 15 | light2 = "#d5c4a1", 16 | light3 = "#bdae93", 17 | light4 = "#a89984", 18 | 19 | bright = { 20 | gray = "#a89984", 21 | red = "#fb4934", 22 | green = "#b8bb26", 23 | yellow = "#fabd2f", 24 | blue = "#83a598", 25 | purple = "#d3869b", 26 | aqua = "#8ec07c", 27 | orange = "#f38019", 28 | }, 29 | 30 | neutral = { 31 | gray = "#928374", 32 | red = "#cc241d", 33 | green = "#98971a", 34 | yellow = "#d79921", 35 | blue = "#458588", 36 | purple = "#b16286", 37 | aqua = "#689d6a", 38 | orange = "#d65d0e", 39 | }, 40 | 41 | faded = { 42 | gray = "#7c6f64", 43 | red = "#9d0006", 44 | green = "#79740e", 45 | yellow = "#b57614", 46 | blue = "#076678", 47 | purple = "#8f3f71", 48 | aqua = "#427b58", 49 | orange = "#af3a03", 50 | }, 51 | } 52 | 53 | gruvbox.dark = { 54 | bg = gruvbox.dark0, 55 | bg0_h = gruvbox.dark0_hard, 56 | bg0 = gruvbox.dark0, 57 | bg0_s = gruvbox.dark0_soft, 58 | bg1 = gruvbox.dark1, 59 | bg2 = gruvbox.dark2, 60 | bg3 = gruvbox.dark3, 61 | bg4 = gruvbox.dark4, 62 | 63 | gray = gruvbox.neutral.gray, 64 | 65 | fg = gruvbox.light1, 66 | fg0 = gruvbox.light0, 67 | fg1 = gruvbox.light1, 68 | fg2 = gruvbox.light2, 69 | fg3 = gruvbox.light3, 70 | fg4 = gruvbox.light4, 71 | 72 | lightgray = gruvbox.light4, 73 | 74 | red = gruvbox.bright.red, 75 | green = gruvbox.bright.green, 76 | yellow = gruvbox.bright.yellow, 77 | blue = gruvbox.bright.blue, 78 | purple = gruvbox.bright.purple, 79 | aqua = gruvbox.bright.aqua, 80 | orange = gruvbox.bright.orange, 81 | 82 | accent = { 83 | red = gruvbox.neutral.red, 84 | green = gruvbox.neutral.green, 85 | yellow = gruvbox.neutral.yellow, 86 | blue = gruvbox.neutral.blue, 87 | purple = gruvbox.neutral.purple, 88 | aqua = gruvbox.neutral.aqua, 89 | orange = gruvbox.neutral.orange, 90 | }, 91 | } 92 | 93 | gruvbox.light = { 94 | bg = gruvbox.light0, 95 | bg0_h = gruvbox.light0_hard, 96 | bg0 = gruvbox.light0, 97 | bg0_s = gruvbox.light0_soft, 98 | bg1 = gruvbox.light1, 99 | bg2 = gruvbox.light2, 100 | bg3 = gruvbox.light3, 101 | bg4 = gruvbox.light4, 102 | 103 | gray = gruvbox.neutral.gray, 104 | 105 | fg = gruvbox.dark1, 106 | fg0 = gruvbox.dark0, 107 | fg1 = gruvbox.dark1, 108 | fg2 = gruvbox.dark2, 109 | fg3 = gruvbox.dark3, 110 | fg4 = gruvbox.dark4, 111 | 112 | darkgray = gruvbox.dark4, 113 | 114 | red = gruvbox.faded.purple, 115 | green = gruvbox.faded.green, 116 | yellow = gruvbox.faded.yellow, 117 | blue = gruvbox.faded.blue, 118 | purple = gruvbox.faded.purple, 119 | aqua = gruvbox.faded.aqua, 120 | orange = gruvbox.faded.orange, 121 | 122 | accent = { 123 | red = gruvbox.neutral.red, 124 | green = gruvbox.neutral.green, 125 | yellow = gruvbox.neutral.yellow, 126 | blue = gruvbox.neutral.blue, 127 | purple = gruvbox.neutral.purple, 128 | aqua = gruvbox.neutral.aqua, 129 | orange = gruvbox.neutral.orange, 130 | }, 131 | } 132 | 133 | return gruvbox 134 | end 135 | 136 | local color = get_gruvbox() 137 | color.dark.bg = color.dark.bg0_h 138 | 139 | color.gruvbox = get_gruvbox 140 | 141 | return color 142 | -------------------------------------------------------------------------------- /private_dot_config/neomutt/muttrc: -------------------------------------------------------------------------------- 1 | set alias_file = "~/.local/share/neomutt/alias" 2 | set header_cache = "~/.cache/neomutt/headers" 3 | set message_cachedir = "~/.cache/neomutt/bodies" 4 | set mailcap_path = "~/.local/share/neomutt/mailcap" 5 | set tmpdir = "~/.cache/neomutt/tmp" 6 | set certificate_file = "/etc/ssl/certs/ca-certificates.crt" 7 | 8 | source "~/.config/neomutt/bindings" 9 | source "~/.config/neomutt/colors" 10 | 11 | # account setup 12 | folder-hook personal/* source "~/.config/neomutt/accounts/personal/config" 13 | folder-hook shopup/* source "~/.config/neomutt/accounts/shopup/config" 14 | 15 | source "~/.config/neomutt/accounts/personal/config" 16 | 17 | # basic options 18 | set mbox_type = Maildir # mailbox type 19 | set mark_old = no # read/new is good enough for me 20 | set beep_new # bell on new mails 21 | set wait_key = yes 22 | set timeout = 3 # idle time before scanning 23 | set mail_check_stats 24 | set pipe_decode # strip headers and eval mimes when piping 25 | set thorough_search # strip headers and eval mimes before searching 26 | 27 | # compose View Options 28 | set editor = "nvim" 29 | set envelope_from # which from? 30 | set edit_headers # show headers when composing 31 | set fast_reply = no 32 | set askcc # ask for CC: 33 | set fcc_attach # save attachments with the body 34 | set forward_format = "Fwd: %s" # format of subject when forwarding 35 | set forward_decode # decode when forwarding 36 | set attribution = "On %d, %n wrote:" # format of quoting header 37 | set reply_to # reply to Reply to: field 38 | set reverse_name # reply as whomever it was to 39 | set include # include message in replies 40 | set forward_quote # include message in forwards 41 | set text_flowed # eliminate odd line breaks 42 | set sig_dashes = no # no dashes before sig 43 | set mime_forward = no # forward attachments as part of body 44 | 45 | # indicator characters 46 | ifdef crypt_chars set crypt_chars = " " 47 | set flag_chars = "" 48 | set status_chars = "罹" 49 | set to_chars = "ﴤ" 50 | set date_format = "%Y-%m-%d %H:%M" 51 | 52 | # status bars 53 | set status_on_top = yes 54 | set attach_format = "%u%D  %T%-75.75d %?T?%& ? %5s · %m/%M" 55 | set index_format = " %zs %zc %zt %D · %-28.28L %?M?(%1M)& ? %?X?&·? %s" 56 | set pager_format = " %n %zc %T %s%*  %D %?X? %X ? %P ☰" 57 | set status_format = "[%f] %?r?%r ? %m %?u? %u ?%?d? %d ?%?t? %t ?%?F? %F ?%?p? %p ?%> (%s/%S)[%P]" 58 | set vfolder_format = " %N %?n?%3n& ? %8m 﫮 · %f" 59 | 60 | set sort = threads 61 | set sort_aux = reverse-last-date-received 62 | set uncollapse_jump 63 | set sort_re 64 | set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*" 65 | set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+" 66 | set send_charset = "utf-8:iso-8859-1:us-ascii" 67 | set charset = "utf-8" 68 | 69 | # pager view options 70 | set pager_index_lines = 10 71 | set pager_context = 3 72 | set pager_stop 73 | set menu_scroll 74 | set tilde 75 | unset markers 76 | 77 | # email headers and attachments 78 | ignore * 79 | unignore from to cc bcc date subject 80 | unignore organization organisation x-mailer: x-newsreader: x-mailing-list: mailing-list: 81 | unignore posted-to: 82 | unhdr_order * 83 | hdr_order date: from: to: cc: bcc: subject: 84 | alternative_order text/plain text/enriched text/html 85 | 86 | # sidebar 87 | set sidebar_visible = no 88 | set sidebar_short_path = yes 89 | set sidebar_delim_chars = "/" 90 | set sidebar_folder_indent = yes 91 | set sidebar_indent_string = ' ' 92 | set sidebar_width = 25 93 | set sidebar_divider_char = '│' 94 | set sidebar_format = "%B %* [%?N?%N / ?%S]" 95 | 96 | # vim: filetype=muttrc 97 | -------------------------------------------------------------------------------- /.chezmoiscripts/.00_helpers.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CHEZMOI_SOURCE="${HOME}/.local/share/chezmoi" 4 | export PATH="${CHEZMOI_SOURCE}/.scripts.sh:${PATH}" 5 | 6 | declare -r red='\033[0;31m' 7 | declare -r green='\033[0;32m' 8 | declare -r orange='\033[0;33m' 9 | declare -r blue='\033[0;34m' 10 | declare -r normal='\033[0m' # No Color 11 | 12 | echo_error() { 13 | printf "${red}[error] ${normal}$@\n" 14 | } 15 | 16 | echo_info() { 17 | printf "${blue}[info] ${normal}$@\n" 18 | } 19 | 20 | echo_warn() { 21 | printf "${orange}[warn] ${normal}$@\n" 22 | } 23 | 24 | command_exists() { 25 | type "${1}" >/dev/null 2>&1 26 | } 27 | 28 | ask_sudo() { 29 | echo_info "running this script would need 'sudo' permission." 30 | echo "" 31 | 32 | sudo -v 33 | 34 | # keep sudo permission fresh 35 | while true; do 36 | sudo -n true 37 | sleep 60 38 | kill -0 "$$" || exit 39 | done 2>/dev/null & 40 | } 41 | 42 | is_darwin() { 43 | [[ $OSTYPE = darwin* ]] 44 | } 45 | 46 | is_linux() { 47 | [[ $OSTYPE = linux* ]] 48 | } 49 | 50 | is_arm64() { 51 | local -r arch="$(uname -m)" 52 | test "${arch}" = "arm64" || test "${arch}" = "aarch64" 53 | } 54 | 55 | is_github_codespace() { 56 | local -r bool="$(chezmoi execute-template '{{ get .meta.is "github_codespace" }}')" 57 | test "${bool}" = "true" 58 | } 59 | 60 | is_headless_machine() { 61 | local -r bool="$(chezmoi execute-template '{{ get .meta.is "headless_machine" }}')" 62 | test "${bool}" = "true" 63 | } 64 | 65 | is_personal_machine() { 66 | local -r bool="$(chezmoi execute-template '{{ get .meta.is "personal_machine" }}')" 67 | test "${bool}" = "true" 68 | } 69 | 70 | should_include_secrets() { 71 | local -r bool="$(chezmoi execute-template '{{ get .meta.should "include_secrets" }}')" 72 | test "${bool}" = "true" 73 | } 74 | 75 | ensure_darwin() { 76 | if ! is_darwin; then 77 | echo_error "unexpected os (${OSTYPE}), expected darwin!" 78 | exit 1 79 | fi 80 | } 81 | 82 | ensure_linux() { 83 | if ! is_linux; then 84 | echo_error "unexpected os (${OSTYPE}), expected linux!" 85 | exit 1 86 | fi 87 | } 88 | 89 | ensure_secret_manager() { 90 | if ! should_include_secrets; then 91 | echo_warn "skipping ensure_secret_manager" 92 | return 0 93 | fi 94 | 95 | if ! command_exists bw; then 96 | echo_info "installing secret manager" 97 | setup-bitwarden-cli 98 | fi 99 | 100 | local status="$(bw status)" 101 | status="${status##*\"status\":\"}" 102 | status="${status%%\"*}" 103 | 104 | if [[ $status = "unauthenticated" ]]; then 105 | echo "secret manager is not authenticated, run:" 106 | echo "" 107 | echo " bw login" 108 | echo "" 109 | echo "and then to unlock, run:" 110 | echo "" 111 | echo " export BW_SESSION=\$(bw unlock --raw)" 112 | echo "" 113 | exit 1 114 | fi 115 | 116 | if [[ $status = "locked" ]]; then 117 | echo "secret manager is locked, run:" 118 | echo "" 119 | echo " export BW_SESSION=\$(bw unlock --raw)" 120 | echo "" 121 | exit 1 122 | fi 123 | 124 | if [[ $status != "unlocked" ]]; then 125 | echo "secret manager is not unlocked" 126 | echo "" 127 | exit 1 128 | fi 129 | } 130 | 131 | ensure_github_cli_login() { 132 | if ! command_exists gh; then 133 | echo_info "installing github cli" 134 | setup-gh 135 | fi 136 | 137 | if ! gh auth status --hostname github.com >/dev/null 2>&1; then 138 | echo_info "initiating github cli login" 139 | gh auth login --hostname github.com --git-protocol https --web 140 | fi 141 | } 142 | 143 | TASK() { 144 | local -r str="$1" 145 | local -r str_len=$((4 + ${#str})) 146 | local -r char="${2:-"="}" 147 | 148 | echo "" 149 | echo "$(printf '%*s' "${str_len}" | tr ' ' "${char}")" 150 | echo "$char $str $char" 151 | echo "$(printf '%*s' "${str_len}" | tr ' ' "${char}")" 152 | echo "" 153 | } 154 | 155 | SUB_TASK() { 156 | local -r str="$1" 157 | local -r char="${2:-"="}" 158 | 159 | echo "" 160 | echo "$char" 161 | echo "$str" 162 | echo "$char" 163 | echo "" 164 | } 165 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/cmp.lua: -------------------------------------------------------------------------------- 1 | local plugin = { 2 | "hrsh7th/nvim-cmp", 3 | dependencies = { 4 | "hrsh7th/cmp-buffer", 5 | "hrsh7th/cmp-cmdline", 6 | "hrsh7th/cmp-nvim-lsp", 7 | "hrsh7th/cmp-path", 8 | "onsails/lspkind-nvim", 9 | }, 10 | event = "InsertEnter", 11 | } 12 | 13 | local function has_words_before() 14 | local line, col = unpack(vim.api.nvim_win_get_cursor(0)) 15 | return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil 16 | end 17 | 18 | function plugin.config() 19 | local cmp = require("cmp") 20 | local luasnip = require("luasnip") 21 | local lspkind = require("lspkind") 22 | 23 | vim.o.completeopt = "menu,menuone,noselect" 24 | 25 | ---@diagnostic disable-next-line: redundant-parameter 26 | cmp.setup({ 27 | completion = { 28 | autocomplete = false, 29 | completeopt = vim.o.completeopt, 30 | }, 31 | experimental = { 32 | ghost_text = true, 33 | }, 34 | formatting = { 35 | format = lspkind.cmp_format({ 36 | with_text = true, 37 | menu = { 38 | buffer = "[buf]", 39 | luasnip = "[snip]", 40 | nvim_lsp = "[lsp]", 41 | nvim_lua = "[vim]", 42 | path = "[path]", 43 | }, 44 | }), 45 | }, 46 | mapping = { 47 | [""] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), 48 | [""] = cmp.mapping(function(fallback) 49 | if require("copilot.suggestion").is_visible() then 50 | require("copilot.suggestion").accept() 51 | elseif cmp.visible() then 52 | cmp.select_next_item({ behavior = cmp.SelectBehavior.Insert }) 53 | elseif luasnip.expandable() then 54 | luasnip.expand() 55 | elseif has_words_before() then 56 | cmp.complete({ reason = cmp.ContextReason.Manual }) 57 | else 58 | fallback() 59 | end 60 | end, { "i", "s" }), 61 | [""] = cmp.mapping(function(fallback) 62 | if cmp.visible() then 63 | cmp.select_prev_item({ behavior = cmp.SelectBehavior.Insert }) 64 | else 65 | fallback() 66 | end 67 | end, { "i", "s" }), 68 | [""] = cmp.mapping.confirm({ select = true }), 69 | [""] = cmp.mapping.abort(), 70 | [""] = cmp.mapping(function(fallback) 71 | if cmp.visible() then 72 | cmp.close() 73 | elseif require("copilot.suggestion").is_visible() then 74 | require("copilot.suggestion").dismiss() 75 | else 76 | fallback() 77 | end 78 | end), 79 | [""] = cmp.mapping.scroll_docs(3), 80 | [""] = cmp.mapping.scroll_docs(-3), 81 | }, 82 | snippet = { 83 | expand = function(args) 84 | luasnip.lsp_expand(args.body) 85 | end, 86 | }, 87 | sources = cmp.config.sources({ 88 | { name = "nvim_lsp", priority = 3 }, 89 | { name = "luasnip", priority = 1 }, 90 | }, { 91 | { name = "buffer" }, 92 | }), 93 | }) 94 | 95 | local cmdline_mapping = cmp.mapping.preset.cmdline({ 96 | [""] = { 97 | c = cmp.mapping.confirm({ select = true }), 98 | }, 99 | [""] = { 100 | c = function() 101 | if not cmp.close() then 102 | vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", true, true, true), "n", true) 103 | end 104 | end, 105 | }, 106 | }) 107 | 108 | cmp.setup.cmdline("/", { 109 | mapping = cmdline_mapping, 110 | sources = { 111 | { name = "buffer" }, 112 | }, 113 | }) 114 | 115 | cmp.setup.cmdline(":", { 116 | mapping = cmdline_mapping, 117 | sources = cmp.config.sources({ 118 | { name = "path" }, 119 | }, { 120 | { name = "cmdline" }, 121 | }), 122 | }) 123 | 124 | cmp.event:on("menu_opened", function() 125 | vim.api.nvim_buf_set_var(0, "copilot_suggestion_hidden", true) 126 | end) 127 | 128 | cmp.event:on("menu_closed", function() 129 | vim.api.nvim_buf_set_var(0, "copilot_suggestion_hidden", false) 130 | end) 131 | end 132 | 133 | return plugin 134 | -------------------------------------------------------------------------------- /dot_bashrc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # return if not interactive shell 4 | if [[ $- != *i* ]]; then 5 | return 6 | fi 7 | 8 | if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then 9 | debian_chroot=$(cat /etc/debian_chroot) 10 | fi 11 | 12 | if [ -x /usr/bin/lesspipe ]; then 13 | eval "$(SHELL=/bin/sh lesspipe)" 14 | fi 15 | 16 | # {{{ env 17 | export XDG_CACHE_HOME="${HOME}/.cache" 18 | export XDG_CONFIG_HOME="${HOME}/.config" 19 | export XDG_DATA_HOME="${HOME}/.local/share" 20 | export XDG_STATE_HOME="${HOME}/.local/state" 21 | 22 | export EDITOR="vim" 23 | export VISUAL="nvim" 24 | export PAGER="less" 25 | export MANPAGER="less -R" 26 | # env }}} 27 | 28 | export DOTFILES="${HOME}/.local/share/chezmoi" 29 | export DOTFILES_MODULES="${DOTFILES}/.modules" 30 | 31 | export PATH="${HOME}/.local/bin:${DOTFILES}/.scripts.sh:${PATH}" 32 | 33 | # {{{ tools 34 | export CARGO_HOME="${XDG_DATA_HOME}/cargo" 35 | export RUSTUP_HOME="${XDG_DATA_HOME}/rustup" 36 | export FNM_DIR="${XDG_DATA_HOME}/fnm" 37 | export GOLANG_DIR="${XDG_DATA_HOME}/golang" 38 | export LUVER_DIR="${XDG_DATA_HOME}/luver" 39 | export PYENV_ROOT="${HOME}/.pyenv" 40 | export RBENV_ROOT="${HOME}/.rbenv" 41 | # tools }}} 42 | 43 | # {{{ completion 44 | if [ -f /etc/bash_completion ]; then 45 | source /etc/bash_completion 46 | elif [ -r /usr/local/etc/profile.d/bash_completion.sh ]; then 47 | source /usr/local/etc/profile.d/bash_completion.sh 48 | fi 49 | # completion }}} 50 | 51 | # sensible defaults 52 | if [ -f "${DOTFILES_MODULES}/.bash-sensible/sensible.bash" ]; then 53 | source "${DOTFILES_MODULES}/.bash-sensible/sensible.bash" 54 | fi 55 | 56 | source "${DOTFILES_MODULES}/helpers.sh" 57 | source "${DOTFILES_MODULES}/aliases.sh" 58 | source "${DOTFILES_MODULES}/fzf.plugin.sh" 59 | source "${DOTFILES_MODULES}/go.plugin.sh" 60 | source "${DOTFILES_MODULES}/gpg.plugin.sh" 61 | source "${DOTFILES_MODULES}/lf.plugin.sh" 62 | source "${DOTFILES_MODULES}/bash/plugins/luver.plugin.bash" 63 | source "${DOTFILES_MODULES}/node.plugin.sh" 64 | source "${DOTFILES_MODULES}/python.plugin.sh" 65 | source "${DOTFILES_MODULES}/ruby.plugin.sh" 66 | source "${DOTFILES_MODULES}/rust.plugin.sh" 67 | 68 | source "${DOTFILES_MODULES}/machine.local.plugin.sh" 69 | 70 | # {{{ appearance 71 | if [ -x /usr/bin/dircolors ]; then 72 | _dircolors_file="${DOTFILES_MODULES}/.dircolors-solarized/dircolors.256dark" 73 | test -r "${_dircolors_file}" && eval "$(dircolors -b "${_dircolors_file}")" || eval "$(dircolors -b)" 74 | fi 75 | 76 | alias dir='dir --color=auto' 77 | alias vdir='vdir --color=auto' 78 | alias grep='grep --color=auto' 79 | alias grep='grep --color=auto' 80 | alias fgrep='fgrep --color=auto' 81 | alias egrep='egrep --color=auto' 82 | 83 | export GREP_COLOR='1;33' 84 | 85 | # colored GCC warnings and errors 86 | export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' 87 | # appearance }}} 88 | 89 | # {{{ ls 90 | if command_exists eza; then 91 | declare -g eza_params=("--git" "--icons" "--classify" "--group-directories-first" "--time-style=long-iso" "--group" "--color-scale") 92 | ls() { eza "${eza_params[@]}" $@; } 93 | l() { eza --git-ignore "${eza_params[@]}" $@; } 94 | la() { eza -a "${eza_params[@]}" $@; } 95 | ll() { eza --header --long "${eza_params[@]}" $@; } 96 | else 97 | declare -g ls_params=("-hF" "--group-directories-first" "--time-style=+%Y-%m-%d %H:%M" "--quoting-style=literal" "--color=auto") 98 | ls() { command ls "${ls_params[@]}" -C $@; } 99 | l() { command ls "${ls_params[@]}" -C $@; } 100 | la() { command ls "${ls_params[@]}" -C -A $@; } 101 | ll() { command ls "${ls_params[@]}" -l $@; } 102 | fi 103 | # ls }}} 104 | 105 | # {{{ zoxide 106 | if command_exists zoxide; then 107 | eval "$(zoxide init bash --no-cmd)" 108 | z() { __zoxide_z $@; } 109 | fi 110 | # zoxide }}} 111 | 112 | # {{{ utilities 113 | reload_shell() { 114 | exec ${current_shell:-"bash"} 115 | } 116 | # utilities }}} 117 | 118 | # {{{ starship 119 | export STARSHIP_CONFIG=~/.config/starship/config.toml 120 | eval "$(starship init bash)" 121 | export PROMPT_COMMAND="starship_precmd;${PROMPT_COMMAND/starship_precmd;/}" 122 | # starship }}} 123 | 124 | # vim: set foldmethod=marker : 125 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/utils/lua_ls.lua: -------------------------------------------------------------------------------- 1 | ---@type table 2 | local _nvim_lib_dir_store = nil 3 | 4 | ---@param lib_path_pattern string 5 | ---@return table 6 | local function get_nvim_lib_dir_map(lib_path_pattern) 7 | local lib_dir_map = {} 8 | 9 | for _, lib_lua_path in ipairs(vim.fn.expand(lib_path_pattern .. "/lua", false, true)) do 10 | lib_lua_path = vim.loop.fs_realpath(lib_lua_path) 11 | 12 | if lib_lua_path then 13 | local lib_dir = vim.fn.fnamemodify(lib_lua_path, ":h") 14 | local lib_name = vim.fn.fnamemodify(lib_dir, ":t") 15 | lib_dir_map[lib_name] = lib_dir 16 | end 17 | end 18 | 19 | return lib_dir_map 20 | end 21 | 22 | local function populate_nvim_lib_dir_store() 23 | _nvim_lib_dir_store = {} 24 | 25 | for lib_name, lib_dir in pairs(get_nvim_lib_dir_map("$VIMRUNTIME")) do 26 | _nvim_lib_dir_store[lib_name] = lib_dir 27 | end 28 | 29 | ---@type LazyPlugin[] 30 | local plugins = require("lazy").plugins() 31 | for _, plugin in ipairs(plugins) do 32 | if vim.fn.isdirectory(plugin.dir .. "/lua") == 1 then 33 | _nvim_lib_dir_store[plugin.name] = plugin.dir 34 | end 35 | end 36 | end 37 | 38 | ---@param package_name string 39 | ---@return string|nil lib_dir 40 | local function get_nvim_lib_dir(package_name) 41 | if not _nvim_lib_dir_store then 42 | populate_nvim_lib_dir_store() 43 | end 44 | 45 | return _nvim_lib_dir_store[package_name] 46 | end 47 | 48 | ---@param packages? string[] 49 | ---@return string[] 50 | local function get_nvim_lib_dirs(packages) 51 | if not _nvim_lib_dir_store then 52 | populate_nvim_lib_dir_store() 53 | end 54 | 55 | if not packages then 56 | packages = vim.tbl_keys(_nvim_lib_dir_store) 57 | end 58 | 59 | local lib_dirs = {} 60 | 61 | for _, package_name in ipairs(packages) do 62 | if package_name ~= "neodev.nvim" then 63 | local lib_dir = _nvim_lib_dir_store[package_name] 64 | if lib_dir then 65 | table.insert(lib_dirs, lib_dir) 66 | end 67 | end 68 | end 69 | 70 | return lib_dirs 71 | end 72 | 73 | local function read_luarc() 74 | local luarc_path = vim.fn.fnamemodify(".luarc.lua", ":p") 75 | if vim.fn.filereadable(luarc_path) == 1 then 76 | return loadstring(table.concat(vim.fn.readfile(luarc_path), "\n"))() or {} 77 | end 78 | return {} 79 | end 80 | 81 | local function to_directory_list(paths) 82 | return vim.tbl_filter( 83 | function(path) 84 | return vim.fn.isdirectory(path) == 1 85 | end, 86 | vim.tbl_map(function(path) 87 | return vim.fn.expand(path) 88 | end, paths or {}) 89 | ) 90 | end 91 | 92 | local function prepare_workspace_library(luarc) 93 | local library = {} 94 | 95 | if luarc.workspace then 96 | vim.list_extend(library, to_directory_list(luarc.workspace.library)) 97 | end 98 | 99 | if luarc.nvim or not luarc.workspace then 100 | table.insert( 101 | library, 102 | get_nvim_lib_dir("neodev.nvim") .. "/types/" .. (vim.version().prerelease and "nightly" or "stable") 103 | ) 104 | vim.list_extend(library, get_nvim_lib_dirs(luarc.nvim and luarc.nvim.packages)) 105 | end 106 | 107 | return library 108 | end 109 | 110 | local mod = {} 111 | 112 | function mod.server_config(config) 113 | local luarc = read_luarc() 114 | if luarc.Lua then 115 | luarc = luarc.Lua 116 | end 117 | 118 | config.settings = { 119 | Lua = vim.tbl_deep_extend( 120 | "force", 121 | { 122 | format = { 123 | enable = false, 124 | }, 125 | runtime = { 126 | version = "LuaJIT", 127 | path = { "?.lua", "?/init.lua", "lua/?.lua", "lua/?/init.lua" }, 128 | pathStrict = false, 129 | }, 130 | workspace = { 131 | checkThirdParty = false, 132 | maxPreload = 10000, 133 | preloadFileSize = 10000, 134 | }, 135 | telemetry = { 136 | enable = false, 137 | }, 138 | }, 139 | luarc, 140 | { 141 | workspace = { 142 | library = prepare_workspace_library(luarc), 143 | }, 144 | } 145 | ), 146 | } 147 | 148 | config.settings.Lua.nvim = nil 149 | end 150 | 151 | return mod 152 | -------------------------------------------------------------------------------- /.chezmoiscripts/.20_setup.linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | CHEZMOI_SOURCE="${HOME}/.local/share/chezmoi" 6 | source "${CHEZMOI_SOURCE}/.chezmoiscripts/.00_helpers.sh" 7 | 8 | install_apt_packages() { 9 | if ! command_exists apt; then 10 | exit 1 11 | fi 12 | 13 | TASK "Install APT Packages" 14 | 15 | apt_update() { 16 | SUB_TASK "sudo apt update" 17 | sudo apt update 18 | } 19 | 20 | apt_install() { 21 | SUB_TASK "sudo apt install --yes $*" 22 | if command_exists apt-fast; then 23 | sudo apt-fast install --yes $@ 24 | else 25 | sudo apt install --yes $@ 26 | fi 27 | } 28 | 29 | if ! command_exists add-apt-repository; then 30 | apt_install software-properties-common 31 | fi 32 | 33 | add_apt_repository() { 34 | SUB_TASK "sudo add-add-apt-repository --yes --no-update $@" 35 | sudo add-apt-repository --yes --no-update "$@" 36 | } 37 | 38 | declare APT_REPOSITORIES=( 39 | ppa:git-core/ppa 40 | ) 41 | 42 | declare APT_PACKAGES=( 43 | chafa 44 | curl 45 | git 46 | gnupg2 47 | grc 48 | htop 49 | jq 50 | libsecret-tools 51 | moreutils 52 | neofetch 53 | shellcheck 54 | translate-shell 55 | tree 56 | unrar 57 | unzip 58 | vim 59 | xclip 60 | xsel 61 | zsh 62 | ) 63 | 64 | if ! is_arm64; then 65 | APT_PACKAGES+=(rar) 66 | fi 67 | 68 | if ! is_headless_machine; then 69 | APT_PACKAGES+=(dconf-cli dconf-editor) 70 | APT_PACKAGES+=(filezilla gpa gparted ibus-avro) 71 | APT_PACKAGES+=(vlc) 72 | fi 73 | 74 | for apt_repo in "${APT_REPOSITORIES[@]}"; do 75 | add_apt_repository ${apt_repo} 76 | done 77 | 78 | apt_update 79 | 80 | apt_install "${APT_PACKAGES[@]}" 81 | } 82 | 83 | run_setup_scripts() { 84 | TASK "Run Setup Scripts" 85 | 86 | declare SETUP_SCRIPTS=( 87 | setup-tpm 88 | setup-zed 89 | ) 90 | 91 | if ! is_github_codespace; then 92 | SETUP_SCRIPTS+=(setup-apt-fast) 93 | SETUP_SCRIPTS+=(setup-fnm setup-pyenv setup-rbenv) 94 | 95 | if ! command_exists docker; then 96 | SETUP_SCRIPTS+=(setup-docker) 97 | fi 98 | 99 | if ! command_exists go; then 100 | SETUP_SCRIPTS+=(setup-golang) 101 | fi 102 | 103 | if ! command_exists rustup; then 104 | SETUP_SCRIPTS+=(setup-rust) 105 | fi 106 | fi 107 | 108 | SETUP_SCRIPTS+=( 109 | setup-bat 110 | setup-delta 111 | setup-eza 112 | setup-fd 113 | setup-fzf 114 | setup-lf 115 | setup-ripgrep 116 | setup-starship 117 | setup-zoxide 118 | ) 119 | 120 | if ! command_exists nvim; then 121 | SETUP_SCRIPTS+=(setup-neovim) 122 | fi 123 | 124 | if ! command_exists tmux; then 125 | SETUP_SCRIPTS+=(setup-tmux) 126 | fi 127 | 128 | if ! is_headless_machine; then 129 | if ! command_exists alacritty; then 130 | SETUP_SCRIPTS+=(setup-alacritty) 131 | fi 132 | if ! command_exists code; then 133 | SETUP_SCRIPTS+=(setup-vscode) 134 | fi 135 | if ! command_exists kitty; then 136 | SETUP_SCRIPTS+=(setup-kitty) 137 | fi 138 | if ! command_exists postman; then 139 | SETUP_SCRIPTS+=(setup-postman) 140 | fi 141 | if ! command_exists rofi; then 142 | SETUP_SCRIPTS+=(setup-rofi) 143 | fi 144 | fi 145 | 146 | if should_include_secrets; then 147 | if ! command_exists keybase; then 148 | SETUP_SCRIPTS+=(setup-keybase) 149 | fi 150 | fi 151 | 152 | for script in "${SETUP_SCRIPTS[@]}"; do 153 | echo "" 154 | if command_exists ${script}; then 155 | echo_info "[${script}] started" 156 | echo "" 157 | ${script} 158 | echo "" 159 | 160 | if [[ "${script}" == "setup-rust" ]]; then 161 | source "${CARGO_HOME:-"${HOME}/.local/share/cargo"}/env" 162 | fi 163 | 164 | echo_info "[${script}] ended" 165 | else 166 | echo_warn "[${script}] not found!" 167 | fi 168 | echo "" 169 | done 170 | } 171 | 172 | create_necessary_directories() { 173 | TASK "Creating Necessary Directories" 174 | 175 | declare NECESSARY_DIRECTORIES=( 176 | ~/.cache/nano/backup 177 | ~/.local/share/mpd/playlists 178 | ~/.local/share/mpdscribble 179 | ~/.local/share/{nvim,vim}/{backup,swap,undo} 180 | ~/.ssh/control 181 | ) 182 | 183 | printf '> %s\n' "${NECESSARY_DIRECTORIES[@]}" 184 | echo "" 185 | mkdir -p "${NECESSARY_DIRECTORIES[@]}" 186 | } 187 | 188 | ensure_linux 189 | ask_sudo 190 | 191 | install_apt_packages 192 | run_setup_scripts 193 | create_necessary_directories 194 | -------------------------------------------------------------------------------- /.chezmoiscripts/.20_setup.darwin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | CHEZMOI_SOURCE="${HOME}/.local/share/chezmoi" 6 | source "${CHEZMOI_SOURCE}/.chezmoiscripts/.00_helpers.sh" 7 | 8 | setup_brew_packages() { 9 | if ! command_exists brew; then 10 | exit 1 11 | fi 12 | 13 | TASK "Setup Brew Packages" 14 | 15 | local brewfile='' 16 | brew_bundle() { 17 | echo "$brewfile" | brew bundle --file=- 18 | } 19 | 20 | SUB_TASK "Update terminfo database" 21 | brewfile=' 22 | brew "ncurses" 23 | ' 24 | brew_bundle 25 | 26 | update_terminfo_database() { 27 | local -r term_name="${1}" 28 | $(brew --prefix ncurses)/bin/infocmp -x "${term_name}" >"/tmp/${term_name}.info" 29 | tic -x -o "${HOME}/.terminfo" -e "${term_name}" "/tmp/${term_name}.info" 30 | } 31 | update_terminfo_database tmux 32 | update_terminfo_database tmux-256color 33 | 34 | SUB_TASK "Setup GNU Programs/Tools" 35 | brewfile=' 36 | brew "binutils" 37 | brew "coreutils" 38 | brew "diffutils" 39 | brew "ed" 40 | brew "findutils" 41 | brew "gawk" 42 | brew "gnu-getopt" 43 | brew "gnu-indent" 44 | brew "gnu-sed" 45 | brew "gnu-tar" 46 | brew "gnu-which" 47 | brew "gnutls" 48 | brew "grep" 49 | brew "gzip" 50 | brew "less" 51 | brew "parallel" 52 | brew "screen" 53 | brew "util-linux" 54 | ' 55 | brew_bundle 56 | 57 | SUB_TASK "Setup tools and utilities" 58 | brewfile=' 59 | tap "yqrashawn/goku" 60 | 61 | brew "age" 62 | brew "asciinema" 63 | brew "bash" 64 | brew "bash-completion@2" 65 | brew "bat" 66 | brew "blueutil" 67 | brew "eza" 68 | brew "fd" 69 | brew "gh" 70 | brew "git" 71 | brew "git-delta" 72 | brew "gnupg" 73 | brew "go" 74 | brew "grc" 75 | brew "imagemagick" 76 | brew "jq" 77 | brew "lf" 78 | brew "openssh" 79 | brew "p7zip" 80 | brew "perl" 81 | brew "pinentry-mac" 82 | brew "ripgrep" 83 | brew "rsync" 84 | brew "starship" 85 | brew "subversion" 86 | brew "switchaudio-osx" 87 | brew "tmux" 88 | brew "trash" 89 | brew "tree" 90 | brew "wget" 91 | brew "yqrashawn/goku/goku" 92 | brew "zoxide" 93 | brew "zsh" 94 | cask "rar" 95 | ' 96 | brew_bundle 97 | 98 | SUB_TASK "Setup Programming Language Version Managers" 99 | brewfile=' 100 | brew "autoconf" 101 | brew "pkg-config" 102 | brew "pyenv" 103 | brew "pyenv-virtualenv" 104 | brew "rbenv" 105 | brew "readline" 106 | brew "ruby-build" 107 | brew "sqlite" 108 | brew "xz" 109 | brew "zlib" 110 | ' 111 | brew_bundle 112 | 113 | if ! is_arm64; then 114 | brewfile=' 115 | tap "rbenv/tap" 116 | 117 | brew "rbenv/tap/openssl@1.0" 118 | ' 119 | brew_bundle 120 | fi 121 | 122 | SUB_TASK "Setup Desktop Apps" 123 | brewfile=' 124 | cask "alacritty" 125 | cask "maccy" 126 | cask "docker" 127 | cask "google-chrome" 128 | cask "hammerspoon" 129 | cask "karabiner-elements" 130 | cask "keybase" 131 | cask "postman" 132 | cask "stats" 133 | cask "visual-studio-code" 134 | cask "vlc" 135 | ' 136 | brew_bundle 137 | 138 | SUB_TASK "Setup Fonts" 139 | brewfile=' 140 | cask "font-fira-code" 141 | cask "font-fira-code-nerd-font" 142 | cask "font-jetbrains-mono" 143 | cask "font-jetbrains-mono-nerd-font" 144 | cask "font-ubuntu" 145 | cask "font-ubuntu-mono" 146 | cask "font-ubuntu-mono-nerd-font" 147 | cask "font-ubuntu-nerd-font" 148 | ' 149 | brew_bundle 150 | } 151 | 152 | run_setup_scripts() { 153 | TASK "Run Setup Scripts" 154 | 155 | declare SETUP_SCRIPTS=( 156 | setup-fnm 157 | setup-tpm 158 | setup-zed 159 | 160 | setup-fzf 161 | ) 162 | 163 | if ! command_exists rustup; then 164 | SETUP_SCRIPTS+=(setup-rust) 165 | fi 166 | 167 | if ! command_exists nvim; then 168 | SETUP_SCRIPTS+=(setup-neovim) 169 | fi 170 | 171 | for script in "${SETUP_SCRIPTS[@]}"; do 172 | echo "" 173 | if command_exists ${script}; then 174 | echo "[${script}] started" 175 | echo "" 176 | ${script} 177 | echo "" 178 | echo "[${script}] ended" 179 | else 180 | echo "[${script}] not found!" 181 | fi 182 | echo "" 183 | done 184 | } 185 | 186 | create_necessary_directories() { 187 | TASK "Creating Necessary Directories" 188 | 189 | declare NECESSARY_DIRECTORIES=( 190 | ~/.cache/nano/backup 191 | ~/.local/share/mpd/playlists 192 | ~/.local/share/mpdscribble 193 | ~/.local/share/{nvim,vim}/{backup,swap,undo} 194 | ~/.ssh/control 195 | ) 196 | 197 | printf '> %s\n' "${NECESSARY_DIRECTORIES[@]}" 198 | echo "" 199 | mkdir -p "${NECESSARY_DIRECTORIES[@]}" 200 | } 201 | 202 | ensure_darwin 203 | 204 | setup_brew_packages 205 | run_setup_scripts 206 | create_necessary_directories 207 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/lsp/base.lua: -------------------------------------------------------------------------------- 1 | local u = require("plugins.lsp.utils") 2 | 3 | local mason_lsp = require("mason-lspconfig") 4 | mason_lsp.setup({ 5 | ensure_installed = { 6 | "bashls", 7 | "clangd", 8 | "cssls", 9 | -- "denols", 10 | "emmet_ls", 11 | "gopls", 12 | "html", 13 | "jsonls", 14 | "lua_ls", 15 | "pyright", 16 | "ruff", 17 | "rust_analyzer", 18 | "tailwindcss", 19 | "vimls", 20 | "vtsls", 21 | "yamlls", 22 | }, 23 | }) 24 | 25 | local server_config = { 26 | clangd = { 27 | filetypes = { "c", "cpp", "objc", "objcpp", "cuda" }, 28 | }, 29 | denols = { 30 | root_dir = require("lspconfig").util.root_pattern("deno.json", "deno.jsonc"), 31 | }, 32 | emmet_ls = { 33 | filetypes = { "html", "css", "scss" }, 34 | }, 35 | lua_ls = u.lua_ls.server_config, 36 | jsonls = { 37 | settings = { 38 | json = { 39 | schemas = vim.list_extend({ 40 | { 41 | fileMatch = { ".luarc.json", ".luarc.jsonc" }, 42 | name = "LuaLS Settings", 43 | url = "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", 44 | }, 45 | }, require("schemastore").json.schemas()), 46 | validate = { enable = true }, 47 | }, 48 | }, 49 | }, 50 | tailwindcss = { 51 | settings = { 52 | tailwindCSS = { 53 | experimental = { 54 | classRegex = { 55 | { "clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)" }, 56 | { "cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)" }, 57 | { "cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]" }, 58 | }, 59 | }, 60 | }, 61 | }, 62 | }, 63 | vtsls = function(config) 64 | -- ref: https://github.com/yioneko/vtsls/blob/main/packages/service/configuration.schema.json 65 | local inlayHints = { 66 | enumMemberValues = { enabled = true }, 67 | functionLikeReturnTypes = { enabled = true }, 68 | parameterNames = { 69 | ---@type 'none'|'literals'|'all' 70 | enabled = "all", 71 | }, 72 | parameterTypes = { enabled = true }, 73 | propertyDeclarationTypes = { enabled = true }, 74 | variableTypes = { enabled = true }, 75 | } 76 | 77 | config.settings = { 78 | typescript = { 79 | inlayHints = inlayHints, 80 | }, 81 | javascript = { 82 | inlayHints = inlayHints, 83 | }, 84 | } 85 | 86 | local on_attach = config.on_attach 87 | config.on_attach = function(client, bufnr) 88 | on_attach(client, bufnr) 89 | 90 | vim.api.nvim_buf_create_user_command(bufnr, "TypescriptOrganizeImports", function() 91 | require("vtsls").commands.organize_imports(bufnr) 92 | end, { desc = "Organize Imports" }) 93 | 94 | vim.api.nvim_buf_create_user_command(bufnr, "TypescriptRemoveUnusedImports", function() 95 | require("vtsls").commands.remove_unused_imports(bufnr) 96 | end, { desc = "Remove Unused Imports" }) 97 | end 98 | end, 99 | } 100 | 101 | local server_setup = { 102 | vtsls = function(server_name, config) 103 | vim.lsp.config(server_name, config) 104 | vim.lsp.enable(server_name) 105 | end, 106 | rust_analyzer = false, 107 | ["*"] = function(server_name, config) 108 | vim.lsp.config(server_name, config) 109 | vim.lsp.enable(server_name) 110 | end, 111 | } 112 | 113 | local function setup_server(server_name) 114 | if server_setup[server_name] == false then 115 | return 116 | end 117 | 118 | local config = u.make_server_config(server_config[server_name]) 119 | local setup = server_setup[server_name] or server_setup["*"] 120 | setup(server_name, config) 121 | end 122 | 123 | for _, server_name in ipairs(mason_lsp.get_installed_servers()) do 124 | setup_server(server_name) 125 | end 126 | 127 | vim.api.nvim_create_user_command("Format", function(params) 128 | local format = require("plugins.lsp.custom").format 129 | if params.range > 0 then 130 | format({ range = vim.lsp.util.make_given_range_params() }) 131 | else 132 | format() 133 | end 134 | end, { desc = "[lsp] format content", range = "%" }) 135 | 136 | local function setup_diagnostics() 137 | vim.diagnostic.config({ 138 | underline = true, 139 | virtual_text = false, 140 | signs = true, 141 | }) 142 | 143 | vim.schedule(function() 144 | for _, severity in ipairs({ "Error", "Warn", "Info", "Hint" }) do 145 | local hl_def = vim.api.nvim_get_hl(0, { 146 | name = "Diagnostic" .. severity, 147 | link = false, 148 | }) 149 | vim.api.nvim_set_hl(0, "DiagnosticLineNr" .. severity, { fg = hl_def.fg, bold = true }) 150 | vim.fn.sign_define("DiagnosticSign" .. severity, { numhl = "DiagnosticLineNr" .. severity, text = "" }) 151 | end 152 | end) 153 | end 154 | 155 | setup_diagnostics() 156 | -------------------------------------------------------------------------------- /.chezmoiscripts/.21_settings.linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | CHEZMOI_SOURCE="${HOME}/.local/share/chezmoi" 6 | source "${CHEZMOI_SOURCE}/.chezmoiscripts/.00_helpers.sh" 7 | 8 | TASK "Writing Linux Settings" 9 | 10 | ensure_linux 11 | ask_sudo 12 | 13 | if is_headless_machine; then 14 | echo_warn "skipping dconf settings on headless machine" 15 | exit 0 16 | fi 17 | 18 | dconf_array_value() { 19 | local value="" 20 | 21 | while [[ $# -gt 0 ]]; do 22 | value="${value},'${1}'" 23 | shift 24 | done 25 | 26 | value="${value:1}" 27 | 28 | if [[ "${value}" == "" ]]; then 29 | value="''" 30 | fi 31 | 32 | echo "[${value}]" 33 | } 34 | 35 | set_custom_keyboard_shortcuts() { 36 | local -A custom_keybindings_keys=() 37 | 38 | add_custom_keybinding() { 39 | local -r key="mt_${1}" 40 | local -r name="'${2}'" 41 | local -r cmd="'${3//\'/\\\'}'" 42 | local -r binding="'${4}'" 43 | 44 | custom_keybindings_keys[${key}]="true" 45 | 46 | echo "(custom) :: ${name} :: ${binding}" 47 | dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${key}/name "${name}" 48 | dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${key}/command "${cmd}" 49 | dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${key}/binding "${binding}" 50 | } 51 | 52 | add_custom_keybinding rofi "Rofi" "${HOME}/.local/bin/run_rofi.sh" "slash" 53 | add_custom_keybinding rofunicode "Rofunicode" "sh -c '${HOME}/.local/bin/rofunicode.sh | xsel -i --clipboard'" "e" 54 | add_custom_keybinding music_next "Music - Next" "mpc next" "period" 55 | add_custom_keybinding music_prev "Music - Prev" "mpc prev" "comma" 56 | add_custom_keybinding music_toggle "Music - Toggle" "${HOME}/.local/bin/music-terminal" "m" 57 | 58 | local new_items=() 59 | 60 | local old_items="$(dconf read /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings)" 61 | if [[ "${old_items}" == "@as []" ]]; then 62 | old_items="" 63 | else 64 | old_items="${old_items:1:-1}" 65 | fi 66 | IFS=", " read -r -a old_items <<<"$old_items" 67 | for item in "${old_items[@]}"; do 68 | item="${item:1:-1}" 69 | item="${item/\/org\/gnome\/settings-daemon\/plugins\/media-keys\/custom-keybindings\//}" 70 | if ! [[ "${item}" == "mt_"* ]]; then 71 | new_items+=("/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${item}") 72 | fi 73 | done 74 | 75 | local available_items=("$(dconf list /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/)") 76 | for item in ${available_items[@]}; do 77 | if [[ "${item}" == "mt_"* ]]; then 78 | set +u 79 | if [[ "${custom_keybindings_keys[${item::-1}]}" == "true" ]]; then 80 | new_items+=("/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${item}") 81 | else 82 | dconf reset -f "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${item}" 83 | fi 84 | set -u 85 | fi 86 | done 87 | 88 | local -r value="$(dconf_array_value ${new_items[@]})" 89 | dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings "${value}" 90 | } 91 | 92 | set_media_keyboard_shortcuts() { 93 | add_media_keybinding() { 94 | local -r key="${1}" 95 | shift 96 | local -r value="$(dconf_array_value $@)" 97 | 98 | echo "(media) :: ${key} :: ${value}" 99 | dconf write "/org/gnome/settings-daemon/plugins/media-keys/${key}" "${value}" 100 | } 101 | 102 | add_media_keybinding area-screenshot "Print" 103 | add_media_keybinding area-screenshot-clip "Print" 104 | add_media_keybinding screencast "Print" 105 | add_media_keybinding screenshot "Print" 106 | add_media_keybinding screenshot-clip "Print" 107 | add_media_keybinding terminal "" 108 | add_media_keybinding window-screenshot "Print" 109 | add_media_keybinding window-screenshot-clip "Print" 110 | } 111 | 112 | set_window_keyboard_shortcuts() { 113 | add_window_keybinding() { 114 | local -r key="${1}" 115 | shift 116 | local -r value="$(dconf_array_value $@)" 117 | 118 | echo "(window) :: ${key} :: ${value}" 119 | dconf write "/org/gnome/desktop/wm/keybindings/${key}" "${value}" 120 | } 121 | 122 | add_window_keybinding close "q" 123 | } 124 | 125 | SUB_TASK "XKB Options" 126 | 127 | echo "shift:both_capslock :: left-shift + right-shift => capslock" 128 | dconf write /org/gnome/desktop/input-sources/xkb-options "['shift:both_capslock']" 129 | 130 | SUB_TASK "Keyboard Shortcut" 131 | 132 | set_custom_keyboard_shortcuts 133 | set_media_keyboard_shortcuts 134 | set_window_keyboard_shortcuts 135 | 136 | echo 137 | echo_info "Done. Note that some of these changes require a logout/restart to take effect." 138 | -------------------------------------------------------------------------------- /private_dot_config/lf/lfrc: -------------------------------------------------------------------------------- 1 | # interpreter for shell commands (needs to be POSIX compatible) 2 | set shell sh 3 | 4 | # set '-eu' options for shell commands 5 | # These options are used to have safer shell commands. Option '-e' is used to 6 | # exit on error and option '-u' is used to give error for unset variables. 7 | # Option '-f' disables pathname expansion which can be useful when $f, $fs, and 8 | # $fx variables contain names with '*' or '?' characters. However, this option 9 | # is used selectively within individual commands as it can be limiting at 10 | # times. 11 | set shellopts '-eu' 12 | 13 | # set internal field separator (IFS) to "\n" for shell commands 14 | # This is useful to automatically split file names in $fs and $fx properly 15 | # since default file separator used in these variables (i.e. 'filesep' option) 16 | # is newline. You need to consider the values of these options and create your 17 | # commands accordingly. 18 | set ifs "\n" 19 | 20 | set drawbox 21 | set icons 22 | set period 15 23 | set scrolloff 5 24 | 25 | # define a custom 'open' command 26 | # This command is called when current file is not a directory. You may want to 27 | # use either file extensions and/or mime types here. Below uses an editor for 28 | # text files and a file opener for the rest. 29 | cmd open ${{ 30 | case $(file --mime-type -Lb $f) in 31 | text/*) 32 | lf -remote "send $id \$$EDITOR \$fx";; 33 | *) 34 | for f in $fx; do $OPENER $f > /dev/null 2> /dev/null & done;; 35 | esac 36 | }} 37 | 38 | cmd smart-rename ${{ 39 | if [ -n "$fs" ]; then 40 | count=$(printf "%s\n" $fs | wc -l) 41 | if [ $count -eq 1 ] && [ -d "$fs" ]; then 42 | vidir $fs 43 | else 44 | printf "%s\n" $fs | vidir - 45 | fi 46 | lf -remote "send $id unselect" 47 | else 48 | lf -remote "send $id rename" 49 | fi 50 | }} 51 | 52 | # make sure trash folder exists 53 | %mkdir -p ~/.trash 54 | 55 | # move current file or selected files to trash folder 56 | # (also see 'man mv' for backup/overwrite options) 57 | cmd trash ${{ 58 | set -f 59 | clear 60 | printf "$fx\n" 61 | printf "\nTrash? [y/n]: " 62 | read answer 63 | if [ "$answer" = "y" ]; then 64 | ~/.config/lf/trash "$fx" 65 | fi 66 | }} 67 | 68 | # define a custom 'delete' command 69 | cmd delete ${{ 70 | set -f 71 | clear 72 | printf "$fx\n" 73 | printf "\nDelete (permanently)? [y/n]: " 74 | read answer 75 | if [ "$answer" = "y" ]; then 76 | rm -rf $fx 77 | fi 78 | }} 79 | 80 | cmd mkdir %{{ 81 | IFS=" " 82 | mkdir -p -- "$*" 83 | lf -remote "send $id select \"$*\"" 84 | }} 85 | 86 | cmd touch %{{ 87 | IFS=" " 88 | touch -- "$*" 89 | lf -remote "send $id select \"$*\"" 90 | }} 91 | 92 | cmd z %{{ 93 | dir="$(zoxide query --exclude "${PWD}" -- "$@")" 94 | lf -remote "send ${id} cd '${dir}'" 95 | }} 96 | 97 | # (xkcd link: https://xkcd.com/1168/) 98 | # extract the current file with the right command 99 | cmd extract ${{ 100 | set -f 101 | ~/.config/lf/extract "$f" 102 | }} 103 | 104 | # compress current file or selected files with tar and gunzip 105 | cmd tar ${{ 106 | set -f 107 | name="${@}" 108 | ~/.config/lf/compress tar "$name" "$fx" 109 | lf -remote "send $id unselect" 110 | }} 111 | 112 | # compress current file or selected files with zip 113 | cmd zip ${{ 114 | set -f 115 | name="${@}" 116 | ~/.config/lf/compress zip "$name" "$fx" 117 | lf -remote "send $id unselect" 118 | }} 119 | 120 | # reload config and refresh ui 121 | cmd refresh :{{ 122 | source "~/.config/lf/lfrc" 123 | reload 124 | }} 125 | 126 | cmd q :quit 127 | 128 | set previewer "~/.config/lf/previewer" 129 | map i $~/.config/lf/previewer "$f" | less -R 130 | 131 | # set cleaner for supported environment 132 | ${{ 133 | if test -z "${TMUX:-}" && test -n "${KITTY_PID:-}"; then 134 | lf -remote "send $id set cleaner '~/.config/lf/cleaner'" 135 | fi 136 | }} 137 | 138 | set mouse 139 | map down 140 | map up 141 | map :toggle 142 | 143 | map e $$EDITOR $f 144 | map i $$PAGER $f 145 | map w $$SHELL 146 | 147 | # execute current file (must be executable) 148 | map x $$f 149 | map X !$f 150 | 151 | # dedicated keys for file opener actions 152 | map o &mimeopen $f 153 | map O $mimeopen --ask $f 154 | 155 | map d 156 | map dd cut 157 | map df trash 158 | map dF delete 159 | 160 | map r smart-rename 161 | 162 | map E extract "$f" 163 | 164 | map za set info size:time 165 | map zh set hidden! 166 | map zn set info 167 | map zr set reverse! 168 | map zs set info size 169 | map zt set info time 170 | 171 | map sa :set sortby atime; set info atime 172 | map sc :set sortby ctime; set info ctime 173 | map se :set sortby ext; set info 174 | map sn :set sortby natural; set info 175 | map ss :set sortby size; set info size 176 | map st :set sortby time; set info time 177 | 178 | map ga push :touch 179 | map gA push :mkdir 180 | map gg top 181 | map gh cd ~ 182 | map gq quit 183 | map gr refresh 184 | map gz push :z 185 | map g. set hidden! 186 | 187 | map J :toggle; down 188 | map K :toggle; up 189 | map :toggle; down 190 | -------------------------------------------------------------------------------- /private_dot_config/alacritty/darwin.toml: -------------------------------------------------------------------------------- 1 | [window] 2 | decorations = "Buttonless" # Buttonless / Full / None / Transparent 3 | 4 | [font] 5 | size = 15.0 6 | 7 | [keyboard] 8 | bindings = [ 9 | { key = "C", mods = "Control|Shift", action = "Copy" }, 10 | { key = "V", mods = "Control|Shift", action = "Paste", mode = "~Vi" }, 11 | 12 | { key = "A", mods = "Alt", chars = "\u001ba" }, 13 | { key = "B", mods = "Alt", chars = "\u001bb" }, 14 | { key = "C", mods = "Alt", chars = "\u001bc" }, 15 | { key = "D", mods = "Alt", chars = "\u001bd" }, 16 | { key = "E", mods = "Alt", chars = "\u001be" }, 17 | { key = "F", mods = "Alt", chars = "\u001bf" }, 18 | { key = "G", mods = "Alt", chars = "\u001bg" }, 19 | { key = "H", mods = "Alt", chars = "\u001bh" }, 20 | { key = "I", mods = "Alt", chars = "\u001bi" }, 21 | { key = "J", mods = "Alt", chars = "\u001bj" }, 22 | { key = "K", mods = "Alt", chars = "\u001bk" }, 23 | { key = "L", mods = "Alt", chars = "\u001bl" }, 24 | { key = "M", mods = "Alt", chars = "\u001bm" }, 25 | { key = "N", mods = "Alt", chars = "\u001bn" }, 26 | { key = "O", mods = "Alt", chars = "\u001bo" }, 27 | { key = "P", mods = "Alt", chars = "\u001bp" }, 28 | { key = "Q", mods = "Alt", chars = "\u001bq" }, 29 | { key = "R", mods = "Alt", chars = "\u001br" }, 30 | { key = "S", mods = "Alt", chars = "\u001bs" }, 31 | { key = "T", mods = "Alt", chars = "\u001bt" }, 32 | { key = "U", mods = "Alt", chars = "\u001bu" }, 33 | { key = "V", mods = "Alt", chars = "\u001bv" }, 34 | { key = "W", mods = "Alt", chars = "\u001bw" }, 35 | { key = "X", mods = "Alt", chars = "\u001bx" }, 36 | { key = "Y", mods = "Alt", chars = "\u001by" }, 37 | { key = "Z", mods = "Alt", chars = "\u001bz" }, 38 | { key = "A", mods = "Alt|Shift", chars = "\u001bA" }, 39 | { key = "B", mods = "Alt|Shift", chars = "\u001bB" }, 40 | { key = "C", mods = "Alt|Shift", chars = "\u001bC" }, 41 | { key = "D", mods = "Alt|Shift", chars = "\u001bD" }, 42 | { key = "E", mods = "Alt|Shift", chars = "\u001bE" }, 43 | { key = "F", mods = "Alt|Shift", chars = "\u001bF" }, 44 | { key = "G", mods = "Alt|Shift", chars = "\u001bG" }, 45 | { key = "H", mods = "Alt|Shift", chars = "\u001bH" }, 46 | { key = "I", mods = "Alt|Shift", chars = "\u001bI" }, 47 | { key = "J", mods = "Alt|Shift", chars = "\u001bJ" }, 48 | { key = "K", mods = "Alt|Shift", chars = "\u001bK" }, 49 | { key = "L", mods = "Alt|Shift", chars = "\u001bL" }, 50 | { key = "M", mods = "Alt|Shift", chars = "\u001bM" }, 51 | { key = "N", mods = "Alt|Shift", chars = "\u001bN" }, 52 | { key = "O", mods = "Alt|Shift", chars = "\u001bO" }, 53 | { key = "P", mods = "Alt|Shift", chars = "\u001bP" }, 54 | { key = "Q", mods = "Alt|Shift", chars = "\u001bQ" }, 55 | { key = "R", mods = "Alt|Shift", chars = "\u001bR" }, 56 | { key = "S", mods = "Alt|Shift", chars = "\u001bS" }, 57 | { key = "T", mods = "Alt|Shift", chars = "\u001bT" }, 58 | { key = "U", mods = "Alt|Shift", chars = "\u001bU" }, 59 | { key = "V", mods = "Alt|Shift", chars = "\u001bV" }, 60 | { key = "W", mods = "Alt|Shift", chars = "\u001bW" }, 61 | { key = "X", mods = "Alt|Shift", chars = "\u001bX" }, 62 | { key = "Y", mods = "Alt|Shift", chars = "\u001bY" }, 63 | { key = "Z", mods = "Alt|Shift", chars = "\u001bZ" }, 64 | { key = "Key1", mods = "Alt", chars = "\u001b1" }, 65 | { key = "Key2", mods = "Alt", chars = "\u001b2" }, 66 | { key = "Key3", mods = "Alt", chars = "\u001b3" }, 67 | { key = "Key4", mods = "Alt", chars = "\u001b4" }, 68 | { key = "Key5", mods = "Alt", chars = "\u001b5" }, 69 | { key = "Key6", mods = "Alt", chars = "\u001b6" }, 70 | { key = "Key7", mods = "Alt", chars = "\u001b7" }, 71 | { key = "Key8", mods = "Alt", chars = "\u001b8" }, 72 | { key = "Key9", mods = "Alt", chars = "\u001b9" }, 73 | { key = "Key0", mods = "Alt", chars = "\u001b0" }, 74 | { key = "Space", mods = "Control", chars = "\u0000" }, # Ctrl + Space 75 | { key = "`", mods = "Alt", chars = "\u001b`" }, # Alt + ` 76 | { key = "`", mods = "Alt|Shift", chars = "\u001b~" }, # Alt + ~ 77 | { key = "Period", mods = "Alt", chars = "\u001b." }, # Alt + . 78 | { key = "Key8", mods = "Alt|Shift", chars = "\u001b*" }, # Alt + * 79 | { key = "Key3", mods = "Alt|Shift", chars = "\u001b#" }, # Alt + # 80 | { key = "Period", mods = "Alt|Shift", chars = "\u001b>" }, # Alt + > 81 | { key = "Comma", mods = "Alt|Shift", chars = "\u001b<" }, # Alt + < 82 | { key = "Minus", mods = "Alt|Shift", chars = "\u001b_" }, # Alt + _ 83 | { key = "Key5", mods = "Alt|Shift", chars = "\u001b%" }, # Alt + % 84 | { key = "Key6", mods = "Alt|Shift", chars = "\u001b^" }, # Alt + ^ 85 | { key = "Backslash", mods = "Alt", chars = "\u001b\\" }, # Alt + \ 86 | { key = "Backslash", mods = "Alt|Shift", chars = "\u001b|" }, # Alt + | 87 | { key = "LBracket", mods = "Alt", chars = "\u001b[" }, # Alt + [ 88 | { key = "LBracket", mods = "Alt|Shift", chars = "\u001b{" }, # Alt + { 89 | { key = "RBracket", mods = "Alt", chars = "\u001b]" }, # Alt + ] 90 | { key = "RBracket", mods = "Alt|Shift", chars = "\u001b}" }, # Alt + } 91 | { key = "Back", mods = "Alt", chars = "\u001b\u007f" }, # Alt + Backspace 92 | ] 93 | -------------------------------------------------------------------------------- /private_dot_config/rofi/config.rasi: -------------------------------------------------------------------------------- 1 | configuration { 2 | /* modes: "window,drun,run,ssh";*/ 3 | font: "JetBrainsMono Nerd Font 13"; 4 | /* location: 0;*/ 5 | /* yoffset: 0;*/ 6 | /* xoffset: 0;*/ 7 | /* fixed-num-lines: true;*/ 8 | /* show-icons: false;*/ 9 | /* terminal: "rofi-sensible-terminal";*/ 10 | /* ssh-client: "ssh";*/ 11 | /* ssh-command: "{terminal} -e {ssh-client} {host} [-p {port}]";*/ 12 | /* run-command: "{cmd}";*/ 13 | /* run-list-command: "";*/ 14 | /* run-shell-command: "{terminal} -e {cmd}";*/ 15 | /* window-command: "wmctrl -i -R {window}";*/ 16 | /* window-match-fields: "all";*/ 17 | /* icon-theme: ;*/ 18 | /* drun-match-fields: "name,generic,exec,categories,keywords";*/ 19 | /* drun-categories: ;*/ 20 | /* drun-show-actions: false;*/ 21 | /* drun-display-format: "{name} [({generic})]";*/ 22 | /* drun-url-launcher: "xdg-open";*/ 23 | /* disable-history: false;*/ 24 | /* ignored-prefixes: "";*/ 25 | /* sort: false;*/ 26 | /* sorting-method: "normal";*/ 27 | /* case-sensitive: false;*/ 28 | /* cycle: true;*/ 29 | /* sidebar-mode: false;*/ 30 | /* hover-select: false;*/ 31 | /* eh: 1;*/ 32 | /* auto-select: false;*/ 33 | /* parse-hosts: false;*/ 34 | /* parse-known-hosts: true;*/ 35 | /* combi-modes: "window,run";*/ 36 | /* matching: "normal";*/ 37 | /* tokenize: true;*/ 38 | /* m: "-5";*/ 39 | /* filter: ;*/ 40 | /* dpi: -1;*/ 41 | /* threads: 0;*/ 42 | /* scroll-method: 0;*/ 43 | /* window-format: "{w} {c} {t}";*/ 44 | /* click-to-exit: true;*/ 45 | /* max-history-size: 25;*/ 46 | /* combi-hide-mode-prefix: false;*/ 47 | /* combi-display-format: "{mode} {text}";*/ 48 | /* matching-negate-char: '-' /* unsupported */;*/ 49 | /* cache-dir: ;*/ 50 | /* window-thumbnail: false;*/ 51 | /* drun-use-desktop-cache: false;*/ 52 | /* drun-reload-desktop-cache: false;*/ 53 | /* normalize-match: false;*/ 54 | /* steal-focus: false;*/ 55 | /* application-fallback-icon: ;*/ 56 | /* refilter-timeout-limit: 8192;*/ 57 | /* pid: "/run/user/1000/rofi.pid";*/ 58 | /* display-window: ;*/ 59 | /* display-windowcd: ;*/ 60 | /* display-run: ;*/ 61 | /* display-ssh: ;*/ 62 | /* display-drun: ;*/ 63 | /* display-combi: ;*/ 64 | /* display-keys: ;*/ 65 | /* display-filebrowser: ;*/ 66 | /* kb-primary-paste: "Control+V,Shift+Insert";*/ 67 | /* kb-secondary-paste: "Control+v,Insert";*/ 68 | /* kb-clear-line: "Control+w";*/ 69 | /* kb-move-front: "Control+a";*/ 70 | /* kb-move-end: "Control+e";*/ 71 | /* kb-move-word-back: "Alt+b,Control+Left";*/ 72 | /* kb-move-word-forward: "Alt+f,Control+Right";*/ 73 | /* kb-move-char-back: "Left,Control+b";*/ 74 | /* kb-move-char-forward: "Right,Control+f";*/ 75 | /* kb-remove-word-back: "Control+Alt+h,Control+BackSpace";*/ 76 | /* kb-remove-word-forward: "Control+Alt+d";*/ 77 | /* kb-remove-char-forward: "Delete,Control+d";*/ 78 | /* kb-remove-char-back: "BackSpace,Shift+BackSpace,Control+h";*/ 79 | /* kb-remove-to-eol: "Control+k";*/ 80 | /* kb-remove-to-sol: "Control+u";*/ 81 | /* kb-accept-entry: "Control+j,Control+m,Return,KP_Enter";*/ 82 | /* kb-accept-custom: "Control+Return";*/ 83 | /* kb-accept-custom-alt: "Control+Shift+Return";*/ 84 | /* kb-accept-alt: "Shift+Return";*/ 85 | /* kb-delete-entry: "Shift+Delete";*/ 86 | /* kb-mode-next: "Shift+Right,Control+Tab";*/ 87 | /* kb-mode-previous: "Shift+Left,Control+ISO_Left_Tab";*/ 88 | /* kb-mode-complete: "Control+l";*/ 89 | /* kb-row-left: "Control+Page_Up";*/ 90 | /* kb-row-right: "Control+Page_Down";*/ 91 | /* kb-row-up: "Up,Control+p";*/ 92 | /* kb-row-down: "Down,Control+n";*/ 93 | /* kb-row-tab: "";*/ 94 | /* kb-element-next: "Tab";*/ 95 | /* kb-element-prev: "ISO_Left_Tab";*/ 96 | /* kb-page-prev: "Page_Up";*/ 97 | /* kb-page-next: "Page_Down";*/ 98 | /* kb-row-first: "Home,KP_Home";*/ 99 | /* kb-row-last: "End,KP_End";*/ 100 | /* kb-row-select: "Control+space";*/ 101 | /* kb-screenshot: "Alt+S";*/ 102 | /* kb-ellipsize: "Alt+period";*/ 103 | /* kb-toggle-case-sensitivity: "grave,dead_grave";*/ 104 | /* kb-toggle-sort: "Alt+grave";*/ 105 | /* kb-cancel: "Escape,Control+g,Control+bracketleft";*/ 106 | /* kb-custom-1: "Alt+1";*/ 107 | /* kb-custom-2: "Alt+2";*/ 108 | /* kb-custom-3: "Alt+3";*/ 109 | /* kb-custom-4: "Alt+4";*/ 110 | /* kb-custom-5: "Alt+5";*/ 111 | /* kb-custom-6: "Alt+6";*/ 112 | /* kb-custom-7: "Alt+7";*/ 113 | /* kb-custom-8: "Alt+8";*/ 114 | /* kb-custom-9: "Alt+9";*/ 115 | /* kb-custom-10: "Alt+0";*/ 116 | /* kb-custom-11: "Alt+exclam";*/ 117 | /* kb-custom-12: "Alt+at";*/ 118 | /* kb-custom-13: "Alt+numbersign";*/ 119 | /* kb-custom-14: "Alt+dollar";*/ 120 | /* kb-custom-15: "Alt+percent";*/ 121 | /* kb-custom-16: "Alt+dead_circumflex";*/ 122 | /* kb-custom-17: "Alt+ampersand";*/ 123 | /* kb-custom-18: "Alt+asterisk";*/ 124 | /* kb-custom-19: "Alt+parenleft";*/ 125 | /* kb-select-1: "Super+1";*/ 126 | /* kb-select-2: "Super+2";*/ 127 | /* kb-select-3: "Super+3";*/ 128 | /* kb-select-4: "Super+4";*/ 129 | /* kb-select-5: "Super+5";*/ 130 | /* kb-select-6: "Super+6";*/ 131 | /* kb-select-7: "Super+7";*/ 132 | /* kb-select-8: "Super+8";*/ 133 | /* kb-select-9: "Super+9";*/ 134 | /* kb-select-10: "Super+0";*/ 135 | /* ml-row-left: "ScrollLeft";*/ 136 | /* ml-row-right: "ScrollRight";*/ 137 | /* ml-row-up: "ScrollUp";*/ 138 | /* ml-row-down: "ScrollDown";*/ 139 | /* me-select-entry: "MousePrimary";*/ 140 | /* me-accept-entry: "MouseDPrimary";*/ 141 | /* me-accept-custom: "Control+MouseDPrimary";*/ 142 | timeout { 143 | action: "kb-cancel"; 144 | delay: 0; 145 | } 146 | filebrowser { 147 | directories-first: true; 148 | sorting-method: "name"; 149 | } 150 | } 151 | 152 | @theme "gruvbox-dark-hard" 153 | -------------------------------------------------------------------------------- /private_dot_config/nvim/lua/plugins/ui/nui.lua: -------------------------------------------------------------------------------- 1 | local Input = require("nui.input") 2 | local Menu = require("nui.menu") 3 | local event = require("nui.utils.autocmd").event 4 | 5 | local function get_prompt_text(prompt, default_prompt) 6 | local prompt_text = prompt or default_prompt 7 | if prompt_text:sub(-1) == ":" then 8 | prompt_text = "[" .. prompt_text:sub(1, -2) .. "]" 9 | end 10 | return prompt_text 11 | end 12 | 13 | local function override_input() 14 | local UIInput = Input:extend("UIInput") 15 | 16 | function UIInput:init(opts, on_done) 17 | local border_top_text = get_prompt_text(opts.prompt, "[Input]") 18 | local default_value = tostring(opts.default or "") 19 | 20 | UIInput.super.init(self, { 21 | relative = "cursor", 22 | position = { 23 | row = 1, 24 | col = 0, 25 | }, 26 | size = { 27 | -- minimum width 20 28 | width = math.max(20, vim.api.nvim_strwidth(default_value)), 29 | }, 30 | border = { 31 | style = "rounded", 32 | text = { 33 | top = border_top_text, 34 | top_align = "left", 35 | }, 36 | }, 37 | win_options = { 38 | winhighlight = "NormalFloat:Normal", 39 | }, 40 | }, { 41 | default_value = default_value, 42 | on_close = function() 43 | on_done(nil) 44 | end, 45 | on_submit = function(value) 46 | on_done(value) 47 | end, 48 | }) 49 | 50 | -- cancel operation if cursor leaves input 51 | self:on(event.BufLeave, function() 52 | on_done(nil) 53 | end, { once = true }) 54 | 55 | -- cancel operation if is pressed 56 | self:map("n", "", function() 57 | on_done(nil) 58 | end, { noremap = true, nowait = true }) 59 | end 60 | 61 | local input_ui 62 | 63 | vim.ui.input = function(opts, on_confirm) 64 | assert(type(on_confirm) == "function", "missing on_confirm function") 65 | 66 | if input_ui then 67 | -- ensure single ui.input operation 68 | vim.api.nvim_err_writeln("busy: another input is pending!") 69 | return 70 | end 71 | 72 | input_ui = UIInput(opts, function(value) 73 | if input_ui then 74 | -- if it's still mounted, unmount it 75 | input_ui:unmount() 76 | end 77 | -- pass the input value 78 | on_confirm(value) 79 | -- indicate the operation is done 80 | input_ui = nil 81 | end) 82 | 83 | input_ui:mount() 84 | end 85 | end 86 | 87 | local function override_select() 88 | local UISelect = Menu:extend("UISelect") 89 | 90 | function UISelect:init(items, opts, on_done) 91 | local border_top_text = get_prompt_text(opts.prompt, "[Select Item]") 92 | local kind = opts.kind or "unknown" 93 | local format_item = opts.format_item or function(item) 94 | return tostring(item.__raw_item or item) 95 | end 96 | 97 | local popup_options = { 98 | relative = "editor", 99 | position = "50%", 100 | border = { 101 | style = "rounded", 102 | text = { 103 | top = border_top_text, 104 | top_align = "left", 105 | }, 106 | }, 107 | win_options = { 108 | winhighlight = "NormalFloat:Normal", 109 | }, 110 | zindex = 999, 111 | } 112 | 113 | if kind == "codeaction" then 114 | -- change position for codeaction selection 115 | popup_options.relative = "cursor" 116 | popup_options.position = { 117 | row = 1, 118 | col = 0, 119 | } 120 | end 121 | 122 | local max_width = popup_options.relative == "editor" and vim.o.columns - 4 or vim.api.nvim_win_get_width(0) - 4 123 | local max_height = popup_options.relative == "editor" and math.floor(vim.o.lines * 80 / 100) 124 | or vim.api.nvim_win_get_height(0) 125 | 126 | local menu_items = {} 127 | for index, item in ipairs(items) do 128 | if type(item) ~= "table" then 129 | item = { __raw_item = item } 130 | end 131 | item.index = index 132 | local item_text = string.sub(format_item(item), 0, max_width) 133 | menu_items[index] = Menu.item(item_text, item) 134 | end 135 | 136 | local menu_options = { 137 | min_width = vim.api.nvim_strwidth(border_top_text), 138 | max_width = max_width, 139 | max_height = max_height, 140 | lines = menu_items, 141 | on_close = function() 142 | on_done(nil, nil) 143 | end, 144 | on_submit = function(item) 145 | on_done(item.__raw_item or item, item.index) 146 | end, 147 | } 148 | 149 | UISelect.super.init(self, popup_options, menu_options) 150 | 151 | -- cancel operation if cursor leaves select 152 | self:on(event.BufLeave, function() 153 | on_done(nil, nil) 154 | end, { once = true }) 155 | end 156 | 157 | local select_ui = nil 158 | 159 | vim.ui.select = function(items, opts, on_choice) 160 | assert(type(on_choice) == "function", "missing on_choice function") 161 | 162 | if select_ui then 163 | -- ensure single ui.select operation 164 | vim.api.nvim_err_writeln("busy: another select is pending!") 165 | return 166 | end 167 | 168 | select_ui = UISelect(items, opts, function(item, index) 169 | if select_ui then 170 | -- if it's still mounted, unmount it 171 | select_ui:unmount() 172 | end 173 | -- pass the select value 174 | on_choice(item, index) 175 | -- indicate the operation is done 176 | select_ui = nil 177 | end) 178 | 179 | select_ui:mount() 180 | end 181 | end 182 | 183 | override_input() 184 | override_select() 185 | --------------------------------------------------------------------------------