├── .config ├── aerospace │ └── aerospace.toml ├── alacritty │ ├── alacritty.toml │ └── themes │ │ └── rose-pine-muted.toml ├── bat │ └── bat.conf ├── bin │ ├── arc │ ├── brew_update │ ├── code_extensions │ ├── docker_nuke │ ├── dotfiles │ ├── e2e_report │ ├── git-submodule-remove │ ├── note │ ├── obsidian │ ├── osxdefaults │ ├── tmux-sessionizer │ ├── u │ └── update_go ├── borders │ └── bordersrc ├── btop │ ├── btop.conf │ └── themes │ │ ├── rosepine.theme │ │ └── zenbones.theme ├── ghostty │ ├── config │ └── themes │ │ └── rose-pine-muted ├── iTerm2 │ └── com.googlecode.iterm2.plist ├── kitty │ └── kitty.conf ├── lazydocker │ └── config.yml ├── lazygit │ └── config.yml ├── neofetch │ └── config.conf ├── nvim │ ├── .luarc.json │ ├── README.md │ ├── after │ │ └── ftplugin │ │ │ ├── dap-float.vim │ │ │ ├── fugitive.lua │ │ │ ├── go.vim │ │ │ ├── json.lua │ │ │ ├── lazy.vim │ │ │ ├── lua.vim │ │ │ ├── netrw.vim │ │ │ ├── python.lua │ │ │ ├── qf.vim │ │ │ ├── sh.vim │ │ │ └── zsh.vim │ ├── filetype.lua │ ├── init.lua │ ├── lazy-lock.json │ ├── lua │ │ ├── core │ │ │ ├── autocommands.lua │ │ │ ├── base.lua │ │ │ ├── highlights.lua │ │ │ ├── init.lua │ │ │ ├── keymaps.lua │ │ │ ├── lazy.lua │ │ │ └── options.lua │ │ ├── lsp │ │ │ ├── init.lua │ │ │ └── servers │ │ │ │ ├── bashls.lua │ │ │ │ ├── cssls.lua │ │ │ │ ├── eslint.lua │ │ │ │ ├── gopls.lua │ │ │ │ ├── jsonls.lua │ │ │ │ ├── lua_ls.lua │ │ │ │ ├── vtsls.lua │ │ │ │ └── yamlls.lua │ │ ├── plugins │ │ │ ├── ai.lua │ │ │ ├── auto-session.lua │ │ │ ├── cmp │ │ │ │ ├── blink.lua │ │ │ │ └── nvim_cmp.lua │ │ │ ├── colorscheme │ │ │ │ ├── gruvbox.lua │ │ │ │ ├── rosepine.lua │ │ │ │ └── zenbones.lua │ │ │ ├── comment.lua │ │ │ ├── conform.lua │ │ │ ├── dap.lua │ │ │ ├── fzf.lua │ │ │ ├── git.lua │ │ │ ├── harpoon.lua │ │ │ ├── lazydev.lua │ │ │ ├── lsp.lua │ │ │ ├── markdown-preview.lua │ │ │ ├── neogen.lua │ │ │ ├── neotest.lua │ │ │ ├── nvim-early-retirement.lua │ │ │ ├── oil.lua │ │ │ ├── snacks.lua │ │ │ ├── statuscol.lua │ │ │ ├── todo-comments.lua │ │ │ ├── treesitter.lua │ │ │ ├── useless.lua │ │ │ ├── vim-surround.lua │ │ │ ├── vim-tmux-navigator.lua │ │ │ ├── which-key.lua │ │ │ └── yazi.lua │ │ ├── statusline.lua │ │ └── utils │ │ │ ├── browse.lua │ │ │ ├── colors.lua │ │ │ ├── fzf.lua │ │ │ ├── icons.lua │ │ │ ├── init.lua │ │ │ ├── lsp.lua │ │ │ └── redir.lua │ ├── snippets │ │ ├── lua │ │ │ └── snippets.lua │ │ └── nvim │ │ │ ├── all.json │ │ │ ├── lua.json │ │ │ ├── package.json │ │ │ ├── react.json │ │ │ └── ts-js.json │ └── stylua.toml ├── obsidian │ ├── .vimrc │ ├── app.json │ ├── appearance.json │ ├── community-plugins.json │ ├── core-plugins.json │ └── themes │ │ └── Rose Pine │ │ ├── manifest.json │ │ └── theme.css ├── tmux-sessionizer │ ├── default │ └── directories ├── tmux │ ├── bin │ │ └── toggle-theme.sh │ └── tmux.conf ├── wezterm │ ├── .luarc.json │ ├── colors │ │ └── kanagawa.lua │ ├── fonts.lua │ ├── utils │ │ └── keys.lua │ ├── wallpapers │ │ └── vader.jpg │ └── wezterm.lua ├── yazi │ ├── theme.toml │ └── yazi.toml └── zsh │ ├── .p10k.zsh │ ├── .zprofile │ ├── .zshrc │ ├── config │ ├── aliases.zsh │ └── options.zsh │ ├── functions │ └── fzf ├── .gitconfig ├── .gitignore ├── .gitignore_global ├── .gitmodules ├── .stow-local-ignore ├── .vimrc ├── .zshenv ├── Brewfile ├── Library └── Application Support │ ├── Code │ └── User │ │ ├── extensions │ │ ├── keybindings.json │ │ ├── settings.json │ │ └── snippets │ │ ├── javascript.code-snippets │ │ └── react.code-snippets │ └── iTerm2 │ └── DynamicProfiles │ ├── gruvbox-material-dark.json │ ├── gruvbox-material-light.json │ └── zenbones_dark.json ├── README.md └── other ├── images ├── screenshot.png └── wallpapers │ ├── README.md │ └── images │ ├── edinburgh-northernlights │ ├── config.json │ └── output.heic │ └── tokyo-nyc │ ├── config.json │ └── output.heic └── lib ├── colors ├── help ├── list ├── misc └── utils /.config/alacritty/alacritty.toml: -------------------------------------------------------------------------------- 1 | [general] 2 | import = ["~/.config/alacritty/themes/rose-pine-muted.toml"] 3 | 4 | [font] 5 | size = 17.0 6 | normal = { family = "JetBrainsMonoNL Nerd Font Mono", style = "Light" } 7 | bold = { family = "JetBrainsMonoNL Nerd Font Mono", style = "Medium" } 8 | bold_italic = { family = "JetBrainsMonoNL Nerd Font Mono", style = "Heavy Italic" } 9 | italic = { family = "JetBrainsMonoNL Nerd Font Mono", style = "Medium Italic" } 10 | 11 | [window] 12 | decorations = "Buttonless" 13 | padding = { x = 5, y = 5 } 14 | 15 | [cursor.style] 16 | blinking = "Always" 17 | 18 | [[keyboard.bindings]] 19 | chars = "s\r" 20 | key = "s" 21 | mods = "Command" 22 | -------------------------------------------------------------------------------- /.config/alacritty/themes/rose-pine-muted.toml: -------------------------------------------------------------------------------- 1 | [colors.primary] 2 | background = '#000000' 3 | foreground = '#e0def4' 4 | 5 | # [colors.cursor] 6 | # text = '#e0def4' 7 | # cursor = '#56526e' 8 | 9 | # [colors.vi_mode_cursor] 10 | # text = '#e0def4' 11 | # cursor = '#56526e' 12 | 13 | [colors.selection] 14 | text = '#e0def4' 15 | background = '#312f44' 16 | 17 | [colors.normal] 18 | black = '#393552' 19 | red = '#eb6f92' 20 | green = '#a1d1da' 21 | yellow = '#f6d5a7' 22 | blue = '#437e91' 23 | magenta = '#d9c7ef' 24 | cyan = '#ebbcba' 25 | white = '#e0def4' 26 | 27 | [colors.bright] 28 | black = '#817c9c' 29 | red = '#eb6f92' 30 | green = '#a1d1da' 31 | yellow = '#f6d5a7' 32 | blue = '#437e91' 33 | magenta = '#d9c7ef' 34 | cyan = '#ebbcba' 35 | white = '#e0def4' 36 | 37 | [colors.hints] 38 | start = { foreground = '#908caa', background = '#2a273f' } 39 | end = { foreground = '#6e6a86', background = '#2a273f' } 40 | -------------------------------------------------------------------------------- /.config/bat/bat.conf: -------------------------------------------------------------------------------- 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="ansi" 8 | --style="default" 9 | 10 | # Enable this to use italic text on the terminal. This is not supported on all 11 | # terminal emulators (like tmux, by default): 12 | --italic-text=always 13 | 14 | # Uncomment the following line to disable automatic paging: 15 | #--paging=never 16 | 17 | # Uncomment the following line if you are using less version >= 551 and want to 18 | # enable mouse scrolling support in `bat` when running inside tmux. This might 19 | # disable text selection, unless you press shift. 20 | #--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse" 21 | 22 | # Syntax mappings: map a certain filename pattern to a language. 23 | # Example 1: use the C++ syntax for Arduino .ino files 24 | # Example 2: Use ".gitignore"-style highlighting for ".ignore" files 25 | #--map-syntax "*.ino:C++" 26 | #--map-syntax ".ignore:Git Ignore" 27 | -------------------------------------------------------------------------------- /.config/bin/arc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | open -a Arc 4 | -------------------------------------------------------------------------------- /.config/bin/brew_update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Update Homebrew 4 | echo 'Updating Homebrew...' 5 | brew update 6 | 7 | # Upgrade all installed formulae 8 | echo 'Upgrading all installed formulae...' 9 | brew upgrade 10 | 11 | # Upgrade cask packages 12 | echo 'Upgrading all installed cask packages...' 13 | brew upgrade --cask --greedy 14 | -------------------------------------------------------------------------------- /.config/bin/code_extensions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | gum style \ 4 | --foreground 14 --border-foreground 14 --border double \ 5 | --margin "1 0" --padding "0 2" \ 6 | ' 7 | ██╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗ 8 | ██║ ██║██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔════╝ 9 | ██║ ██║███████╗██║ ██║ ██║██║ ██║█████╗ 10 | ╚██╗ ██╔╝╚════██║██║ ██║ ██║██║ ██║██╔══╝ 11 | ╚████╔╝ ███████║╚██████╗╚██████╔╝██████╔╝███████╗ 12 | ╚═══╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ 13 | ███████╗██╗ ██╗████████╗███████╗███╗ ██╗███████╗██╗ ██████╗ ███╗ ██╗███████╗ 14 | ██╔════╝╚██╗██╔╝╚══██╔══╝██╔════╝████╗ ██║██╔════╝██║██╔═══██╗████╗ ██║██╔════╝ 15 | █████╗ ╚███╔╝ ██║ █████╗ ██╔██╗ ██║███████╗██║██║ ██║██╔██╗ ██║███████╗ 16 | ██╔══╝ ██╔██╗ ██║ ██╔══╝ ██║╚██╗██║╚════██║██║██║ ██║██║╚██╗██║╚════██║ 17 | ███████╗██╔╝ ██╗ ██║ ███████╗██║ ╚████║███████║██║╚██████╔╝██║ ╚████║███████║ 18 | ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ 19 | ' 20 | 21 | selected=$(gum choose "Save VSCode extensions" "Install VSCode extensions" "Exit") 22 | dotfiles_dir=$(pwd -P) 23 | extensios_dir=$dotfiles_dir/vscode/Library/Application\ Support/Code/User/extensions 24 | 25 | if [[ $# -eq 1 ]] || [[ $selected == "Exit" ]]; then 26 | exit 1 27 | fi 28 | 29 | if [[ $selected == "Save VSCode extensions" ]]; then 30 | echo "Saving VSCode extensions..." 31 | code --list-extensions > $extensions_dir 32 | fi 33 | 34 | if [[ $selected == "Install VSCode extensions" ]]; then 35 | if [[ -f $extensios_dir ]]; then 36 | echo "Installing VSCode extensions..." 37 | extension_list=$(cat $extensios_dir) 38 | for i in "${extension_list[@]}"; do 39 | code --install-extension $i 40 | done 41 | else 42 | echo "VSCode extensions file not found." 43 | fi 44 | fi 45 | -------------------------------------------------------------------------------- /.config/bin/docker_nuke: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker stop "$(docker ps -a -q)" \ 4 | && docker rm "$(docker ps -a -q)" \ 5 | && docker volume rm "$(docker volume ls -q)" \ 6 | && docker rmi "$(docker image ls -q)" 7 | -------------------------------------------------------------------------------- /.config/bin/dotfiles: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DOTFILES_DIRECTORY="${HOME}/.dotfiles" 4 | DOTFILES_TARBALL_PATH="https://github.com/gonstoll/dotfiles/tarball/master" 5 | DOTFILES_GIT_REMOTE="https://github.com/gonstoll/dotfiles.git" 6 | 7 | # If missing, download and extract the dotfiles repository 8 | if [[ ! -d ${DOTFILES_DIRECTORY} ]]; then 9 | printf "$(tput setaf 7)Downloading dotfiles...\033[m\n" 10 | mkdir ${DOTFILES_DIRECTORY} 11 | # Get the tarball 12 | curl -fsSLo ${HOME}/dotfiles.tar.gz ${DOTFILES_TARBALL_PATH} 13 | # Extract to the dotfiles directory 14 | tar -zxf ${HOME}/dotfiles.tar.gz --strip-components 1 -C ${DOTFILES_DIRECTORY} 15 | # Remove the tarball 16 | rm -rf ${HOME}/dotfiles.tar.gz 17 | fi 18 | 19 | cd ${DOTFILES_DIRECTORY} 20 | 21 | source ./other/lib/help 22 | source ./other/lib/list 23 | source ./other/lib/misc 24 | source ./other/lib/utils 25 | 26 | # Test for known flags 27 | for opt in "$@" 28 | do 29 | case $opt in 30 | --no-packages) no_packages=true ;; 31 | --no-sync) no_sync=true ;; 32 | # --no-custom-zshrc-path) no_custom_zshrc_path=true ;; 33 | -*|--*) e_warning "Warning: invalid option $opt" ;; 34 | esac 35 | done 36 | 37 | # Add custom .zshrc path 38 | # function custom_zshrc_path() { 39 | # sudo tee -a /etc/zshenv >/dev/null <<'EOF' 40 | # 41 | # if [[ -z "$XDG_CONFIG_HOME" ]] 42 | # then 43 | # export XDG_CONFIG_HOME="$HOME/.config" 44 | # fi 45 | # 46 | # if [[ -d "$XDG_CONFIG_HOME/zsh" ]] 47 | # then 48 | # export ZDOTDIR="$XDG_CONFIG_HOME/zsh/" 49 | # fi 50 | # EOF 51 | # } 52 | # 53 | # # Conditionally create a custom .zshrc path 54 | # if [[ $no_custom_zshrc_path ]]; then 55 | # printf "Skipped creating a custom .zshrc path.\n" 56 | # else 57 | # e_header "Creating custom .zshrc path..." 58 | # custom_zshrc_path 59 | # e_success "Custom .zshrc path added!" 60 | # fi 61 | 62 | # Check for Homebrew and install if missing 63 | if ! type_exists 'brew'; then 64 | e_header "Installing Homebrew..." 65 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 66 | echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> $ZDOTDIR/.zprofile 67 | eval "$(/opt/homebrew/bin/brew shellenv)" 68 | e_success "Homebrew installed successfully!" 69 | fi 70 | 71 | # Check for git and install if missing 72 | if ! type_exists 'git'; then 73 | e_header "Updating Homebrew before installing git..." 74 | brew update 75 | e_header "Installing Git..." 76 | brew install git 77 | e_success "Git installed!" 78 | fi 79 | 80 | # Initialize the git repository if it's missing 81 | if ! is_git_repo; then 82 | e_header "Initializing git repository..." 83 | git init 84 | git remote add origin ${DOTFILES_GIT_REMOTE} 85 | git fetch origin master 86 | # Reset the index and working tree to the fetched HEAD 87 | # (submodules are cloned in the subsequent sync step) 88 | git reset --hard FETCH_HEAD 89 | # Remove any untracked files 90 | git clean -fd 91 | e_success "Git repository initialized successfully!" 92 | fi 93 | 94 | # Conditionally sync with the remote repository 95 | if [[ $no_sync ]]; then 96 | printf "Skipped dotfiles sync.\n" 97 | else 98 | e_header "Syncing dotfiles git repository..." 99 | # Pull down the latest changes 100 | git pull --rebase origin master 101 | # Update submodules 102 | git submodule update --recursive --init --quiet 103 | e_success "Git submodules syncing complete!" 104 | fi 105 | 106 | # Conditionally install brew and runtime packages 107 | if [[ $no_packages ]]; then 108 | printf "Skipped package installations.\n" 109 | else 110 | printf "Installing/updating packages...\n" 111 | BREWFILE_PATH="" 112 | 113 | if [[ -z "$HOMEBREW_BUNDLE_FILE" ]]; then 114 | BREWFILE_PATH="${DOTFILES_DIRECTORY}/Brewfile" 115 | echo "export HOMEBREW_BUNDLE_FILE=${BREWFILE_PATH}" >> "$HOME/.zshenv" 116 | else 117 | BREWFILE_PATH="$HOMEBREW_BUNDLE_FILE" 118 | fi 119 | 120 | # Install Homebrew packages 121 | brew bundle --file="$BREWFILE_PATH" 122 | 123 | # Install Node packages 124 | run_misc_packages 125 | fi 126 | 127 | # Checks if you have a `init_script` file on your home directory 128 | # and moves it to the correct location 129 | if [ -f $HOME/init_script ]; then 130 | mv $HOME/init_script ./.config/bin/init_script 131 | fi 132 | 133 | # Ask before potentially overwriting stowed dotfiles 134 | seek_confirmation "Warning: This step may overwrite your existing stowed dotfiles." 135 | 136 | if is_confirmed; then 137 | is_backup=false 138 | if [ -f "$HOME/.zshrc" ] || [ -f "$HOME/.zshenv" ]; then 139 | is_backup=true 140 | e_header "Backing up your existing zsh files" 141 | [ -f "$HOME/.zshrc" ] && mv "$HOME/.zshrc" "$HOME/.zshrc.bak" 142 | [ -f "$HOME/.zshenv" ] && mv "$HOME/.zshenv" "$HOME/.zshenv.bak" 143 | fi 144 | 145 | e_header "Linking dotfiles..." 146 | 147 | stow -v . 148 | 149 | e_success "Dotfiles linked successfully!" 150 | if [ "$is_backup" = true ]; then 151 | e_warning "Your previous zsh files have been backed up with a .bak extension." 152 | fi 153 | else 154 | e_warning "Aborted linking dotfiles." 155 | exit 1 156 | fi 157 | 158 | # Ask before potentially overwriting OS X defaults 159 | seek_confirmation "Warning: This step may modify your OS X system defaults." 160 | 161 | if is_confirmed; then 162 | bash ./.config/bin/osxdefaults 163 | e_success "OS X settings updated! You may need to restart." 164 | else 165 | e_warning "Skipped OS X settings update.\n" 166 | fi 167 | 168 | if [ -f ./.config/bin/init_script ]; then 169 | e_header "Running init_script..." 170 | bash ./.config/bin/init_script 171 | e_success "init_script complete!" 172 | fi 173 | 174 | source $ZDOTDIR/.zshrc 175 | chmod +x $XDG_CONFIG_HOME/bin/* 176 | 177 | e_header "All done! You should probably restart your computer, and enjoy your new dotfiles!" 178 | -------------------------------------------------------------------------------- /.config/bin/e2e_report: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | download_dir="$HOME/Downloads" 4 | report_dir="$HOME/reports/e2e" 5 | report_file_name="report_$(date +%Y%m%d_%H%M%S).zip" 6 | report_dest="$report_dir/$report_file_name" 7 | run_tests=false 8 | 9 | source "$XDG_CONFIG_HOME/zsh/functions" 10 | 11 | for opt in "$@" 12 | do 13 | case $opt in 14 | --clean) rm -rf "$report_dir" ;; 15 | --run) run_tests=true ;; 16 | -*|--*) print_warning "Warning: invalid option $opt" 17 | esac 18 | done 19 | 20 | if [ "$run_tests" = true ]; then 21 | print_header "Running reports" 22 | npx playwright merge-reports --reporter html "$report_dir" 23 | fi 24 | 25 | if [ ! -f "$download_dir/report.zip" ]; then 26 | print_warning "No new report file found. Runnning existing reports" 27 | npx playwright merge-reports --reporter html "$report_dir" 28 | fi 29 | 30 | if [ ! -d "$report_dir" ]; then 31 | mkdir -p "$report_dir" 32 | fi 33 | 34 | print_header "Moving report to destination directory" 35 | mv "$download_dir/report.zip" "$report_dest" 36 | 37 | print_header "Running reports" 38 | npx playwright merge-reports --reporter html "$report_dir" 39 | -------------------------------------------------------------------------------- /.config/bin/git-submodule-remove: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Quickly totally remove a git submodule. Since this takes a few 4 | # steps, create a custom script to do this. 5 | 6 | # See: 7 | # https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/36593218#36593218 8 | # https://gist.github.com/myusuf3/7f645819ded92bda6677 9 | 10 | # Usage: 11 | # git-submodule-remove path/to/submodule 12 | 13 | submodule_path=$1 14 | 15 | if [ -z "$submodule_path" ]; then 16 | echo 'No submodule path specified. Exiting...' 17 | exit 1 18 | fi 19 | 20 | if [ ! -d "$submodule_path" ]; then 21 | echo 'Specify valid submodule path as first parameter' 22 | exit 1 23 | fi 24 | 25 | # Remove the submodule entry from .git/config 26 | echo "Deinitializing submodule $submodule_path" 27 | git submodule deinit -f $submodule_path 28 | echo ' ' 29 | 30 | # Remove the submodule directory from the superproject's .git/modules directory 31 | echo "Removing .git/modules for $submodule_path" 32 | rm -rf .git/modules/$submodule_path 33 | echo ' ' 34 | 35 | # Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule 36 | echo "Removing files for $submodule_path" 37 | git rm -rf $submodule_path 38 | -------------------------------------------------------------------------------- /.config/bin/note: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | markdown_dir="$HOME/notes/shell" 4 | 5 | if [ ! -d "$markdown_dir" ]; then 6 | mkdir -p "$markdown_dir" 7 | fi 8 | 9 | function create_markdown_file() { 10 | local filename 11 | filename=$(echo "$1" | tr ' ' '_') 12 | touch -c "$markdown_dir/$filename.md" 13 | nvim "$markdown_dir/$filename.md" 14 | } 15 | 16 | if [ $# -eq 0 ]; then 17 | rg --files "$markdown_dir" | fzf --preview "bat --color=always {}" 18 | else 19 | create_markdown_file "$1" 20 | fi 21 | -------------------------------------------------------------------------------- /.config/bin/obsidian: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source "$XDG_CONFIG_HOME/zsh/functions" 4 | 5 | OBSIDIAN_CONFIG="${XDG_CONFIG_HOME}/obsidian/" 6 | OBSIDIAN_NOTES="${HOME}/notes/obsidian" 7 | 8 | for opt in "$@" 9 | do 10 | case $opt in 11 | --create-vault=*) 12 | vault_name="${opt#*=}" 13 | mkdir -p "${OBSIDIAN_NOTES}/${vault_name}/.obsidian" 14 | cp -r "${OBSIDIAN_CONFIG}" "${OBSIDIAN_NOTES}/${vault_name}/.obsidian" 15 | ;; 16 | -*|--*) print_warning "Warning: invalid option $opt" ;; 17 | esac 18 | done 19 | -------------------------------------------------------------------------------- /.config/bin/osxdefaults: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ~/.macos — https://mths.be/macos 4 | # Also see: https://macos-defaults.com/ 5 | 6 | # Close any open System Preferences panes, to prevent them from overriding 7 | # settings we’re about to change 8 | osascript -e 'tell application "System Preferences" to quit' 9 | 10 | # Ask for the administrator password upfront 11 | sudo -v 12 | 13 | # Keep-alive: update existing `sudo` time stamp until `.macos` has finished 14 | while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & 15 | 16 | # Disable the sound effects on boot 17 | sudo nvram SystemAudioVolume=" " 18 | 19 | # Sync iTerm2 configs 20 | defaults write com.googlecode.iterm2 PrefsCustomFolder -string "$HOME/dotfiles/iterm2" 21 | defaults write com.googlecode.iterm2 LoadPrefsFromCustomFolder -bool true 22 | 23 | # Set wallpaper to one of the dynamic wallpapers 24 | wallpaper_image_path="$DOTFILES/other/images/wallpapers/images/tokyo-nyc/output.heic" 25 | osascript -e 'tell application "System Events" to set picture of every desktop to POSIX file "'$wallpaper_image_path'"' 26 | # Set a random wallpaper 27 | # osascript -e 'tell application "Finder" to set desktop picture to POSIX file "$(find ~/dotfiles/other/images/wallpapers -name "*.heic" -type f | shuf -n 1)"' 28 | 29 | # Enable menu-bar icons 30 | defaults write com.apple.systemuiserver menuExtras -array \ 31 | "/System/Library/CoreServices/Menu Extras/Bluetooth.menu" \ 32 | "/System/Library/CoreServices/Menu Extras/Clock.menu" \ 33 | "/System/Library/CoreServices/Menu Extras/Battery.menu" \ 34 | "/System/Library/CoreServices/Menu Extras/Volume.menu" 35 | 36 | # VSCode: disable the Apple press and hold for VSCode only 37 | defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false 38 | 39 | # Ctrl + Cmd and click to drag window from anywhere 40 | defaults write -g NSWindowShouldDragOnGesture -bool true 41 | 42 | # -------------------------- KEYBOARD -------------------------- 43 | 44 | # Set a blazingly fast keyboard repeat rate 45 | defaults write -g KeyRepeat -int 1 46 | defaults write -g InitialKeyRepeat -int 13 47 | 48 | # Disable automatic capitalization as it’s annoying when typing code 49 | defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false 50 | 51 | # Disable smart dashes as they’re annoying when typing code 52 | defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false 53 | 54 | # Disable automatic period substitution as it’s annoying when typing code 55 | defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false 56 | 57 | # Disable smart quotes as they’re annoying when typing code 58 | defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false 59 | 60 | # Disable auto-correct 61 | defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false 62 | 63 | # -------------------------- DOCK -------------------------- 64 | 65 | # Group apps on macOS dock 66 | defaults write com.apple.dock expose-group-apps -bool true 67 | 68 | # Dock size 69 | defaults write com.apple.dock "tilesize" -int "44" 70 | 71 | # Autohide dock 72 | defaults write com.apple.dock "autohide" -bool "true" 73 | 74 | # Remove recent apps from dock 75 | defaults write com.apple.dock "show-recents" -bool "false" 76 | 77 | # -------------------------- SCREENSHOTS -------------------------- 78 | 79 | # Disable shadow in screenshots 80 | defaults write com.apple.screencapture "disable-shadow" -bool "true" 81 | 82 | # Don't display date in screenshots names 83 | defaults write com.apple.screencapture "include-date" -bool "false" 84 | 85 | # -------------------------- FINDER -------------------------- 86 | 87 | # Column view as default 88 | defaults write com.apple.finder "FXPreferredViewStyle" -string "clmv" 89 | 90 | # Set $HOME as the default location for new Finder windows 91 | defaults write com.apple.finder "NewWindowTarget" -string "PfHm" 92 | defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}" 93 | 94 | # -------------------------- TRACKPAD -------------------------- 95 | 96 | # Enable three finger drag 97 | defaults write com.apple.AppleMultitouchTrackpad "TrackpadThreeFingerDrag" -bool "true" 98 | 99 | # Enable tap to click 100 | defaults write com.apple.AppleMultitouchTrackpad "Clicking" -bool "true" 101 | 102 | # -------------------------- KILL ALL -------------------------- 103 | 104 | for app in "Activity Monitor" \ 105 | "cfprefsd" \ 106 | "Dock" \ 107 | "SystemUIServer" \ 108 | "Finder"; do 109 | killall "${app}" &> /dev/null 110 | done 111 | -------------------------------------------------------------------------------- /.config/bin/tmux-sessionizer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DIRECTORIES=($(eval echo $(xargs < "$XDG_CONFIG_HOME/tmux-sessionizer/directories"))) 4 | 5 | function switch_to() { 6 | if [[ -z $TMUX ]]; then 7 | tmux attach-session -t "$1" 8 | else 9 | tmux switch-client -t "$1" 10 | fi 11 | } 12 | 13 | function has_session() { 14 | tmux list-sessions | grep -q "^$1:" 15 | } 16 | 17 | function hydrate() { 18 | if [ -f "$2/.tmux-sessionizer" ]; then 19 | tmux send-keys -t "$1" "source $2/.tmux-sessionizer" c-M 20 | elif [ -f "$XDG_CONFIG_HOME/tmux-sessionizer/default" ]; then 21 | tmux send-keys -t "$1" "source $XDG_CONFIG_HOME/tmux-sessionizer/default" c-M 22 | fi 23 | } 24 | 25 | if [[ $# -eq 1 ]]; then 26 | selected="$1" 27 | else 28 | selected=$(find "${DIRECTORIES[@]}" -mindepth 1 -maxdepth 1 -type d | fzf \ 29 | --border=rounded \ 30 | --border-label="[tmux sessionizer]" \ 31 | --prompt=" " \ 32 | --no-bold \ 33 | --height=100% \ 34 | ) 35 | fi 36 | 37 | if [[ -z "$selected" ]]; then 38 | exit 0 39 | fi 40 | 41 | selected_name=$(basename "$selected" | tr . _) 42 | tmux_running=$(pgrep tmux) 43 | 44 | if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then 45 | tmux new-session -ds "$selected_name" -c "$selected" 46 | hydrate "$selected_name" "$selected" 47 | fi 48 | 49 | if ! has_session "$selected_name"; then 50 | tmux new-session -ds "$selected_name" -c "$selected" 51 | hydrate "$selected_name" "$selected" 52 | fi 53 | 54 | switch_to "$selected_name" 55 | -------------------------------------------------------------------------------- /.config/bin/u: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # Taken from: https://github.com/joshmedeski/dotfiles/blob/main/.config/bin/u 3 | 4 | gum style \ 5 | --foreground 12 --border-foreground 12 --border double \ 6 | --margin "1 0" --padding "0 2" \ 7 | ' 8 | ██╗ ██╗██████╗ ██████╗ █████╗ ████████╗███████╗ 9 | ██║ ██║██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██╔════╝ 10 | ██║ ██║██████╔╝██║ ██║███████║ ██║ █████╗ 11 | ██║ ██║██╔═══╝ ██║ ██║██╔══██║ ██║ ██╔══╝ 12 | ╚██████╔╝██║ ██████╔╝██║ ██║ ██║ ███████╗ 13 | ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ 14 | ' 15 | 16 | 17 | set -l NOW $(date +%Y-%m-%d-%H-%M-%S) 18 | echo -e "$NOW\n" >>/tmp/u-$NOW.txt 19 | 20 | gum confirm "Do you wish to update your scripts?" 21 | 22 | if [ $? -eq 1 ]; then 23 | exit 1 24 | fi 25 | 26 | gum spin --spinner globe --title "🪟 tpm plugins updating..." --show-output -- ~/.config/tmux/plugins/tpm/bin/update_plugins all >>/tmp/u-$NOW.txt 27 | echo "\n" >>/tmp/u-$NOW.txt 28 | echo "✅ 🪟 tpm plugins updated" 29 | 30 | gum spin --spinner globe --title "💤 lazy.nvim syncing..." -- nvim --headless "+Lazy! sync" +qa 31 | echo "\n" >>/tmp/u-$NOW.txt 32 | echo "✅ 💤 lazy.nvim synced" 33 | 34 | gum spin --spinner globe --title "🧰 mason.nvim updating" -- nvim --headless "+MasonUpdate" +qa 35 | echo "\n" >>/tmp/u-$NOW.txt 36 | echo "✅ 🧰 mason.nvim updated" 37 | 38 | gum spin --spinner globe --title "🌳 nvim-treesitter updating" -- nvim --headless "+TSUpdate" +qa 39 | echo "\n" >>/tmp/u-$NOW.txt 40 | echo "✅ 🌳 nvim-treesitter updated" 41 | 42 | gum spin --spinner globe --title "🍻 brew updating" --show-output -- brew update >>/tmp/u-$NOW.txt 43 | echo "\n" >>/tmp/u-$NOW.txt 44 | echo "✅ 🍻 brew updated" 45 | 46 | set -l OUTDATED (brew outdated) 47 | echo $OUTDATED >>/tmp/u-$NOW.txt 48 | 49 | if test -n "$OUTDATED" 50 | gum spin --spinner globe --title "🍻 brew upgrading" --show-output -- brew upgrade >>/tmp/u-$NOW.txt 51 | echo "\n" >>/tmp/u-$NOW.txt 52 | echo "✅ 🍻 brew upgraded" 53 | 54 | gum spin --spinner globe --title "🍻 brew cleaning up" --show-output -- brew cleanup --prune=all >>/tmp/u-$NOW.txt 55 | echo "\n" >>/tmp/u-$NOW.txt 56 | echo "✅ 🍻 brew cleaned up" 57 | else 58 | echo "No outdated brew packages" >>/tmp/u-$NOW.txt 59 | end 60 | 61 | gum spin --spinner globe --title "🍻 brew doctoring" --show-output -- brew doctor >>/tmp/u-$NOW.txt 62 | echo "\n" >>/tmp/u-$NOW.txt 63 | echo "✅ 🍻 brew doctored" 64 | 65 | echo "✅ 🧾 logged to /tmp/u-$NOW.txt" 66 | man /tmp/u-$NOW.txt 67 | -------------------------------------------------------------------------------- /.config/bin/update_go: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | go_installer="$(curl -s 'https://go.dev/VERSION?m=text' | head -n 1).darwin-arm64.pkg" 4 | go_link="https://go.dev/dl/$go_installer" 5 | go_tmp="/tmp/go" 6 | 7 | curl --create-dirs --output-dir $go_tmp -JOL "$go_link" 8 | rm -rf /usr/local/go 9 | sudo installer -pkg "$go_tmp/$go_installer" -target /usr/local 10 | rm -rf $go_tmp 11 | -------------------------------------------------------------------------------- /.config/borders/bordersrc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | options=( 4 | style=round 5 | width=5.0 6 | hidpi=on 7 | active_color=0xfff6f8fa 8 | blacklist="ghostty,wezterm-gui,alacritty,kitty" 9 | ) 10 | 11 | borders "${options[@]}" 12 | -------------------------------------------------------------------------------- /.config/btop/themes/rosepine.theme: -------------------------------------------------------------------------------- 1 | # Theme: rosepine 2 | # By: Gonzalo Stoll 3 | 4 | # Main bg 5 | theme[main_bg]="#000000" 6 | 7 | # Main text color 8 | theme[main_fg]="#e0def4" 9 | 10 | # Title color for boxes 11 | theme[title]="#e0def4" 12 | 13 | # Highlight color for keyboard shortcuts 14 | theme[hi_fg]="#437e91" 15 | 16 | # Background color of selected item in processes box 17 | theme[selected_bg]="#233136" 18 | 19 | # Foreground color of selected item in processes box 20 | theme[selected_fg]="#e0def4" 21 | 22 | # Color of inactive/disabled text 23 | theme[inactive_fg]="#a1d1da" 24 | 25 | # Misc colors for processes box including mini cpu graphs, details memory graph and details status text 26 | theme[proc_misc]="#437e91" 27 | 28 | # Cpu box outline color 29 | theme[cpu_box]="#a1d1da" 30 | 31 | # Memory/disks box outline color 32 | theme[mem_box]="#a1d1da" 33 | 34 | # Net up/down box outline color 35 | theme[net_box]="#a1d1da" 36 | 37 | # Processes box outline color 38 | theme[proc_box]="#a1d1da" 39 | 40 | # Box divider line and small boxes line color 41 | theme[div_line]="#a1d1da" 42 | 43 | # Temperature graph colors 44 | theme[temp_start]="#ebbcba" 45 | theme[temp_mid]="#d9c7ef" 46 | theme[temp_end]="#eb6f92" 47 | 48 | # CPU graph colors 49 | theme[cpu_start]="#ebbcba" 50 | theme[cpu_mid]="#d9c7ef" 51 | theme[cpu_end]="#eb6f92" 52 | 53 | # Mem/Disk free meter 54 | theme[free_start]="#ebbcba" 55 | theme[free_mid]="#d9c7ef" 56 | theme[free_end]="#eb6f92" 57 | 58 | # Mem/Disk cached meter 59 | theme[cached_start]="#ebbcba" 60 | theme[cached_mid]="#d9c7ef" 61 | theme[cached_end]="#eb6f92" 62 | 63 | # Mem/Disk available meter 64 | theme[available_start]="#ebbcba" 65 | theme[available_mid]="#d9c7ef" 66 | theme[available_end]="#eb6f92" 67 | 68 | # Mem/Disk used meter 69 | theme[used_start]="#ebbcba" 70 | theme[used_mid]="#d9c7ef" 71 | theme[used_end]="#eb6f92" 72 | 73 | # Download graph colors 74 | theme[download_start]="#ebbcba" 75 | theme[download_mid]="#d9c7ef" 76 | theme[download_end]="#eb6f92" 77 | 78 | # Upload graph colors 79 | theme[upload_start]="#ebbcba" 80 | theme[upload_mid]="#d9c7ef" 81 | theme[upload_end]="#eb6f92" 82 | -------------------------------------------------------------------------------- /.config/btop/themes/zenbones.theme: -------------------------------------------------------------------------------- 1 | # Theme: zenbones 2 | # By: Gonzalo Stoll 3 | 4 | # Main bg 5 | theme[main_bg]="#181616" 6 | 7 | # Main text color 8 | theme[main_fg]="#b4bdc3" 9 | 10 | # Title color for boxes 11 | theme[title]="#b4bdc3" 12 | 13 | # Highlight color for keyboard shortcuts 14 | theme[hi_fg]="#6099c0" 15 | 16 | # Background color of selected item in processes box 17 | theme[selected_bg]="#414868" 18 | 19 | # Foreground color of selected item in processes box 20 | theme[selected_fg]="#b4bdc3" 21 | 22 | # Color of inactive/disabled text 23 | theme[inactive_fg]="#6d8086" 24 | 25 | # Misc colors for processes box including mini cpu graphs, details memory graph and details status text 26 | theme[proc_misc]="#6099c0" 27 | 28 | # Cpu box outline color 29 | theme[cpu_box]="#6d8086" 30 | 31 | # Memory/disks box outline color 32 | theme[mem_box]="#6d8086" 33 | 34 | # Net up/down box outline color 35 | theme[net_box]="#6d8086" 36 | 37 | # Processes box outline color 38 | theme[proc_box]="#6d8086" 39 | 40 | # Box divider line and small boxes line color 41 | theme[div_line]="#6d8086" 42 | 43 | # Temperature graph colors 44 | theme[temp_start]="#819b69" 45 | theme[temp_mid]="#a1938c" 46 | theme[temp_end]="#de6e7c" 47 | 48 | # CPU graph colors 49 | theme[cpu_start]="#819b69" 50 | theme[cpu_mid]="#a1938c" 51 | theme[cpu_end]="#de6e7c" 52 | 53 | # Mem/Disk free meter 54 | theme[free_start]="#819b69" 55 | theme[free_mid]="#a1938c" 56 | theme[free_end]="#de6e7c" 57 | 58 | # Mem/Disk cached meter 59 | theme[cached_start]="#819b69" 60 | theme[cached_mid]="#a1938c" 61 | theme[cached_end]="#de6e7c" 62 | 63 | # Mem/Disk available meter 64 | theme[available_start]="#819b69" 65 | theme[available_mid]="#a1938c" 66 | theme[available_end]="#de6e7c" 67 | 68 | # Mem/Disk used meter 69 | theme[used_start]="#819b69" 70 | theme[used_mid]="#a1938c" 71 | theme[used_end]="#de6e7c" 72 | 73 | # Download graph colors 74 | theme[download_start]="#819b69" 75 | theme[download_mid]="#a1938c" 76 | theme[download_end]="#de6e7c" 77 | 78 | # Upload graph colors 79 | theme[upload_start]="#819b69" 80 | theme[upload_mid]="#a1938c" 81 | theme[upload_end]="#de6e7c" 82 | -------------------------------------------------------------------------------- /.config/ghostty/config: -------------------------------------------------------------------------------- 1 | # Fonts, underlines 2 | # font-family = SFMono Nerd Font 3 | # font-style-italic = Regular Italic 4 | font-size = 18 5 | font-feature = -calt 6 | font-feature = -liga 7 | font-feature = -dlig 8 | adjust-underline-position = 2 9 | adjust-cell-height = -1 10 | 11 | # Windows, colors and styles 12 | theme = rose-pine-muted 13 | macos-titlebar-style = hidden 14 | window-padding-y = 2,0 15 | window-padding-x = 2 16 | window-padding-balance = true 17 | 18 | # macOS stuff 19 | macos-option-as-alt = left 20 | macos-window-shadow = false 21 | 22 | # Keys 23 | # Ascii device control codes: https://www3.rocketsoftware.com/bluezone/help/v42/en/bzadmin/APPENDIX_C/ASCII_Character_Set.htm 24 | keybind = alt+left=unbind 25 | keybind = alt+right=unbind 26 | keybind = super+enter=unbind 27 | 28 | # Tmux-sessionizer: Ctrl-f+S (.zshrc binds this to `s\n`, since `s` is an alias 29 | # for tmux-sessionizer) 30 | keybind = cmd+s=text:\x06\x53 31 | keybind = cmd+b=text:\x06\x42 32 | -------------------------------------------------------------------------------- /.config/ghostty/themes/rose-pine-muted: -------------------------------------------------------------------------------- 1 | palette = 0=#393552 2 | palette = 1=#eb6f92 3 | palette = 2=#a1d1da 4 | palette = 3=#f6d5a7 5 | palette = 4=#437e91 6 | palette = 5=#d9c7ef 7 | palette = 6=#ebbcba 8 | palette = 7=#e0def4 9 | palette = 8=#817c9c 10 | palette = 9=#eb6f92 11 | palette = 10=#a1d1da 12 | palette = 11=#f6d5a7 13 | palette = 12=#437e91 14 | palette = 13=#d9c7ef 15 | palette = 14=#ebbcba 16 | palette = 15=#e0def4 17 | background = #000000 18 | foreground = #e0def4 19 | cursor-text = #010101 20 | selection-background = #312f44 21 | selection-foreground = #e0def4 22 | -------------------------------------------------------------------------------- /.config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | font_family JetBrainsMonoNL Nerd Font Mono 2 | bold_font auto 3 | italic_font auto 4 | bold_italic_font auto 5 | font_size 18.0 6 | 7 | hide_window_decorations titlebar-only 8 | 9 | shell_integration no-cursor 10 | cursor_shape block 11 | cursor #ffffff 12 | cursor_text_color #010101 13 | 14 | background #000000 15 | foreground #e0def4 16 | color0 #393552 17 | color1 #eb6f92 18 | color2 #a1d1da 19 | color3 #f6d5a7 20 | color4 #437e91 21 | color5 #d9c7ef 22 | color6 #ebbcba 23 | color7 #e0def4 24 | color8 #817c9c 25 | color9 #eb6f92 26 | color10 #a1d1da 27 | color11 #f6d5a7 28 | color12 #437e91 29 | color13 #d9c7ef 30 | color14 #ebbcba 31 | color15 #e0def4 32 | selection_background #312f44 33 | selection_foreground #e0def4 34 | 35 | map cmd+r load_config_file 36 | map cmd+s send_text all \x06\x53 37 | -------------------------------------------------------------------------------- /.config/lazydocker/config.yml: -------------------------------------------------------------------------------- 1 | gui: 2 | border: 'single' 3 | -------------------------------------------------------------------------------- /.config/lazygit/config.yml: -------------------------------------------------------------------------------- 1 | git: 2 | overrideGpg: true 3 | 4 | os: 5 | editPreset: nvim 6 | 7 | gui: 8 | border: 'single' 9 | branchColors: 10 | 'master': red 11 | 12 | nerdFontsVersion: '3' 13 | 14 | filterMode: fuzzy 15 | 16 | theme: 17 | selectedLineBgColor: 18 | - reverse 19 | -------------------------------------------------------------------------------- /.config/nvim/.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", 3 | "diagnostics": { 4 | "disable": [ "deprecated", "missing-fields" ] 5 | }, 6 | "format": { 7 | "enable": true, 8 | "defaultConfig": { 9 | "indent_size": "4", 10 | "tab_width": "4", 11 | "quote_style": "double", 12 | "call_arg_parentheses": "keep", 13 | "trailing_table_separator": "smart", 14 | "space_around_table_field_list": "false", 15 | "space_before_attribute": "false", 16 | "space_inside_square_brackets": "false", 17 | "align_call_args": "false", 18 | "align_function_params": "false", 19 | "align_continuous_assign_statement": "false", 20 | "align_continuous_rect_table_field": "false", 21 | "align_if_branch": "false", 22 | "align_array_table": "false" 23 | } 24 | }, 25 | "workspace": { 26 | "checkThirdParty": false 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.config/nvim/README.md: -------------------------------------------------------------------------------- 1 | # Neovim configuration 2 | 3 | Dotfiles screenshot 4 | 5 | This is my Neovim configuration. Take from it what you need! 6 | 7 | Always a WIP 😅 8 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/dap-float.vim: -------------------------------------------------------------------------------- 1 | nnoremap q :q 2 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/fugitive.lua: -------------------------------------------------------------------------------- 1 | vim.keymap.set("n", "P", function() 2 | vim.cmd.Git("push") 3 | end, {buffer = true, remap = false, desc = "Fugitive: Push"}) 4 | vim.keymap.set("n", "p", function() 5 | vim.cmd.Git("pull") 6 | end, {buffer = true, remap = false, desc = "Fugitive: Pull"}) 7 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/go.vim: -------------------------------------------------------------------------------- 1 | set tabstop=4 2 | set shiftwidth=4 3 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/json.lua: -------------------------------------------------------------------------------- 1 | -- When creating a new line with o, make sure there is a trailing comma on the current line 2 | vim.keymap.set("n", "o", function() 3 | local line = vim.api.nvim_get_current_line() 4 | local should_add_comma = string.find(line, "[^,{[]$") 5 | 6 | if should_add_comma then 7 | return "A," 8 | else 9 | return "o" 10 | end 11 | end, {buffer = true, expr = true}) 12 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/lazy.vim: -------------------------------------------------------------------------------- 1 | setlocal cursorline 2 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/lua.vim: -------------------------------------------------------------------------------- 1 | " remove {o|O} newline auto-comments 2 | setlocal formatoptions-=o 3 | set tabstop=4 4 | set shiftwidth=4 5 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/netrw.vim: -------------------------------------------------------------------------------- 1 | " Open file in vertical split 2 | " let g:netrw_browse_split = 2 3 | " Remove netrw banner 4 | let g:netrw_banner = 0 5 | " Long list style (time stamp information and file size) 6 | let g:netrw_liststyle = 1 7 | let g:netrw_bufsettings = 'noma nomod nu nobl nowrap ro' 8 | let g:netrw_winsize = 50 9 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/python.lua: -------------------------------------------------------------------------------- 1 | vim.opt.tabstop = 4 2 | vim.opt.shiftwidth = 4 3 | 4 | vim.keymap.set('n', 'pr', function() 5 | local filepath = vim.fn.expand('%') 6 | local py_cmd = 'python3 ' .. filepath 7 | local cmd = 'sh -c "' .. py_cmd .. '; exec $SHELL"' 8 | vim.cmd.new() 9 | vim.cmd.wincmd('J') 10 | vim.api.nvim_win_set_height(0, 14) 11 | vim.wo.winfixheight = true 12 | 13 | -- Open terminal window, execute file and keep terminal open 14 | vim.cmd.term(cmd) 15 | end, {desc = 'Python: Run current file'}) 16 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/qf.vim: -------------------------------------------------------------------------------- 1 | setlocal relativenumber! 2 | setlocal cursorline 3 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/sh.vim: -------------------------------------------------------------------------------- 1 | set tabstop=4 2 | set shiftwidth=4 3 | -------------------------------------------------------------------------------- /.config/nvim/after/ftplugin/zsh.vim: -------------------------------------------------------------------------------- 1 | set filetype=bash 2 | -------------------------------------------------------------------------------- /.config/nvim/filetype.lua: -------------------------------------------------------------------------------- 1 | vim.filetype.add({ 2 | filename = { 3 | [".eslintrc.json"] = "jsonc", 4 | }, 5 | pattern = { 6 | ["tsconfig*.json"] = "jsonc", 7 | [".*/%.vscode/.*%.json"] = "jsonc", 8 | -- Borrowed from LazyVim. Mark huge files to disable features later. 9 | [".*"] = function(path, bufnr) 10 | return vim.bo[bufnr] 11 | and vim.bo[bufnr].filetype ~= "bigfile" 12 | and path 13 | and vim.fn.getfsize(path) > (1024 * 500) -- 500 KB 14 | and "bigfile" 15 | or nil 16 | end, 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /.config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- Add `t_RB` so that neovim detect background 2 | -- https://github.com/neovim/neovim/issues/17070#issuecomment-1086775760 3 | -- vim.loop.fs_write(2, '\27Ptmux;\27\27]11;?\7\27\\', -1, nil) 4 | 5 | vim.g.blink_enabled = true 6 | _G.Utils = require("utils") 7 | 8 | require("core") 9 | require("lsp") 10 | 11 | vim.filetype.add({ 12 | extension = { 13 | env = "sh", 14 | }, 15 | filename = { 16 | [".env"] = "sh", 17 | }, 18 | pattern = { 19 | ["%.env%.[%w_.-]+"] = "sh", 20 | }, 21 | }) 22 | -------------------------------------------------------------------------------- /.config/nvim/lazy-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, 3 | "CopilotChat.nvim": { "branch": "main", "commit": "16d897fd43d07e3b54478ccdb2f8a16e4df4f45a" }, 4 | "FixCursorHold.nvim": { "branch": "master", "commit": "1900f89dc17c603eec29960f57c00bd9ae696495" }, 5 | "SchemaStore.nvim": { "branch": "main", "commit": "6c52c57432280c54596feb0c0958e1a6cb546f4d" }, 6 | "auto-session": { "branch": "main", "commit": "00334ee24b9a05001ad50221c8daffbeedaa0842" }, 7 | "avante.nvim": { "branch": "main", "commit": "bc403ddcbf98c4181ee2a7efd35cd1e18a2fdc5c" }, 8 | "blame.nvim": { "branch": "main", "commit": "b87b8c820e4cec06fbbd2f946b7b35c45906ee0c" }, 9 | "blink.cmp": { "branch": "main", "commit": "022521a8910a5543b0251b21c9e1a1e989745796" }, 10 | "cellular-automaton.nvim": { "branch": "main", "commit": "1606e9d5d04ff254023c3f3c62842d065708d6d3" }, 11 | "conform.nvim": { "branch": "master", "commit": "6feb2f28f9a9385e401857b21eeac3c1b66dd628" }, 12 | "copilot.lua": { "branch": "master", "commit": "5f726c8e6bbcd7461ee0b870d4e6c8a973b55b64" }, 13 | "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" }, 14 | "dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" }, 15 | "duck.nvim": { "branch": "main", "commit": "d8a6b08af440e5a0e2b3b357e2f78bb1883272cd" }, 16 | "fidget.nvim": { "branch": "main", "commit": "d9ba6b7bfe29b3119a610892af67602641da778e" }, 17 | "fzf-lua": { "branch": "main", "commit": "8c8845ca6d05bc768b7ce27ebe3682ddf7e6a996" }, 18 | "gitsigns.nvim": { "branch": "main", "commit": "8bdaccdb897945a3c99c1ad8df94db0ddf5c8790" }, 19 | "gruvbox-material": { "branch": "master", "commit": "f5f912fbc7cf2d45da6928b792d554f85c7aa89a" }, 20 | "harpoon": { "branch": "harpoon2", "commit": "ed1f853847ffd04b2b61c314865665e1dadf22c7" }, 21 | "lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" }, 22 | "lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" }, 23 | "lazygit.nvim": { "branch": "main", "commit": "b9eae3badab982e71abab96d3ee1d258f0c07961" }, 24 | "let-it-snow.nvim": { "branch": "main", "commit": "823511ad1b0d36e44f9c5e2418892e7438f23a41" }, 25 | "lush.nvim": { "branch": "main", "commit": "45a79ec4acb5af783a6a29673a999ce37f00497e" }, 26 | "luvit-meta": { "branch": "main", "commit": "1df30b60b1b4aecfebc785aa98943db6c6989716" }, 27 | "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, 28 | "mason-lspconfig.nvim": { "branch": "main", "commit": "60eaff7a470b8e78ddff09d847d17a011f560759" }, 29 | "mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" }, 30 | "neogen": { "branch": "main", "commit": "d7f9461727751fb07f82011051338a9aba07581d" }, 31 | "neotest": { "branch": "master", "commit": "ef492755730e59e1d8122c461abbd086bee4c76b" }, 32 | "neotest-golang": { "branch": "main", "commit": "5718217f750704210a6b62f6b294e272f2bf5516" }, 33 | "neotest-jest": { "branch": "main", "commit": "4e1f81fed36a1dc46c45ddce5afac41a99e1cfe6" }, 34 | "neotest-playwright": { "branch": "master", "commit": "6266945039dac27a354de33d2f2a66e75485d5e9" }, 35 | "neotest-vitest": { "branch": "main", "commit": "a6099e1fb55a2c2851da3dd0f4d510af9a234c92" }, 36 | "nui.nvim": { "branch": "main", "commit": "7cd18e73cfbd70e1546931b7268b3eebaeff9391" }, 37 | "nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" }, 38 | "nvim-dap": { "branch": "master", "commit": "b0f983507e3702f073bfe1516846e58b56d4e42f" }, 39 | "nvim-dap-go": { "branch": "main", "commit": "8763ced35b19c8dc526e04a70ab07c34e11ad064" }, 40 | "nvim-dap-ui": { "branch": "master", "commit": "73a26abf4941aa27da59820fd6b028ebcdbcf932" }, 41 | "nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" }, 42 | "nvim-early-retirement": { "branch": "main", "commit": "6db15a859cf73d4027e919f5a49cc795ee96831a" }, 43 | "nvim-lspconfig": { "branch": "master", "commit": "03bc581e05e81d33808b42b2d7e76d70adb3b595" }, 44 | "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, 45 | "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, 46 | "nvim-treesitter-context": { "branch": "master", "commit": "ed1cf48d5af252248c55f50b9427e8ce883a2c6b" }, 47 | "nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" }, 48 | "nvim-ts-context-commentstring": { "branch": "main", "commit": "1b212c2eee76d787bbea6aa5e92a2b534e7b4f8f" }, 49 | "nvim-web-devicons": { "branch": "master", "commit": "1fb58cca9aebbc4fd32b086cb413548ce132c127" }, 50 | "octo.nvim": { "branch": "master", "commit": "53a424b7432d97f3ef0b5cf7a08972d7c9974f5a" }, 51 | "oil.nvim": { "branch": "master", "commit": "685cdb4ffa74473d75a1b97451f8654ceeab0f4a" }, 52 | "one-small-step-for-vimkind": { "branch": "main", "commit": "2eff53bed71e7e0737d1bd7c22de79d99ae0dad7" }, 53 | "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" }, 54 | "rose-pine": { "branch": "main", "commit": "6b9840790cc7acdfadde07f308d34b62dd9cc675" }, 55 | "snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" }, 56 | "statuscol.nvim": { "branch": "main", "commit": "a2580e009a3b4c51b5978768d907dafae2c919ac" }, 57 | "todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" }, 58 | "vim-fugitive": { "branch": "master", "commit": "4a745ea72fa93bb15dd077109afbb3d1809383f2" }, 59 | "vim-surround": { "branch": "master", "commit": "3d188ed2113431cf8dac77be61b842acb64433d9" }, 60 | "vim-tmux-navigator": { "branch": "master", "commit": "96da8e10ce83b754f442c3e25d1bf74451d220f2" }, 61 | "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" }, 62 | "yazi.nvim": { "branch": "main", "commit": "59c22d1a8bcb3d00a7115ef7f2d59b90cf989ab3" }, 63 | "zenbones.nvim": { "branch": "main", "commit": "9deaa8a38e43e8c587b427095dd43c3511255b21" } 64 | } 65 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/autocommands.lua: -------------------------------------------------------------------------------- 1 | local augroup = vim.api.nvim_create_augroup 2 | local autocmd = vim.api.nvim_create_autocmd 3 | 4 | -- Highlight yanked text 5 | autocmd("TextYankPost", { 6 | desc = "Highlight yanked text", 7 | group = augroup("YankHighlight", {}), 8 | callback = function() 9 | vim.highlight.on_yank() 10 | end, 11 | }) 12 | 13 | -- Disable eslint on node_modules 14 | autocmd({"BufNewFile", "BufRead"}, { 15 | pattern = {"**/node_modules/**", "node_modules", "/node_modules/*"}, 16 | group = augroup("DisableEslintOnNodeModules", {}), 17 | callback = function() 18 | vim.diagnostic.enable(false) 19 | end, 20 | }) 21 | 22 | -- Statusline 23 | local statusline_group = augroup("StatusLine", {}) 24 | autocmd({"WinEnter", "BufEnter"}, { 25 | pattern = "*", 26 | group = statusline_group, 27 | callback = function() 28 | if (vim.bo.filetype == "oil") then 29 | vim.wo.statusline = "%!v:lua.require('statusline').oil()" 30 | return 31 | end 32 | vim.wo.statusline = "%!v:lua.require('statusline').active()" 33 | end, 34 | }) 35 | 36 | autocmd({"WinLeave", "BufLeave"}, { 37 | pattern = "*", 38 | group = statusline_group, 39 | callback = function(args) 40 | local leaving_buf_filetype = vim.api.nvim_get_option_value("filetype", {buf = args.buf}) 41 | if (leaving_buf_filetype == "oil") then 42 | vim.wo.statusline = "%!v:lua.require('statusline').oil()" 43 | return 44 | end 45 | vim.wo.statusline = "%!v:lua.require('statusline').inactive()" 46 | end, 47 | }) 48 | 49 | autocmd("ColorScheme", { 50 | group = augroup("cursor-highlight", {}), 51 | callback = function() 52 | if vim.o.background == "light" then 53 | vim.cmd("highlight! clear Cursor") 54 | end 55 | end, 56 | }) 57 | 58 | autocmd("TermOpen", { 59 | group = augroup("custom-term-open", {}), 60 | callback = function() 61 | vim.opt_local.number = false 62 | vim.opt_local.relativenumber = false 63 | vim.opt_local.scrolloff = 0 64 | end, 65 | }) 66 | 67 | autocmd("FileType", { 68 | pattern = "*", 69 | group = augroup("diable-new-line-comments", {}), 70 | callback = function() 71 | vim.opt_local.formatoptions:remove("o") 72 | vim.opt_local.formatoptions:remove("r") 73 | vim.opt_local.formatoptions:remove("c") 74 | end, 75 | }) 76 | 77 | autocmd("BufWritePost", { 78 | pattern = "aerospace.toml", 79 | group = augroup("Aerospace", {}), 80 | command = "!aerospace reload-config", 81 | }) 82 | 83 | autocmd("BufWritePost", { 84 | pattern = "*", 85 | group = augroup("FileDetect", {}), 86 | desc = "Detect filetype on files with on extension after saving the file", 87 | callback = function() 88 | if vim.bo.filetype == "" then 89 | vim.cmd("filetype detect") 90 | end 91 | end, 92 | }) 93 | 94 | -- Redir 95 | vim.api.nvim_create_user_command("Redir", Utils.redir.redir, { 96 | nargs = "+", 97 | complete = "command", 98 | range = true, 99 | bang = true, 100 | }) 101 | 102 | vim.api.nvim_create_user_command("EvalFile", function(args) 103 | local bang = args.bang 104 | Utils.redir.evaler("%")(bang) 105 | end, {bar = true, bang = true}) 106 | 107 | vim.api.nvim_create_user_command("EvalLine", function(args) 108 | local bang = args.bang 109 | Utils.redir.evaler(".")(bang) 110 | end, {bar = true, bang = true}) 111 | 112 | vim.api.nvim_create_user_command("EvalRange", function(args) 113 | local bang = args.bang 114 | Utils.redir.evaler("'<,'>")(bang) 115 | end, {bar = true, bang = true, range = true}) 116 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/base.lua: -------------------------------------------------------------------------------- 1 | vim.g.mapleader = " " 2 | vim.g.maplocalleader = " " 3 | vim.opt.termguicolors = true 4 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/highlights.lua: -------------------------------------------------------------------------------- 1 | vim.api.nvim_set_hl(0, "LazyGitBorder", {link = "FloatBorder"}) 2 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/init.lua: -------------------------------------------------------------------------------- 1 | require("core.base") 2 | require("core.lazy") 3 | require("core.options") 4 | require("core.keymaps") 5 | require("core.autocommands") 6 | require("core.highlights") 7 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/keymaps.lua: -------------------------------------------------------------------------------- 1 | local keyset = vim.keymap.set 2 | 3 | -- keyset('n', '-', function() 4 | -- local cur_file = vim.fn.expand('%:t') 5 | -- vim.cmd.Ex() 6 | -- vim.fn.search('^' .. cur_file .. '$') 7 | -- end, {desc = 'Open Netrw'}) 8 | -- keyset('n', '', vim.cmd.Rex, {desc = 'Open last visited file'}) 9 | 10 | keyset("c", "", "", { desc = "Edit command in cmdline mode" }) 11 | keyset("n", "", "ggG", { desc = "Select all" }) 12 | 13 | -- New tab 14 | keyset("n", "tn", ":tabnew %", { desc = "New tab" }) 15 | keyset("n", "tc", ":tabclose", { desc = "Close tab" }) 16 | -- Split window 17 | keyset("n", "ss", ":splitw", { desc = "Split window horizontally" }) -- Horizontal 18 | keyset("n", "sv", ":vsplitw", { desc = "Split window vertically" }) -- Vertical 19 | 20 | -- Move between qf items 21 | keyset("n", "", "cprevzz", { desc = "Previous quickfix item" }) 22 | keyset("n", "", "cnextzz", { desc = "Next quickfix item" }) 23 | 24 | -- Resize splits 25 | keyset("n", "", "5>", { desc = "Resize window (left)" }) 26 | keyset("n", "", "5<", { desc = "Resize window (right)" }) 27 | keyset("n", "", "5-", { desc = "Resize window (down)" }) 28 | keyset("n", "", "5+", { desc = "Resize window (up)" }) 29 | 30 | -- Move lines 31 | keyset("v", "J", ":m '>+1gv=gv", { desc = "Move line down" }) 32 | keyset("v", "K", ":m '<-2gv=gv", { desc = "Move line up" }) 33 | keyset("n", "J", "mzJ`z") 34 | 35 | -- Jumping pages keeps cursor in the middle 36 | keyset("n", "", "zz", { desc = "Jump page down" }) 37 | keyset("n", "", "zz", { desc = "Jump page up" }) 38 | 39 | -- Keep search terms in the middle of the screen 40 | keyset("n", "n", "nzzzv", { desc = "Jump to next search term" }) 41 | keyset("n", "N", "Nzzzv", { desc = "Jump to previous search term" }) 42 | 43 | -- Pastes copied buffer and keeps it in the register 44 | keyset("x", "pp", '"_dP') 45 | 46 | -- Sources current buffer 47 | keyset("n", "x", function() 48 | vim.cmd("so") 49 | end, { desc = "Source current buffer" }) 50 | keyset("n", "X", ":.lua", { desc = "Source current line" }) 51 | keyset("v", "X", ":.lua", { desc = "Source current selection" }) 52 | 53 | -- Opens fugitive 54 | keyset("n", "gf", ":top Git", { desc = "Fugitive: Open git console" }) 55 | 56 | -- Toggle highlighting search 57 | keyset("n", ";h", ":set hlsearch!", { desc = "Toggle highlighting search" }) 58 | 59 | -- Save without formatting 60 | keyset("n", "wf", ":noautocmd w", { desc = "Save without formatting" }) 61 | 62 | -- Open terminal below 63 | keyset("n", "st", function() 64 | vim.cmd.new() 65 | vim.cmd.wincmd("J") -- Move to the window below 66 | vim.api.nvim_win_set_height(0, 12) 67 | vim.wo.winfixheight = true 68 | vim.cmd.term() 69 | end, { desc = "Open terminal below" }) 70 | 71 | keyset("t", "", "", { desc = "Exit terminal mode" }) 72 | 73 | keyset("n", "bg", function() 74 | local active_bg = vim.o.background 75 | if active_bg == "dark" then 76 | vim.cmd("set background=light") 77 | else 78 | vim.cmd("set background=dark") 79 | end 80 | end, { desc = "Toggle background" }) 81 | 82 | keyset({ "i", "s" }, "", function() 83 | vim.snippet.stop() 84 | return "" 85 | end, { expr = true, desc = "Close snippet session" }) 86 | 87 | keyset("n", "cm", ":!chmod +x %", { desc = "Make file executable" }) 88 | 89 | keyset("n", "gh", "_", { desc = "Go to start of line" }) 90 | keyset("n", "gl", "$", { desc = "Go to end of line" }) 91 | 92 | keyset({ "n", "v", "i" }, "", function() 93 | require("fzf-lua").complete_path() 94 | end, { silent = true, desc = "Fuzzy complete path" }) 95 | 96 | keyset("n", "bb", function() 97 | vim.ui.input({ prompt = "Search: " }, function(input) 98 | if input then 99 | Utils.browse.query_browser(input) 100 | end 101 | end) 102 | end, { desc = "Browse on the web" }) 103 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/lazy.lua: -------------------------------------------------------------------------------- 1 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 2 | if not (vim.uv or vim.loop).fs_stat(lazypath) then 3 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 4 | local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) 5 | if vim.v.shell_error ~= 0 then 6 | vim.api.nvim_echo({ 7 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 8 | { out, "WarningMsg" }, 9 | { "\nPress any key to exit..." }, 10 | }, true, {}) 11 | vim.fn.getchar() 12 | os.exit(1) 13 | end 14 | end 15 | vim.opt.rtp:prepend(lazypath) 16 | 17 | require("lazy").setup({ 18 | spec = { 19 | { import = "plugins" }, 20 | { import = "plugins.cmp" }, 21 | { import = "plugins.colorscheme" }, 22 | }, 23 | change_detection = { 24 | notify = false, 25 | enabled = true, 26 | }, 27 | install = { 28 | colorscheme = { "rose-pine" }, 29 | }, 30 | performance = { 31 | cache = { enabled = true }, 32 | rtp = { 33 | disabled_plugins = { 34 | "gzip", 35 | "netrwPlugin", 36 | "rplugin", 37 | "tarPlugin", 38 | "tohtml", 39 | "tutor", 40 | "zipPlugin", 41 | "netrw", 42 | "netrwPlugin", 43 | "netrwSettings", 44 | "netrwFileHandlers", 45 | }, 46 | }, 47 | }, 48 | ui = { 49 | border = "single", 50 | size = { 51 | width = 0.7, 52 | height = 0.7, 53 | }, 54 | }, 55 | }) 56 | -------------------------------------------------------------------------------- /.config/nvim/lua/core/options.lua: -------------------------------------------------------------------------------- 1 | vim.cmd("colorscheme rose-pine") 2 | 3 | vim.opt.guicursor = "a:block/,a:blinkoff200-blinkon400-Cursor/lCursor" 4 | vim.opt.cursorline = false 5 | 6 | vim.opt.clipboard = "unnamedplus" 7 | 8 | vim.opt.number = true 9 | vim.opt.relativenumber = true 10 | vim.opt.scrolloff = 8 11 | vim.opt.scroll = 10 12 | vim.opt.tabstop = 2 13 | vim.opt.softtabstop = 2 14 | vim.opt.shiftwidth = 2 15 | vim.opt.expandtab = true 16 | vim.opt.smartindent = true 17 | vim.opt.colorcolumn = "120" 18 | 19 | vim.opt.signcolumn = "yes" 20 | vim.opt.foldcolumn = "1" 21 | vim.opt.foldlevel = 99 22 | vim.opt.foldlevelstart = 99 23 | vim.opt.foldenable = true 24 | vim.wo.foldmethod = "expr" -- Set foldmethod to expr 25 | vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()" 26 | vim.opt.fillchars = { fold = " ", foldopen = "", foldsep = " ", foldclose = "" } 27 | vim.opt.diffopt = { 28 | "internal", 29 | "filler", 30 | "closeoff", 31 | "indent-heuristic", 32 | "linematch:60", 33 | "algorithm:histogram", 34 | "context:20", 35 | "iwhiteall", 36 | } 37 | 38 | vim.opt.swapfile = false 39 | vim.opt.backup = false 40 | 41 | vim.opt.wrap = false 42 | vim.opt.textwidth = 80 43 | vim.opt.formatexpr = "v:lua.require'conform'.formatexpr()" 44 | 45 | vim.opt.hlsearch = false 46 | vim.opt.incsearch = true 47 | vim.opt.ignorecase = true 48 | vim.opt.smartcase = true 49 | vim.opt.inccommand = "split" 50 | 51 | vim.opt.splitright = true 52 | vim.opt.conceallevel = 0 53 | 54 | vim.g.markdown_recommended_style = 0 -- see https://www.reddit.com/r/neovim/comments/z2lhyz/comment/ixjb7je 55 | vim.opt.updatetime = 300 56 | vim.opt.mouse = "a" 57 | vim.opt.wildignore:append({ "*/node_modules/*" }) 58 | vim.opt.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal,localoptions" 59 | -- vim.opt.showtabline = 0 60 | 61 | -- Grep format 62 | vim.opt.grepprg = "rg --vimgrep" 63 | vim.opt.grepformat = "%f:%l:%c:%m" 64 | 65 | -- Wrap long lines at a character in 'breakat' 66 | -- vim.opt.linebreak = true 67 | 68 | -- Don't break lines after a one-letter word 69 | -- vim.cmd('set fo-=1') 70 | 71 | -- Avoid comments to continue on new lines 72 | -- vim.opt.formatoptions = vim.o.formatoptions:gsub('cro', '') 73 | 74 | -- Keep indentantion on wrapped lines 75 | -- vim.opt.breakindent = true 76 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/bashls.lua: -------------------------------------------------------------------------------- 1 | return { 2 | settings = { 3 | bashIde = { 4 | globPattern = "*@(.sh|.inc|.bash|.command|.zsh)", 5 | shellcheckArguments = { 6 | "-e", 7 | "SC2086", -- Double quote to prevent globbing and word splitting 8 | -- '-e', 'SC2155', -- Declare and assign separately to avoid masking return values 9 | }, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/cssls.lua: -------------------------------------------------------------------------------- 1 | return { 2 | settings = { 3 | css = { 4 | lint = { unknownAtRules = "ignore" }, 5 | }, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/eslint.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("eslint") 2 | 3 | return { 4 | settings = { 5 | format = false, 6 | workingDirectories = { mode = "auto" }, -- helps eslint find the eslintrc when it's placed in a subfolder instead of the cwd root 7 | }, 8 | flags = os.getenv("DEBOUNCE_ESLINT") and { 9 | allow_incremental_sync = false, 10 | debounce_text_changes = 1000, 11 | } or nil, 12 | keys = { 13 | { 14 | "ef", 15 | ":LspEslintFixAll", 16 | desc = desc("Fix all"), 17 | }, 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/gopls.lua: -------------------------------------------------------------------------------- 1 | -- Organize go imports (https://github.com/harrisoncramer/nvim/blob/main/lua/lsp/servers/gopls.lua) 2 | -- local function goimports() 3 | -- local params = vim.lsp.util.make_range_params() 4 | -- params.context = {only = {'source.organizeImports'}} 5 | -- local result = vim.lsp.buf_request_sync(0, 'textDocument/codeAction', params) 6 | -- for cid, res in pairs(result or {}) do 7 | -- for _, r in pairs(res.result or {}) do 8 | -- if r.edit then 9 | -- local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or 'utf-16' 10 | -- vim.lsp.util.apply_workspace_edit(r.edit, enc) 11 | -- end 12 | -- end 13 | -- end 14 | -- vim.lsp.buf.format({async = false}) 15 | -- end 16 | -- 17 | -- vim.api.nvim_create_autocmd('BufWritePre', { 18 | -- pattern = '*.go', 19 | -- callback = function() 20 | -- goimports() 21 | -- end, 22 | -- desc = 'Run goimports on save in Golang files', 23 | -- }) 24 | 25 | -- https://github.com/golang/tools/blob/master/gopls/doc/settings.md 26 | return { 27 | settings = { 28 | gopls = { 29 | analyses = { 30 | fillstruct = false, 31 | }, 32 | -- staticcheck = true, -- https://github.com/golang/tools/blob/master/gopls/doc/settings.md#staticcheck-bool 33 | completeFunctionCalls = false, 34 | gofumpt = true, 35 | completeUnimported = true, 36 | }, 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/jsonls.lua: -------------------------------------------------------------------------------- 1 | return { 2 | settings = { 3 | json = { 4 | maxItemsComputed = 5000, 5 | colorDecorators = { enable = true }, 6 | format = { enable = true }, 7 | keepLines = { enable = true }, 8 | schemaDownload = { enable = true }, 9 | trace = { server = "off" }, 10 | -- schemas = require('schemastore').json.schemas(), 11 | validate = { enable = true }, 12 | }, 13 | }, 14 | -- Lazy-load schemas. 15 | on_new_config = function(config) 16 | config.settings.json.schemas = config.settings.json.schemas or {} 17 | vim.list_extend(config.settings.json.schemas, require("schemastore").json.schemas()) 18 | end, 19 | } 20 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/lua_ls.lua: -------------------------------------------------------------------------------- 1 | return { 2 | settings = { 3 | Lua = { 4 | hint = { enable = true }, 5 | workspace = { checkThirdParty = false }, 6 | telemetry = { enable = false }, 7 | completion = { callSnippet = "Replace" }, 8 | diagnostics = { globals = { "vim" } }, 9 | format = { 10 | enable = true, 11 | -- https://github.com/CppCXY/EmmyLuaCodeStyle/blob/master/docs/format_config_EN.md 12 | defaultConfig = { 13 | indent_size = 4, 14 | tab_width = 4, 15 | quote_style = "double", 16 | call_arg_parentheses = "keep", 17 | trailing_table_separator = "smart", 18 | space_around_table_field_list = "false", 19 | space_before_attribute = false, 20 | space_inside_square_brackets = false, 21 | align_call_args = false, 22 | align_function_params = false, 23 | align_continuous_assign_statement = false, 24 | align_continuous_rect_table_field = false, 25 | align_if_branch = false, 26 | align_array_table = false, 27 | }, 28 | }, 29 | }, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/vtsls.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("typescript") 2 | local settings = { 3 | updateImportsOnFileMove = { enabled = "always" }, 4 | format = { 5 | enable = false, 6 | insertSpaceAfterOpeningAndBeforeClosingEmptyBraces = false, 7 | insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces = false, 8 | }, 9 | preferences = { 10 | importModuleSpecifier = os.getenv("LSP_TS_IMPORT_MODULE_SPECIFIER_PROJECT_RELATIVE") and "project-relative" 11 | or "auto", 12 | }, 13 | inlayHints = { 14 | parameterNames = { enabled = "literals" }, 15 | parameterTypes = { enabled = true }, 16 | variableTypes = { enabled = true }, 17 | propertyDeclarationTypes = { enabled = true }, 18 | functionLikeReturnTypes = { enabled = true }, 19 | enumMemberValues = { enabled = true }, 20 | }, 21 | } 22 | 23 | return { 24 | settings = { 25 | complete_function_calls = true, 26 | vtsls = { 27 | enableMoveToFileCodeAction = true, 28 | autoUseWorkspaceTsdk = true, 29 | experimental = { 30 | completion = { 31 | -- https://github.com/yioneko/vtsls/blob/main/packages/service/configuration.schema.json#L1259-L1271 32 | enableServerSideFuzzyMatch = true, 33 | entriesLimit = 3000, 34 | }, 35 | }, 36 | }, 37 | javascript = settings, 38 | typescript = settings, 39 | }, 40 | keys = { 41 | { 42 | "to", 43 | function() 44 | vim.lsp.buf.code_action({ 45 | apply = true, 46 | context = { 47 | only = { "source.organizeImports" }, 48 | diagnostics = {}, 49 | }, 50 | }) 51 | end, 52 | desc = desc("Organize imports"), 53 | }, 54 | { 55 | "ta", 56 | function() 57 | vim.lsp.buf.code_action({ 58 | apply = true, 59 | context = { 60 | only = { "source.addMissingImports.ts" }, 61 | diagnostics = {}, 62 | }, 63 | }) 64 | end, 65 | desc = desc("Add missing imports"), 66 | }, 67 | { 68 | "tr", 69 | function() 70 | vim.lsp.buf.code_action({ 71 | apply = true, 72 | context = { 73 | only = { "source.removeUnused.ts" }, 74 | diagnostics = {}, 75 | }, 76 | }) 77 | end, 78 | desc = desc("Remove unused imports"), 79 | }, 80 | { 81 | "tf", 82 | function() 83 | vim.lsp.buf.code_action({ 84 | apply = true, 85 | context = { 86 | only = { "source.fixAll.ts" }, 87 | diagnostics = {}, 88 | }, 89 | }) 90 | end, 91 | desc = desc("Fix all"), 92 | }, 93 | { 94 | "tt", 95 | function() 96 | Utils.lsp.execute({ command = "typescript.selectTypeScriptVersion" }) 97 | end, 98 | desc = desc("Select typescript version"), 99 | }, 100 | }, 101 | } 102 | -------------------------------------------------------------------------------- /.config/nvim/lua/lsp/servers/yamlls.lua: -------------------------------------------------------------------------------- 1 | return { 2 | settings = { 3 | yaml = { 4 | schemaStore = { 5 | enable = false, -- Disable built-in schemaStore support, and use SchemaStore.nvim instead. 6 | url = "", -- Avoid TypeError: Cannot read properties of undefined (reading 'length') 7 | }, 8 | -- schemas = require('schemastore').yaml.schemas(), 9 | }, 10 | }, 11 | -- Lazy-load schemas. 12 | on_new_config = function(config) 13 | config.settings.yaml.schemas = config.settings.yaml.schemas or {} 14 | vim.list_extend(config.settings.yaml.schemas, require("schemastore").yaml.schemas()) 15 | end, 16 | } 17 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/ai.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "zbirenbaum/copilot.lua", 4 | cmd = "Copilot", 5 | opts = { 6 | filetypes = { 7 | markdown = true, 8 | sh = function() 9 | if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), "^%.env.*") then 10 | -- disable for .env files 11 | return false 12 | end 13 | return true 14 | end, 15 | }, 16 | suggestion = { 17 | enabled = true, 18 | auto_trigger = true, 19 | keymap = { 20 | accept = "", 21 | next = "", 22 | prev = "", 23 | dismiss = "", 24 | }, 25 | }, 26 | }, 27 | }, 28 | 29 | { 30 | "CopilotC-Nvim/CopilotChat.nvim", 31 | cmd = { "CopilotChat" }, 32 | dependencies = { "zbirenbaum/copilot.lua", "nvim-lua/plenary.nvim" }, 33 | opts = { debug = false }, 34 | }, 35 | 36 | { 37 | "yetone/avante.nvim", 38 | version = false, 39 | build = "make", 40 | dependencies = { 41 | "nvim-treesitter/nvim-treesitter", 42 | "stevearc/dressing.nvim", 43 | "nvim-lua/plenary.nvim", 44 | "MunifTanjim/nui.nvim", 45 | "ibhagwan/fzf-lua", 46 | "nvim-tree/nvim-web-devicons", 47 | "zbirenbaum/copilot.lua", 48 | }, 49 | keys = { 50 | { "ak", ":AvanteChat", desc = "Avante: Chat" }, 51 | }, 52 | opts = { 53 | provider = "gemini", 54 | windows = { 55 | postion = "right", 56 | width = 40, 57 | sidebar_header = { 58 | enabled = true, 59 | align = "left", 60 | rounded = false, 61 | }, 62 | }, 63 | file_selector = { 64 | provider = "fzf", 65 | }, 66 | }, 67 | }, 68 | } 69 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/auto-session.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'rmagatti/auto-session', 3 | cmd = {'SessionRestore', 'SessionSave'}, 4 | ---@module "auto-session" 5 | ---@type AutoSession.Config 6 | opts = { 7 | enabled = false, 8 | auto_restore = false, 9 | auto_create = false, 10 | suppressed_dirs = {'~/', '~/Dev/', '~/Downloads', '~/Documents', '~/Desktop/'}, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/cmp/blink.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "saghen/blink.cmp", 3 | version = "1.*", 4 | event = "InsertEnter", 5 | enabled = vim.g.blink_enabled, 6 | ---@module 'blink.cmp' 7 | ---@type blink.cmp.Config 8 | opts = { 9 | keymap = { 10 | preset = "enter", 11 | [""] = { "show", "show_documentation", "hide_documentation" }, 12 | [""] = { "scroll_documentation_up", "fallback" }, 13 | [""] = { "scroll_documentation_down", "fallback" }, 14 | }, 15 | cmdline = { 16 | enabled = true, 17 | completion = { 18 | menu = { auto_show = true }, 19 | list = { 20 | selection = { preselect = false }, 21 | }, 22 | }, 23 | keymap = { 24 | preset = "enter", 25 | [""] = { "show_and_insert" }, 26 | [""] = { "accept_and_enter", "fallback" }, 27 | [""] = { "select_next", "fallback" }, 28 | [""] = { "select_prev", "fallback" }, 29 | }, 30 | }, 31 | sources = { 32 | default = { "lsp", "path", "snippets", "buffer", "lazydev" }, 33 | providers = { 34 | lazydev = { 35 | name = "LazyDev", 36 | module = "lazydev.integrations.blink", 37 | score_offset = 100, -- show at a higher priority than lsp 38 | }, 39 | lsp = { 40 | fallbacks = { "buffer", "path" }, 41 | }, 42 | snippets = { 43 | name = "Snippets", 44 | module = "blink.cmp.sources.snippets", 45 | min_keyword_length = 3, 46 | opts = { 47 | friendly_snippets = false, 48 | search_paths = { vim.fn.stdpath("config") .. "/snippets/nvim" }, 49 | }, 50 | }, 51 | }, 52 | }, 53 | completion = { 54 | accept = { 55 | auto_brackets = { 56 | enabled = false, 57 | }, 58 | }, 59 | trigger = { 60 | show_on_accept_on_trigger_character = false, 61 | }, 62 | list = { 63 | selection = { 64 | preselect = false, 65 | auto_insert = false, 66 | }, 67 | }, 68 | menu = { 69 | draw = { 70 | treesitter = { "lsp" }, 71 | columns = { 72 | { "label", gap = 2 }, 73 | { "kind_icon", gap = 1, "kind" }, 74 | }, 75 | }, 76 | }, 77 | documentation = { 78 | auto_show = true, 79 | auto_show_delay_ms = 200, 80 | window = { 81 | border = "none", 82 | max_width = math.floor(vim.o.columns * 0.4), 83 | max_height = math.floor(vim.o.lines * 0.5), 84 | }, 85 | }, 86 | }, 87 | }, 88 | opts_extend = { "sources.default" }, 89 | } 90 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/cmp/nvim_cmp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "hrsh7th/nvim-cmp", 3 | event = "VeryLazy", 4 | enabled = not vim.g.blink_enabled, 5 | dependencies = { 6 | "hrsh7th/cmp-nvim-lsp", 7 | "hrsh7th/cmp-buffer", 8 | "hrsh7th/cmp-path", 9 | "hrsh7th/cmp-cmdline", 10 | "hrsh7th/cmp-emoji", 11 | {"onsails/lspkind-nvim", config = false}, 12 | { 13 | "garymjr/nvim-snippets", 14 | opts = {search_paths = {vim.fn.stdpath("config") .. "/snippets/nvim"}}, 15 | keys = { 16 | { 17 | "", 18 | function() 19 | if vim.snippet.active({direction = 1}) then 20 | vim.schedule(function() 21 | vim.snippet.jump(1) 22 | end) 23 | return 24 | end 25 | return "" 26 | end, 27 | expr = true, 28 | silent = true, 29 | mode = "i", 30 | }, 31 | { 32 | "", 33 | function() 34 | vim.schedule(function() 35 | vim.snippet.jump(1) 36 | end) 37 | end, 38 | expr = true, 39 | silent = true, 40 | mode = "s", 41 | }, 42 | { 43 | "", 44 | function() 45 | if vim.snippet.active({direction = -1}) then 46 | vim.schedule(function() 47 | vim.snippet.jump(-1) 48 | end) 49 | return 50 | end 51 | return "" 52 | end, 53 | expr = true, 54 | silent = true, 55 | mode = {"i", "s"}, 56 | }, 57 | }, 58 | }, 59 | }, 60 | config = function() 61 | local cmp = require("cmp") 62 | local lspkind = require("lspkind") 63 | local cmp_select_opts = {behavior = cmp.SelectBehavior.Select} 64 | 65 | cmp.setup({ 66 | snippet = { 67 | expand = function(args) 68 | vim.snippet.expand(args.body) 69 | end, 70 | }, 71 | preselect = cmp.PreselectMode.None, 72 | completion = { 73 | completeopt = "menu,menuone,noinsert,noselect", 74 | }, 75 | window = { 76 | documentation = { 77 | max_width = math.floor(vim.o.columns * 0.4), 78 | max_height = math.floor(vim.o.lines * 0.5), 79 | border = "none", 80 | }, 81 | }, 82 | mapping = { 83 | [""] = cmp.mapping.confirm({select = false, behavior = cmp.ConfirmBehavior.Insert}), 84 | [""] = cmp.mapping.abort(), 85 | [""] = cmp.mapping.scroll_docs(-4), 86 | [""] = cmp.mapping.scroll_docs(4), 87 | [""] = cmp.mapping.select_prev_item(cmp_select_opts), 88 | [""] = cmp.mapping.select_next_item(cmp_select_opts), 89 | [""] = cmp.mapping.select_prev_item(cmp_select_opts), 90 | [""] = cmp.mapping.select_next_item(cmp_select_opts), 91 | [""] = cmp.mapping.complete({reason = "auto"}), 92 | }, 93 | sources = cmp.config.sources({ 94 | {name = "lazydev", group_index = 0}, 95 | { 96 | name = "snippets", 97 | keyword_length = 3, 98 | entry_filter = function() 99 | local ctx = require("cmp.config.context") 100 | local in_string = ctx.in_syntax_group("String") or ctx.in_treesitter_capture("string") 101 | local in_comment = ctx.in_syntax_group("Comment") or ctx.in_treesitter_capture("comment") 102 | return not in_string and not in_comment 103 | end, 104 | }, 105 | { 106 | name = "nvim_lsp", 107 | keyword_length = 2, 108 | max_item_count = 50, 109 | entry_filter = function(entry, ctx) 110 | return require("cmp.types").lsp.CompletionItemKind[entry:get_kind()] ~= "Text" 111 | end, 112 | }, 113 | }, { 114 | {name = "buffer", keyword_length = 3, max_item_count = 20}, 115 | {name = "path"}, 116 | {name = "emoji"}, 117 | }), 118 | formatting = { 119 | format = lspkind.cmp_format({ 120 | mode = "symbol_text", 121 | }), 122 | fields = {"abbr", "kind"}, -- Remove 'menu' to avoid truncation 123 | }, 124 | }) 125 | 126 | cmp.setup.cmdline({"/", "?"}, { 127 | mapping = cmp.mapping.preset.cmdline(), 128 | sources = { 129 | {name = "buffer"}, 130 | }, 131 | }) 132 | 133 | cmp.setup.cmdline(":", { 134 | mapping = cmp.mapping.preset.cmdline(), 135 | sources = cmp.config.sources({ 136 | {name = "path"}, 137 | }, { 138 | {name = "cmdline"}, 139 | }), 140 | }) 141 | end, 142 | } 143 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/colorscheme/gruvbox.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "sainnhe/gruvbox-material", 3 | lazy = true, 4 | config = function() 5 | vim.g.gruvbox_material_better_performance = 1 6 | vim.g.gruvbox_material_foreground = "material" 7 | vim.g.gruvbox_material_background = "soft" 8 | vim.g.gruvbox_material_ui_contrast = "low" 9 | vim.g.gruvbox_material_float_style = "dim" 10 | vim.g.gruvbox_material_enable_italic = 0 11 | vim.g.gruvbox_material_disable_italic_comment = 1 12 | vim.g.gruvbox_material_cursor = "red" 13 | vim.g.gruvbox_material_disable_terminal_colors = 1 14 | 15 | local function set_highlights() 16 | local highlights_groups = { 17 | Normal = {bg = "#000000"}, 18 | Cursor = {bg = "#ffffff"}, 19 | } 20 | 21 | for group, styles in pairs(highlights_groups) do 22 | vim.api.nvim_set_hl(0, group, styles) 23 | end 24 | end 25 | 26 | vim.api.nvim_create_autocmd("ColorScheme", { 27 | callback = function() 28 | if vim.g.colors_name == "gruvbox-material" then 29 | set_highlights() 30 | end 31 | end, 32 | }) 33 | end, 34 | } 35 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/colorscheme/rosepine.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "rose-pine/neovim", 3 | name = "rose-pine", 4 | priority = 1000, 5 | opts = { 6 | dark_variant = "moon", 7 | styles = {italic = false}, 8 | palette = { 9 | dawn = { 10 | no_bg = "#faf4ed", 11 | cursor_bg = "#000000", 12 | cursor_fg = "#ffffff", 13 | }, 14 | moon = { 15 | gold = "#f6d5a7", 16 | foam = "#a1d1da", 17 | iris = "#d9c7ef", 18 | rose = "#ebbcba", 19 | pine = "#437e91", 20 | no_bg = "#000000", 21 | cursor_bg = "#ffffff", 22 | cursor_fg = "#000000", 23 | }, 24 | }, 25 | highlight_groups = { 26 | Normal = {bg = "no_bg"}, 27 | Cursor = {bg = "cursor_bg", fg = "cursor_fg"}, 28 | Directory = {fg = "foam", bold = false}, 29 | StatusLine = {bg = "surface", fg = "subtle"}, 30 | StatusLineTerm = {link = "StatusLine"}, 31 | StatusLineNC = {link = "StatusLine"}, 32 | --- gitsigns 33 | StatusLineGitSignsAdd = {bg = "surface", fg = "pine"}, 34 | StatusLineGitSignsChange = {bg = "surface", fg = "gold"}, 35 | StatusLineGitSignsDelete = {bg = "surface", fg = "rose"}, 36 | --- diagnostics 37 | StatusLineDiagnosticSignError = {bg = "surface", fg = "love"}, 38 | StatusLineDiagnosticSignWarn = {bg = "surface", fg = "gold"}, 39 | StatusLineDiagnosticSignInfo = {bg = "surface", fg = "foam"}, 40 | StatusLineDiagnosticSignHint = {bg = "surface", fg = "iris"}, 41 | StatusLineDiagnosticSignOk = {bg = "surface", fg = "pine"}, 42 | }, 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/colorscheme/zenbones.lua: -------------------------------------------------------------------------------- 1 | ---@class ColorSet 2 | ---@field bg string 3 | ---@field bg1 string 4 | ---@field bg_stark string 5 | ---@field fg string 6 | ---@field fg1 string 7 | ---@field blossom string 8 | ---@field blossom1 string 9 | ---@field leaf string 10 | ---@field leaf1 string 11 | ---@field rose string 12 | ---@field rose1 string 13 | ---@field sky string 14 | ---@field sky1 string 15 | ---@field water string 16 | ---@field water1 string 17 | ---@field wood string 18 | ---@field wood1 string 19 | 20 | ---@class LightColorSet : ColorSet 21 | ---@field bg_bright string 22 | 23 | ---@class DarkColorSet : ColorSet 24 | ---@field bg_warm string 25 | 26 | ---@class Palette 27 | ---@field dark DarkColorSet 28 | ---@field light LightColorSet 29 | 30 | return { 31 | "mcchrish/zenbones.nvim", 32 | dependencies = {"rktjmp/lush.nvim"}, 33 | lazy = true, 34 | config = function() 35 | vim.g.zenbones_italic_comments = false 36 | vim.g.rosebones_italic_comments = false 37 | 38 | vim.api.nvim_create_autocmd("ColorScheme", { 39 | group = vim.api.nvim_create_augroup("Customize Zenbones", {}), 40 | callback = function() 41 | local active_colorscheme = vim.g.colors_name 42 | 43 | if (not string.find(active_colorscheme, "bones")) then 44 | return 45 | end 46 | 47 | local theme = require(active_colorscheme) 48 | ---@type Palette 49 | local palette = require(active_colorscheme .. ".palette") 50 | local lush = require("lush") 51 | local bg = vim.o.background 52 | local statusline_bg = bg == "dark" and palette.dark.bg_warm.li(10) or palette.light.bg1 53 | 54 | ---@diagnostic disable: undefined-global 55 | local specs = lush.parse(function() 56 | return { 57 | -- Normal({theme.Normal, bg = bg == 'dark' and '#181616' or palette[bg].bg}), 58 | Normal({theme.Normal, bg = bg == "dark" and "#000000" or palette[bg].bg}), 59 | -- NormalNC({theme.NormalNC, bg = bg == 'dark' and '#2d2929' or palette[bg].bg}), 60 | -- NormalNC({theme.NormalNC, bg = bg == 'dark' and '#1f1d1d' or palette[bg].bg.da(10)}), 61 | NormalNC({theme.NormalNC, bg = bg == "dark" and "#262323" or palette[bg].bg.da(10)}), 62 | TermCursor({cterm = "reverse", gui = "reverse"}), 63 | Cursor({theme.Cursor, bg = bg == "dark" and "#ffffff" or "#000000"}), 64 | FloatBorder({theme.FloatBorder, bg = theme.NormalFloat.bg}), 65 | FloatTitle({theme.FloatTitle, bg = theme.NormalFloat.bg}), 66 | Special({theme.Special, gui = "normal"}), 67 | Statement({theme.Statement, gui = "normal"}), 68 | Directory({theme.Directory, gui = "normal"}), 69 | Boolean({ 70 | theme.Boolean, 71 | gui = "bold", 72 | fg = active_colorscheme == "rosebones" and palette[bg].rose or theme.Boolean.fg, 73 | }), 74 | SnippetTabStop({theme.SnippetTabStop, bg = theme.Normal.bg}), 75 | Function({ 76 | theme.Function, 77 | fg = bg == "dark" and palette.dark.bg.li(58) or 78 | palette.light.bg.sa(20).da(60), 79 | }), 80 | TodoBgTODO({theme.TodoBgTODO, bg = palette[bg].water, fg = palette[bg].fg}), 81 | TodoFgTODO({theme.TodoFgTODO, fg = palette[bg].water}), 82 | -- Statusline 83 | StatusLine({theme.StatusLine, bg = statusline_bg}), 84 | --- gitsigns 85 | StatusLineGitSignsAdd({bg = statusline_bg, fg = theme.GitSignsAdd.fg}), 86 | StatusLineGitSignsChange({bg = statusline_bg, fg = theme.GitSignsChange.fg}), 87 | StatusLineGitSignsDelete({bg = statusline_bg, fg = theme.GitSignsDelete.fg}), 88 | --- diagnostics 89 | StatusLineDiagnosticSignError({bg = statusline_bg, fg = theme.DiagnosticError.fg}), 90 | StatusLineDiagnosticSignWarn({bg = statusline_bg, fg = theme.DiagnosticWarn.fg}), 91 | StatusLineDiagnosticSignInfo({bg = statusline_bg, fg = theme.DiagnosticInfo.fg}), 92 | StatusLineDiagnosticSignHint({bg = statusline_bg, fg = theme.DiagnosticHint.fg}), 93 | StatusLineDiagnosticSignOk({bg = statusline_bg, fg = theme.DiagnosticOk.fg}), 94 | } 95 | end) 96 | 97 | lush.apply(lush.compile(specs)) 98 | 99 | if (active_colorscheme == "rosebones") then 100 | vim.api.nvim_set_hl(0, "@tag.tsx", {link = "Function"}) 101 | vim.api.nvim_set_hl(0, "@tag.builtin.tsx", {link = "Function"}) 102 | end 103 | end, 104 | }) 105 | end, 106 | } 107 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/comment.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "numToStr/Comment.nvim", 3 | event = "VeryLazy", 4 | dependencies = {"JoosepAlviste/nvim-ts-context-commentstring"}, 5 | init = function() 6 | vim.g.skip_ts_context_commentstring_module = true 7 | end, 8 | config = function() 9 | local comment = require("Comment") 10 | local comment_string = require("ts_context_commentstring") 11 | comment.setup({ 12 | pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(), 13 | }) 14 | comment_string.setup() 15 | end, 16 | } 17 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/conform.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "stevearc/conform.nvim", 3 | event = { "BufWritePre" }, 4 | cmd = { "ConformInfo" }, 5 | ---@module "conform" 6 | ---@type conform.setupOpts 7 | opts = { 8 | quiet = true, 9 | formatters_by_ft = { 10 | typescript = { "prettier" }, 11 | typescriptreact = { "prettier" }, 12 | javascript = { "prettier" }, 13 | javascriptreact = { "prettier" }, 14 | html = { "prettier" }, 15 | css = { "prettier" }, 16 | scss = { "prettier" }, 17 | lua = { "stylua", lsp_format = "first" }, 18 | markdown = { "prettier" }, 19 | yaml = { "prettier" }, 20 | graphql = { "prettier" }, 21 | vue = { "prettier" }, 22 | angular = { "prettier" }, 23 | less = { "prettier" }, 24 | flow = { "prettier" }, 25 | sh = { "beautysh" }, 26 | bash = { "beautysh" }, 27 | zsh = { "beautysh" }, 28 | http = { "kulala-fmt" }, 29 | python = { "black" }, 30 | go = { "gofmt" }, 31 | ["_"] = { "trim_whitespace" }, 32 | }, 33 | format_on_save = function(bufnr) 34 | -- Disable autoformat for files in a certain path 35 | local bufname = vim.api.nvim_buf_get_name(bufnr) 36 | if bufname:match("/node_modules/") then 37 | return 38 | end 39 | 40 | ---@type conform.FormatOpts 41 | return { timeout_ms = 500, lsp_format = "fallback" } 42 | end, 43 | log_level = vim.log.levels.DEBUG, 44 | formatters = { 45 | prettier = { 46 | prepend_args = function() 47 | return { 48 | "--no-semi", 49 | "--single-quote", 50 | "--no-bracket-spacing", 51 | "--print-width", 52 | "80", 53 | "--config-precedence", 54 | "prefer-file", 55 | } 56 | end, 57 | }, 58 | beautysh = { 59 | prepend_args = function() 60 | return { "--indent-size", "4", "--force-function-style", "fnpar" } 61 | end, 62 | }, 63 | }, 64 | }, 65 | } 66 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/fzf.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("fzf") 2 | 3 | local grep_opts = { 4 | "rg", 5 | "--vimgrep", 6 | "--hidden", 7 | "--follow", 8 | "--glob", 9 | '"!**/.git/*"', 10 | "--column", 11 | "--line-number", 12 | "--no-heading", 13 | "--color=always", 14 | "--smart-case", 15 | "--max-columns=4096", 16 | "-e", 17 | } 18 | 19 | return { 20 | "ibhagwan/fzf-lua", 21 | dependencies = { "nvim-tree/nvim-web-devicons" }, 22 | cmd = "FzfLua", 23 | event = "VeryLazy", 24 | keys = function() 25 | local fzf = require("fzf-lua") 26 | return { 27 | { "fo", fzf.buffers, desc = desc("Find opened buffers in current neovim instance") }, 28 | { "fs", fzf.lgrep_curbuf, desc = desc("Fuzzily search in current buffer") }, 29 | { "ff", fzf.files, desc = desc("Search files") }, 30 | { "fg", fzf.grep, desc = desc("Search by grep") }, 31 | { "fl", fzf.live_grep, desc = desc("Search by live grep") }, 32 | { "fk", fzf.keymaps, desc = desc("Keymaps") }, 33 | { "fh", fzf.search_history, desc = desc("Get list of searches") }, 34 | { "fb", fzf.resume, desc = desc("Resume search") }, 35 | { "fd", fzf.lsp_document_diagnostics, desc = desc("Get file diagnostics") }, 36 | { "fr", fzf.lsp_references, desc = desc("Goto References") }, 37 | { "fy", fzf.lsp_document_symbols, desc = desc("Document Symbols") }, 38 | { "fw", fzf.lsp_live_workspace_symbols, desc = desc("Workspace Symbols") }, 39 | { "fG", Utils.fzf.folder_grep, desc = desc("Grep on selected folder") }, 40 | } 41 | end, 42 | opts = function() 43 | local actions = require("fzf-lua.actions") 44 | local img_previewer ---@type string[]? 45 | for _, v in ipairs({ 46 | { cmd = "ueberzug", args = {} }, 47 | { cmd = "chafa", args = { "{file}", "--format=symbols" } }, 48 | { cmd = "viu", args = { "-b" } }, 49 | }) do 50 | if vim.fn.executable(v.cmd) == 1 then 51 | img_previewer = vim.list_extend({ v.cmd }, v.args) 52 | break 53 | end 54 | end 55 | 56 | require("fzf-lua").register_ui_select(function(_, items) 57 | local min_h, max_h = 0.35, 0.70 58 | local h = (#items + 4) / vim.o.lines 59 | if h < min_h then 60 | h = min_h 61 | elseif h > max_h then 62 | h = max_h 63 | end 64 | return { 65 | winopts = { height = h, width = 0.60, row = 0.40 }, 66 | } 67 | end) 68 | 69 | return { 70 | defaults = { 71 | -- formatter = 'path.filename_first', 72 | formatter = "path.dirname_first", 73 | }, 74 | previewers = { 75 | builtin = { 76 | extensions = { 77 | ["png"] = img_previewer, 78 | ["jpg"] = img_previewer, 79 | ["jpeg"] = img_previewer, 80 | ["gif"] = img_previewer, 81 | ["webp"] = img_previewer, 82 | }, 83 | ueberzug_scaler = "fit_contain", 84 | }, 85 | }, 86 | winopts = { 87 | width = 0.60, 88 | height = 0.9, 89 | backdrop = 100, 90 | preview = { 91 | layout = "vertical", 92 | vertical = "down:45%", 93 | }, 94 | }, 95 | fzf_opts = { 96 | ["--tiebreak"] = "begin", -- Proper sort of results (see https://github.com/ibhagwan/fzf-lua/issues/411#issuecomment-1125527931) 97 | ["--info"] = "default", 98 | ["--layout"] = "default", 99 | ["--margin"] = "0,1", 100 | }, 101 | keymap = { 102 | builtin = { 103 | true, 104 | [""] = "preview-page-down", 105 | [""] = "preview-page-up", 106 | }, 107 | fzf = { 108 | ["ctrl-d"] = "preview-page-down", 109 | ["ctrl-u"] = "preview-page-up", 110 | ["ctrl-q"] = "select-all+accept", 111 | }, 112 | }, 113 | files = { 114 | cwd_prompt = false, 115 | prompt = Utils.icons.misc.file .. " ", 116 | git_icons = true, 117 | hidden = true, 118 | follow = true, 119 | -- rg_opts = [[--color=never --files --hidden --follow -g "!.git"]], 120 | -- fd_opts = [[--color=never --type f --hidden --follow --exclude .git]], 121 | }, 122 | grep = { 123 | cwd_prompt = false, 124 | prompt = Utils.icons.misc.search .. " ", 125 | input_prompt = "Grep For ❯ ", 126 | cmd = table.concat(grep_opts, " "), 127 | hidden = true, 128 | follow = true, 129 | -- actions = { 130 | -- ['ctrl-q'] = { 131 | -- fn = actions.file_edit_or_qf, prefix = 'select-all+' 132 | -- }, 133 | -- }, 134 | }, 135 | buffers = { 136 | actions = { 137 | ["ctrl-x"] = { actions.buf_del, actions.resume }, 138 | }, 139 | }, 140 | } 141 | end, 142 | } 143 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/git.lua: -------------------------------------------------------------------------------- 1 | local octo_desc = Utils.plugin_keymap_desc("octo") 2 | 3 | return { 4 | { "tpope/vim-fugitive", cmd = "Git" }, 5 | 6 | { 7 | "FabijanZulj/blame.nvim", 8 | cmd = "BlameToggle", 9 | opts = { 10 | mappings = { 11 | commit_info = "K", 12 | }, 13 | }, 14 | }, 15 | 16 | { 17 | "kdheepak/lazygit.nvim", 18 | cmd = { "LazyGit", "LazyGitConfig", "LazyGitCurrentFile", "LazyGitFilter", "LazyGitFilterCurrentFile" }, 19 | dependencies = { "nvim-lua/plenary.nvim" }, 20 | keys = { 21 | { "gg", "LazyGit", desc = "LazyGit: Open" }, 22 | }, 23 | }, 24 | 25 | { 26 | "lewis6991/gitsigns.nvim", 27 | event = "VeryLazy", 28 | opts = function() 29 | local desc = Utils.plugin_keymap_desc("gitsigns") 30 | 31 | return { 32 | signs = { 33 | add = { text = Utils.icons.git.added }, 34 | change = { text = Utils.icons.git.changed }, 35 | delete = { text = Utils.icons.git.deleted }, 36 | topdelete = { text = Utils.icons.git.deleted }, 37 | changedelete = { text = Utils.icons.git.changed }, 38 | untracked = { text = Utils.icons.git.added }, 39 | }, 40 | current_line_blame = true, 41 | current_line_blame_opts = { delay = 500 }, 42 | preview_config = { 43 | border = "single", 44 | title = "Preview changes", 45 | title_pos = "center", 46 | }, 47 | on_attach = function(bufnr) 48 | local gs = package.loaded.gitsigns 49 | 50 | local function map(mode, l, r, opts) 51 | opts = opts or {} 52 | opts.buffer = bufnr 53 | vim.keymap.set(mode, l, r, opts) 54 | end 55 | 56 | -- Navigation 57 | map("n", "]c", function() 58 | if vim.wo.diff then 59 | return "]c" 60 | end 61 | vim.schedule(function() 62 | gs.next_hunk() 63 | vim.cmd("normal! zz") 64 | end) 65 | return "" 66 | end, { expr = true, desc = desc("Next hunk") }) 67 | 68 | map("n", "[c", function() 69 | if vim.wo.diff then 70 | return "[c" 71 | end 72 | vim.schedule(function() 73 | gs.prev_hunk() 74 | vim.cmd("normal! zz") 75 | end) 76 | return "" 77 | end, { expr = true, desc = desc("Previous hunk") }) 78 | 79 | -- Actions 80 | map("n", "gs", gs.stage_hunk, { desc = desc("Stage hunk") }) 81 | map("n", "gr", gs.reset_hunk, { desc = desc("Reset hunk") }) 82 | map("v", "gs", function() 83 | gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) 84 | end, { desc = desc("Stage hunk") }) 85 | map("v", "gr", function() 86 | gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) 87 | end, { desc = desc("Reset hunk") }) 88 | -- map('n', 'hS', gs.stage_buffer, {desc = desc('Stage buffer')}) 89 | -- map('n', 'hR', gs.reset_buffer, {desc = desc('Reset buffer')}) 90 | map("n", "gp", gs.preview_hunk, { desc = desc("Preview hunk") }) 91 | map("n", "gb", function() 92 | gs.blame_line({ full = true }) 93 | end, { desc = desc("Blame line") }) 94 | -- map('n', 'tb', gs.toggle_current_line_blame, {desc = desc('Toggle current line blame')}) 95 | -- map('n', 'hd', gs.diffthis, {desc = desc('Diff this')}) 96 | -- map('n', 'hD', function() gs.diffthis('~') end, {desc = desc('Diff this')}) 97 | 98 | -- Text object 99 | map({ "o", "x" }, "ih", ":Gitsigns select_hunk") 100 | end, 101 | } 102 | end, 103 | }, 104 | 105 | { 106 | "pwntester/octo.nvim", 107 | cmd = "Octo", 108 | event = { { event = "BufReadCmd", pattern = "octo://*" } }, 109 | opts = { 110 | enable_builtin = true, 111 | default_to_projects_v2 = true, 112 | default_merge_method = "squash", 113 | picker = "fzf-lua", 114 | picker_config = { 115 | use_emojis = true, 116 | }, 117 | }, 118 | keys = { 119 | { "oi", "Octo issue list", desc = octo_desc("List Issues") }, 120 | { "oI", "Octo issue search", desc = octo_desc("Search Issues") }, 121 | { "op", "Octo pr list", desc = octo_desc("List PRs") }, 122 | { "oP", "Octo pr search", desc = octo_desc("Search PRs") }, 123 | { "or", "Octo repo list", desc = octo_desc("List Repos") }, 124 | { "oS", "Octo search", desc = octo_desc("Search") }, 125 | 126 | { "a", "", desc = octo_desc("+assignee"), ft = "octo" }, 127 | { "c", "", desc = octo_desc("+comment/code"), ft = "octo" }, 128 | { "l", "", desc = octo_desc("+label"), ft = "octo" }, 129 | { "i", "", desc = octo_desc("+issue"), ft = "octo" }, 130 | { "r", "", desc = octo_desc("+react"), ft = "octo" }, 131 | { "p", "", desc = octo_desc("+pr"), ft = "octo" }, 132 | { "pr", "", desc = octo_desc("+rebase"), ft = "octo" }, 133 | { "ps", "", desc = octo_desc("+squash"), ft = "octo" }, 134 | { "v", "", desc = octo_desc("+review"), ft = "octo" }, 135 | { "g", "", desc = octo_desc("+goto_issue"), ft = "octo" }, 136 | { "@", "@", mode = "i", ft = "octo", silent = true }, 137 | { "#", "#", mode = "i", ft = "octo", silent = true }, 138 | }, 139 | }, 140 | 141 | { 142 | "sindrets/diffview.nvim", 143 | cmd = { "DiffviewOpen", "DiffviewFileHistory" }, 144 | opts = function() 145 | local diffview_config = require("diffview.config") 146 | return { 147 | keymaps = { 148 | file_panel = { 149 | [""] = false, 150 | [""] = false, 151 | { 152 | "n", 153 | "", 154 | diffview_config.actions.scroll_view(0.25), 155 | { desc = "Diffview: Scroll the view down" }, 156 | }, 157 | { 158 | "n", 159 | "", 160 | diffview_config.actions.scroll_view(-0.25), 161 | { desc = "Diffview: Scroll the view up" }, 162 | }, 163 | }, 164 | }, 165 | } 166 | end, 167 | }, 168 | } 169 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/harpoon.lua: -------------------------------------------------------------------------------- 1 | -- A lot here was taken from https://github.com/mike-jl/harpoonEx 2 | local desc = Utils.plugin_keymap_desc("harpoon") 3 | 4 | local globalIndex = {} 5 | 6 | local function get_full_path(path) 7 | local bufPath = vim.uv.fs_realpath(path) 8 | if not bufPath then 9 | if string.sub(path, 1, 1) == "/" then 10 | bufPath = path 11 | else 12 | bufPath = vim.uv.fs_realpath(".") .. "/" .. path 13 | end 14 | end 15 | return bufPath 16 | end 17 | 18 | local function sync_index(list, index) 19 | if index then 20 | globalIndex[list.name] = index 21 | return 22 | end 23 | 24 | if globalIndex[list.name] > list._length then 25 | globalIndex[list.name] = list._length 26 | return 27 | end 28 | local bufPath = get_full_path(vim.api.nvim_buf_get_name(0)) 29 | -- find corresponding harpoon item 30 | for i = 1, list._length do 31 | local item = list.items[i] 32 | if item ~= nil and item.value ~= nil then 33 | local harpoonPath = get_full_path(item.value) 34 | if bufPath == harpoonPath then 35 | globalIndex[list.name] = i 36 | return 37 | end 38 | end 39 | end 40 | end 41 | 42 | local function cur_buf_is_harpoon(list) 43 | local current = list.items[globalIndex[list.name]] 44 | if not current then 45 | return true 46 | end 47 | 48 | local bufnr = vim.fn.bufnr(get_full_path(current.value)) 49 | 50 | return bufnr == vim.fn.bufnr() 51 | end 52 | 53 | local function next_harpoon(list, prev) 54 | if not cur_buf_is_harpoon(list) then 55 | list:select(globalIndex[list.name]) 56 | return 57 | end 58 | local i = globalIndex[list.name] or 0 59 | local j = 1 60 | while true do 61 | if prev then 62 | i = i - 1 63 | else 64 | i = i + 1 65 | end 66 | if list.items[i] then 67 | list:select(i) 68 | return 69 | end 70 | j = j + 1 71 | if j > list._length then 72 | return 73 | end 74 | end 75 | end 76 | 77 | local keys = { 78 | open_menu = "hh", 79 | add_to_list = "ha", 80 | sel_f1 = "h1", 81 | sel_f2 = "h2", 82 | sel_f3 = "h3", 83 | sel_f4 = "h4", 84 | sel_f5 = "h5", 85 | sel_f6 = "h6", 86 | sel_f7 = "h7", 87 | sel_f8 = "h8", 88 | sel_f9 = "h9", 89 | prev_file = "", 90 | next_file = "", 91 | } 92 | 93 | return { 94 | "ThePrimeagen/harpoon", 95 | branch = "harpoon2", 96 | dependencies = {"nvim-lua/plenary.nvim"}, 97 | keys = { 98 | {keys.open_menu, desc = desc("Open menu")}, 99 | {keys.add_to_list, desc = desc("Add to list")}, 100 | {keys.prev_file, desc = desc("Previous file")}, 101 | {keys.next_file, desc = desc("Next file")}, 102 | {keys.sel_f1, desc = desc("Select file 1")}, 103 | {keys.sel_f2, desc = desc("Select file 2")}, 104 | {keys.sel_f3, desc = desc("Select file 3")}, 105 | {keys.sel_f4, desc = desc("Select file 4")}, 106 | {keys.sel_f5, desc = desc("Select file 5")}, 107 | {keys.sel_f6, desc = desc("Select file 6")}, 108 | {keys.sel_f7, desc = desc("Select file 7")}, 109 | {keys.sel_f8, desc = desc("Select file 8")}, 110 | {keys.sel_f9, desc = desc("Select file 9")}, 111 | }, 112 | config = function() 113 | local harpoon = require("harpoon") 114 | -- local extensions = require('harpoon.extensions') 115 | ---@type HarpoonToggleOptions 116 | local menu_opts = {border = "single"} 117 | 118 | harpoon:setup({settings = {save_on_toggle = true, sync_on_ui_close = true}}) 119 | -- harpoon:extend(extensions.builtins.command_on_nav('UfoEnableFold')) 120 | harpoon:extend({ 121 | SELECT = function(args) 122 | sync_index(args.list, args.idx) 123 | end, 124 | ADD = function(args) 125 | sync_index(args.list, args.idx) 126 | end, 127 | REMOVE = function(args) 128 | sync_index(args.list) 129 | end, 130 | UI_CREATE = function(cx) 131 | vim.keymap.set( 132 | "n", 133 | "", 134 | function() harpoon.ui:select_menu_item({vsplit = true}) end, 135 | {desc = desc("Open as vertical split"), buffer = cx.bufnr} 136 | ) 137 | vim.keymap.set( 138 | "n", 139 | "", 140 | function() harpoon.ui:select_menu_item({split = true}) end, 141 | {desc = desc("Open as split"), buffer = cx.bufnr} 142 | ) 143 | vim.keymap.set( 144 | "n", 145 | "", 146 | function() harpoon.ui:select_menu_item({tabedit = true}) end, 147 | {desc = desc("Open in new tab"), buffer = cx.bufnr} 148 | ) 149 | 150 | for line_number, file in pairs(cx.contents) do 151 | if string.find(cx.current_file, file, 1, true) then 152 | -- highlight the harpoon menu line that corresponds to the current buffer 153 | vim.api.nvim_buf_add_highlight( 154 | cx.bufnr, 155 | -1, 156 | "CursorLineNr", 157 | line_number - 1, 158 | 0, 159 | -1 160 | ) 161 | -- set the position of the cursor in the harpoon menu to the start of the current buffer line 162 | vim.api.nvim_win_set_cursor(cx.win_id, {line_number, 0}) 163 | end 164 | end 165 | end, 166 | }) 167 | 168 | vim.keymap.set("n", keys.open_menu, function() harpoon.ui:toggle_quick_menu(harpoon:list(), menu_opts) end, 169 | {desc = desc("Open menu")}) 170 | vim.keymap.set("n", keys.add_to_list, function() harpoon:list():add() end, {desc = desc("Add to list")}) 171 | vim.keymap.set("n", keys.prev_file, function() next_harpoon(harpoon:list(), true) end, 172 | {desc = desc("Previous file")}) 173 | vim.keymap.set("n", keys.next_file, function() next_harpoon(harpoon:list(), false) end, 174 | {desc = desc("Next file")}) 175 | vim.keymap.set("n", keys.sel_f1, function() harpoon:list():select(1) end, {desc = desc("Select file 1")}) 176 | vim.keymap.set("n", keys.sel_f2, function() harpoon:list():select(2) end, {desc = desc("Select file 2")}) 177 | vim.keymap.set("n", keys.sel_f3, function() harpoon:list():select(3) end, {desc = desc("Select file 3")}) 178 | vim.keymap.set("n", keys.sel_f4, function() harpoon:list():select(4) end, {desc = desc("Select file 4")}) 179 | vim.keymap.set("n", keys.sel_f5, function() harpoon:list():select(5) end, {desc = desc("Select file 5")}) 180 | vim.keymap.set("n", keys.sel_f6, function() harpoon:list():select(6) end, {desc = desc("Select file 6")}) 181 | vim.keymap.set("n", keys.sel_f7, function() harpoon:list():select(7) end, {desc = desc("Select file 7")}) 182 | vim.keymap.set("n", keys.sel_f8, function() harpoon:list():select(8) end, {desc = desc("Select file 8")}) 183 | vim.keymap.set("n", keys.sel_f9, function() harpoon:list():select(9) end, {desc = desc("Select file 9")}) -- If I ever have more than 9 tabs open, time to rethink my life choices 184 | end, 185 | } 186 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/lazydev.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/lazydev.nvim", 3 | ft = "lua", 4 | cmd = "LazyDev", 5 | dependencies = { 6 | -- {'gonstoll/wezterm-types', lazy = true}, 7 | {"Bilal2453/luvit-meta", lazy = true}, 8 | }, 9 | opts = { 10 | library = { 11 | {path = "luvit-meta/library", words = {"vim%.uv"}}, 12 | {path = "snacks.nvim", words = {"Snacks"}}, 13 | {"nvim-dap-ui"}, 14 | -- {path = 'wezterm-types', mods = {'wezterm'}}, 15 | }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/lsp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "neovim/nvim-lspconfig" }, 3 | 4 | { 5 | "b0o/SchemaStore.nvim", 6 | -- Loaded by jsonls when needed. 7 | version = false, 8 | lazy = true, 9 | }, 10 | 11 | { 12 | "mason-org/mason.nvim", 13 | build = ":MasonUpdate", 14 | event = "VeryLazy", 15 | opts = { 16 | ui = { border = "single" }, 17 | ensure_installed = { 18 | "js-debug-adapter", 19 | "black", 20 | "gofumpt", 21 | "stylua", 22 | }, 23 | }, 24 | config = function(_, opts) 25 | require("mason").setup(opts) 26 | local mr = require("mason-registry") 27 | mr:on("package:install:success", function() 28 | vim.defer_fn(function() 29 | -- trigger FileType event to possibly load this newly installed LSP server 30 | require("lazy.core.handler.event").trigger({ 31 | event = "FileType", 32 | buf = vim.api.nvim_get_current_buf(), 33 | }) 34 | end, 100) 35 | end) 36 | 37 | mr.refresh(function() 38 | for _, tool in ipairs(opts.ensure_installed) do 39 | local p = mr.get_package(tool) 40 | if not p:is_installed() then 41 | p:install() 42 | end 43 | end 44 | end) 45 | end, 46 | }, 47 | 48 | { 49 | "mason-org/mason-lspconfig.nvim", 50 | event = "VeryLazy", 51 | opts = { 52 | ensure_installed = { 53 | "tailwindcss", 54 | "cssls", 55 | "lua_ls", 56 | "eslint", 57 | "bashls", 58 | "vtsls", 59 | "jsonls", 60 | "yamlls", 61 | "bashls", 62 | "gopls", 63 | "basedpyright", 64 | }, 65 | automatic_installation = true, 66 | automatic_enable = false, 67 | }, 68 | }, 69 | 70 | { 71 | "j-hui/fidget.nvim", 72 | event = "LspAttach", 73 | opts = { 74 | notification = { 75 | window = { 76 | winblend = 1, 77 | normal_hl = "NormalFloat", 78 | }, 79 | }, 80 | }, 81 | }, 82 | } 83 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/markdown-preview.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("markdown preview") 2 | 3 | return { 4 | "iamcco/markdown-preview.nvim", 5 | build = "cd app && npm install && rm -f package-lock.json && git restore .", 6 | ft = {"markdown"}, 7 | init = function() vim.g.mkdp_filetypes = {"markdown"} end, 8 | keys = { 9 | {"mp", ":MarkdownPreview", mode = "n", desc = desc("Preview")}, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/neogen.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("neogen") 2 | 3 | return { 4 | "danymat/neogen", 5 | dependencies = "nvim-treesitter/nvim-treesitter", 6 | keys = function() 7 | return { 8 | {"nf", function() require("neogen").generate({type = "func"}) end, desc = desc("Generate function docs")}, 9 | {"nt", function() require("neogen").generate({type = "type"}) end, desc = desc("Generate type docs")}, 10 | {"nc", function() require("neogen").generate({type = "class"}) end, desc = desc("Generate class docs")}, 11 | {"ne", function() require("neogen").generate({type = "file"}) end, desc = desc("Generate file docs")}, 12 | } 13 | end, 14 | opts = {snippet_engine = "nvim"}, 15 | } 16 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/neotest.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-neotest/neotest", 3 | dependencies = { 4 | "nvim-neotest/nvim-nio", 5 | "nvim-treesitter/nvim-treesitter", 6 | "nvim-lua/plenary.nvim", 7 | "antoinemadec/FixCursorHold.nvim", 8 | -- Adapters 9 | "gonstoll/neotest-jest", 10 | "marilari88/neotest-vitest", 11 | "thenbe/neotest-playwright", 12 | "fredrikaverpil/neotest-golang", 13 | }, 14 | keys = function() 15 | local desc = Utils.plugin_keymap_desc("neotest") 16 | return { 17 | { "T", "", desc = "+test" }, 18 | { 19 | "Tt", 20 | function() 21 | require("neotest").run.run(vim.fn.expand("%")) 22 | end, 23 | desc = desc("Run File"), 24 | }, 25 | { 26 | "TT", 27 | function() 28 | require("neotest").run.run(vim.uv.cwd()) 29 | end, 30 | desc = desc("Run All Test Files"), 31 | }, 32 | { 33 | "Tr", 34 | function() 35 | require("neotest").run.run() 36 | end, 37 | desc = desc("Run Nearest"), 38 | }, 39 | { 40 | "Tw", 41 | function() 42 | require("neotest").run.run({ 43 | vim.fn.expand("%"), 44 | jestCommand = "node_modules/.bin/jest --watch", 45 | }) 46 | end, 47 | desc = desc("Run test on watch mode"), 48 | }, 49 | { 50 | "TW", 51 | function() 52 | require("neotest").watch.toggle(vim.fn.expand("%")) 53 | end, 54 | desc = desc("Toggle watch mode (not working with jest)"), 55 | }, 56 | { 57 | "Tl", 58 | function() 59 | require("neotest").run.run_last() 60 | end, 61 | desc = desc("Run Last"), 62 | }, 63 | { 64 | "Ts", 65 | function() 66 | require("neotest").summary.toggle() 67 | end, 68 | desc = desc("Toggle Summary"), 69 | }, 70 | { 71 | "To", 72 | function() 73 | require("neotest").output.open({ enter = true, auto_close = true }) 74 | end, 75 | desc = desc("Show Output"), 76 | }, 77 | { 78 | "TO", 79 | function() 80 | require("neotest").output_panel.toggle() 81 | end, 82 | desc = desc("Toggle Output Panel"), 83 | }, 84 | { 85 | "TS", 86 | function() 87 | require("neotest").run.stop() 88 | end, 89 | desc = desc("Stop"), 90 | }, 91 | } 92 | end, 93 | opts = { 94 | status = { virtual_text = true }, 95 | output = { open_on_run = true }, 96 | summary = { mappings = { jumpto = "" } }, 97 | output_panel = { 98 | open = "botright vsplit | vertical resize 80", 99 | }, 100 | adapters = { 101 | ["neotest-jest"] = { 102 | jestCommand = "npm test --", 103 | jestConfigFile = function(file) 104 | if string.find(file, "/apps/") or string.find(file, "/packages/") then 105 | return string.match(file, "(.-/[^/]+/)src") .. "jest.config.{j,t}s" 106 | end 107 | 108 | return vim.fn.getcwd() .. "/jest.config.{j,t}s" 109 | end, 110 | cwd = function(file) 111 | if string.find(file, "/apps/") or string.find(file, "/packages/") then 112 | return string.match(file, "(.-/[^/]+/)src") 113 | end 114 | return vim.fn.getcwd() 115 | end, 116 | }, 117 | ["neotest-vitest"] = { 118 | filter_dir = function(name, rel_path, root) 119 | return name ~= "node_modules" 120 | end, 121 | }, 122 | ["neotest-golang"] = { 123 | dap_go_enabled = true, 124 | }, 125 | ["neotest-playwright"] = { 126 | adapter = { 127 | options = { 128 | enable_dynamic_test_discovery = true, 129 | get_playwright_binary = function() 130 | local install_path = "node_modules/.bin/playwright" 131 | return vim.fs.find(install_path, { upward = true, path = vim.fn.getcwd(), type = "file" })[1] 132 | end, 133 | get_playwright_config = function() 134 | local root_paths = { "/apps/e2e", "/apps/e2e-tests" } 135 | local path = nil 136 | for _, root_path in ipairs(root_paths) do 137 | local app_path = vim.fn.getcwd() .. root_path 138 | if vim.fn.isdirectory(app_path) then 139 | path = app_path .. "/playwright.config.ts" 140 | end 141 | end 142 | return path or vim.loop.cwd() .. "/playwright.config.ts" 143 | end, 144 | ---@param name string 145 | ---@param rel_path string 146 | filter_dir = function(name, rel_path, root) 147 | return rel_path:match("node_modules") 148 | end, 149 | ---@param file_path string 150 | is_test_file = function(file_path) 151 | return file_path:find("{e2e,e2e-tests}/.*%.{test,spec}%.[tj]sx?$") ~= nil 152 | end, 153 | }, 154 | }, 155 | }, 156 | }, 157 | }, 158 | config = function(_, opts) 159 | local neotest_ns = vim.api.nvim_create_namespace("neotest") 160 | vim.diagnostic.config({ 161 | virtual_text = { 162 | format = function(diagnostic) 163 | -- Replace newline and tab characters with space for more compact diagnostics 164 | local message = diagnostic.message:gsub("\n", " "):gsub("\t", " "):gsub("%s+", " "):gsub("^%s+", "") 165 | return message 166 | end, 167 | }, 168 | }, neotest_ns) 169 | 170 | if opts.adapters then 171 | local adapters = {} 172 | for name, config in pairs(opts.adapters or {}) do 173 | if type(name) == "number" then 174 | if type(config) == "string" then 175 | config = require(config) 176 | end 177 | adapters[#adapters + 1] = config 178 | elseif config ~= false then 179 | local adapter = require(name) 180 | if type(config) == "table" and not vim.tbl_isempty(config) then 181 | local meta = getmetatable(adapter) 182 | if adapter.setup then 183 | adapter.setup(config) 184 | elseif adapter.adapter then 185 | adapter.adapter(config) 186 | adapter = adapter.adapter 187 | elseif meta and meta.__call then 188 | adapter = adapter(config) 189 | else 190 | error("Adapter " .. name .. " does not support setup") 191 | end 192 | end 193 | adapters[#adapters + 1] = adapter 194 | end 195 | end 196 | opts.adapters = adapters 197 | end 198 | 199 | require("neotest").setup(opts) 200 | end, 201 | } 202 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/nvim-early-retirement.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "chrisgrieser/nvim-early-retirement", 3 | config = true, 4 | event = "VeryLazy", 5 | } 6 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/oil.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("oil") 2 | 3 | return { 4 | "stevearc/oil.nvim", 5 | dependencies = { 6 | {"nvim-treesitter/nvim-treesitter"}, 7 | {"nvim-tree/nvim-web-devicons", lazy = true}, 8 | }, 9 | ---@module 'oil' 10 | ---@type oil.SetupOpts 11 | opts = { 12 | delete_to_trash = true, 13 | skip_confirm_for_simple_edits = true, 14 | view_options = { 15 | show_hidden = true, 16 | is_always_hidden = function(name, _) 17 | return vim.startswith(name, ".DS_Store") 18 | end, 19 | }, 20 | keymaps = { 21 | [""] = false, -- Split 22 | [""] = false, -- refresh 23 | ["os"] = "actions.select_split", 24 | ["ov"] = "actions.select_vsplit", 25 | [""] = "actions.refresh", 26 | }, 27 | float = {padding = 4}, 28 | }, 29 | config = function(_, opts) 30 | local oil = require("oil") 31 | oil.setup(opts) 32 | vim.keymap.set("n", "-", oil.open, {desc = desc("Open parent directory")}) 33 | end, 34 | } 35 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/snacks.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("snacks") 2 | local scratch_path = os.getenv("HOME") .. "/notes/scratch" 3 | 4 | return { 5 | "folke/snacks.nvim", 6 | lazy = false, 7 | ---@type snacks.Config 8 | opts = { 9 | bigfile = {enabled = true}, 10 | quickfile = {enabled = true}, 11 | gitbrowse = {enabled = true}, 12 | dashboard = {enabled = false}, 13 | notifier = {enabled = false}, 14 | statuscolumn = {enabled = false}, 15 | words = {enabled = false}, 16 | lazygit = {enabled = false}, 17 | image = { 18 | doc = {inline = false}, 19 | convert = {notify = false}, 20 | }, 21 | picker = { 22 | finder = "explorer", 23 | hidden = true, 24 | supports_live = false, 25 | ui_select = false, 26 | }, 27 | scratch = { 28 | root = scratch_path, 29 | win = {width = 150, height = 40, border = "single"}, 30 | }, 31 | }, 32 | keys = function() 33 | local snacks = require("snacks") 34 | return { 35 | { 36 | ".", 37 | function() 38 | vim.ui.input({ 39 | prompt = "Enter scratch buffer title: ", 40 | default = "", 41 | }, function(t) 42 | if not vim.fn.isdirectory(scratch_path) then 43 | vim.fn.mkdir(scratch_path, "p") 44 | end 45 | 46 | if not t then 47 | return 48 | end 49 | 50 | local title = t ~= "" and t:gsub("%s+", "_") or "Untitled" 51 | snacks.scratch.open({ 52 | ft = "markdown", 53 | name = title .. "_" .. os.date("%Y-%m-%d-%H-%M-%S"), 54 | win = { 55 | title = title, 56 | }, 57 | }) 58 | end) 59 | end, 60 | desc = desc("Open a scratch buffer"), 61 | }, 62 | { 63 | "S", 64 | -- function() snacks.scratch.select() end, 65 | function() Utils.fzf.scratch_select() end, 66 | desc = desc("Select a scratch buffer"), 67 | }, 68 | { 69 | "cR", 70 | function() snacks.rename.rename_file() end, 71 | desc = desc("Rename File"), 72 | }, 73 | { 74 | "gy", 75 | function() snacks.gitbrowse() end, 76 | desc = desc("Open line(s) in browser"), 77 | mode = {"n", "v"}, 78 | }, 79 | { 80 | "gY", 81 | function() 82 | snacks.gitbrowse.open({ 83 | open = function(url) 84 | vim.fn.setreg("+", url) 85 | vim.notify("Yanked url to clipboard") 86 | end, 87 | }) 88 | end, 89 | desc = desc("Copy line(s) link"), 90 | mode = {"n", "v"}, 91 | }, 92 | { 93 | "oe", 94 | snacks.picker.explorer, 95 | desc = desc("Open file explorer"), 96 | }, 97 | } 98 | end, 99 | } 100 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/statuscol.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "luukvbaal/statuscol.nvim", 3 | config = function() 4 | local builtin = require("statuscol.builtin") 5 | require("statuscol").setup({ 6 | segments = { 7 | {text = {builtin.foldfunc}, click = "v:lua.ScFa"}, -- Fold 8 | {text = {" %s"}, click = "v:lua.ScSa"}, -- Git 9 | {text = {builtin.lnumfunc, " "}, condition = {true, builtin.not_empty}, click = "v:lua.ScLa"}, 10 | }, 11 | }) 12 | end, 13 | } 14 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/todo-comments.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("TODO comments") 2 | 3 | return { 4 | "folke/todo-comments.nvim", 5 | dependencies = {"nvim-lua/plenary.nvim"}, 6 | event = "BufReadPre", 7 | opts = { 8 | gui_style = { 9 | fg = "NONE", 10 | bg = "NONE", 11 | }, 12 | colors = { 13 | info = {"DiffText", "#2563EB"}, 14 | }, 15 | }, 16 | config = function(_, opts) 17 | local todo_comments = require("todo-comments") 18 | todo_comments.setup(opts) 19 | vim.keymap.set("n", "]t", function() todo_comments.jump_next() end, {desc = desc("Next todo comment")}) 20 | vim.keymap.set("n", "[t", function() todo_comments.jump_prev() end, {desc = desc("Previous todo comment")}) 21 | end, 22 | } 23 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-treesitter/nvim-treesitter", 3 | branch = "master", 4 | dependencies = { 5 | { "windwp/nvim-ts-autotag", opts = {} }, 6 | { "nvim-treesitter/nvim-treesitter-context", opts = { enable = false } }, 7 | }, 8 | cmd = { "TSInstall", "TSBufEnable", "TSBufDisable", "TSModuleInfo" }, 9 | build = ":TSUpdate", 10 | lazy = vim.fn.argc(-1) == 0, 11 | config = function() 12 | local configs = require("nvim-treesitter.configs") 13 | local parsers = require("nvim-treesitter.parsers") 14 | 15 | configs.setup({ 16 | ensure_installed = { 17 | "bash", 18 | "css", 19 | "diff", 20 | "dockerfile", 21 | "go", 22 | "gomod", 23 | "gowork", 24 | "graphql", 25 | "html", 26 | "javascript", 27 | "jsdoc", 28 | "json", 29 | "json5", 30 | "lua", 31 | "markdown", 32 | "markdown_inline", 33 | "php", 34 | "prisma", 35 | "python", 36 | "regex", 37 | "rust", 38 | "scss", 39 | "sql", 40 | "tsx", 41 | "typescript", 42 | "vim", 43 | "vimdoc", 44 | "yaml", 45 | }, 46 | highlight = { enable = true }, 47 | indent = { enable = true }, 48 | context_commentstring = { 49 | enable = true, 50 | enable_autocmd = false, 51 | }, 52 | incremental_selection = { 53 | enable = true, 54 | keymaps = { 55 | init_selection = "ti", 56 | scope_incremental = "ts", 57 | node_incremental = "v", 58 | node_decremental = "V", 59 | }, 60 | }, 61 | }) 62 | 63 | local parser_configs = parsers.get_parser_configs() 64 | parser_configs.tsx.filetype_to_parsername = { "javascript", "typescript.tsx" } 65 | end, 66 | } 67 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/useless.lua: -------------------------------------------------------------------------------- 1 | local duck_desc = Utils.plugin_keymap_desc("duck") 2 | local cel_desc = Utils.plugin_keymap_desc("CellularAutomaton") 3 | 4 | return { 5 | { 6 | "tamton-aquib/duck.nvim", 7 | keys = { 8 | {",dd", function() require("duck").hatch("🐈") end, desc = duck_desc("Hatch")}, 9 | {",dk", function() require("duck").cook() end, mode = "n", desc = duck_desc("Cook")}, 10 | }, 11 | }, 12 | 13 | { 14 | "eandrju/cellular-automaton.nvim", 15 | keys = { 16 | {",fml", "CellularAutomaton make_it_rain", desc = cel_desc("Make it rain")}, 17 | }, 18 | }, 19 | 20 | { 21 | "marcussimonsen/let-it-snow.nvim", 22 | cmd = "LetItSnow", 23 | opts = {}, 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/vim-surround.lua: -------------------------------------------------------------------------------- 1 | return {"tpope/vim-surround", config = false, event = "BufReadPre"} 2 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/vim-tmux-navigator.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "christoomey/vim-tmux-navigator", 3 | cmd = { 4 | "TmuxNavigateLeft", 5 | "TmuxNavigateDown", 6 | "TmuxNavigateUp", 7 | "TmuxNavigateRight", 8 | "TmuxNavigatePrevious", 9 | }, 10 | keys = { 11 | {"", "TmuxNavigateLeft"}, 12 | {"", "TmuxNavigateDown"}, 13 | {"", "TmuxNavigateUp"}, 14 | {"", "TmuxNavigateRight"}, 15 | {"", "TmuxNavigatePrevious"}, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/which-key.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/which-key.nvim", 3 | event = "VeryLazy", 4 | opts = { 5 | icons = {rules = false}, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /.config/nvim/lua/plugins/yazi.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc("yazi") 2 | 3 | return { 4 | "mikavilpas/yazi.nvim", 5 | keys = { 6 | {"-", "Yazi", desc = desc("Open yazi at the current file")}, 7 | -- Open in the current working directory 8 | {"cw", "Yazi cwd", desc = desc("Open yazi in nvim's working directory")}, 9 | {"", "Yazi toggle", desc = desc("Resume the last yazi session")}, 10 | }, 11 | ---@module 'yazi.config' 12 | ---@type YaziConfig 13 | opts = { 14 | open_for_directories = false, 15 | keymaps = { 16 | show_help = "", 17 | open_file_in_horizontal_split = "os", 18 | open_file_in_vertical_split = "ov", 19 | grep_in_directory = "", 20 | }, 21 | highlight_groups = { 22 | -- hovered_buffer = {bg = 'none', fg = 'none'}, 23 | hovered_buffer_in_same_directory = {bg = "none", fg = "none"}, 24 | }, 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /.config/nvim/lua/statusline.lua: -------------------------------------------------------------------------------- 1 | -- Credit goes where credit is due. This is a modified version of: 2 | -- https://nuxsh.is-a.dev/blog/custom-nvim-statusline.html 3 | local modes = { 4 | ["n"] = "[Normal]", 5 | ["no"] = "[Normal]", 6 | ["v"] = "[Visual]", 7 | ["V"] = "[Visual line]", 8 | [""] = "[Visual block]", 9 | ["s"] = "[Select]", 10 | ["S"] = "[Select line]", 11 | [""] = "[Select block]", 12 | ["i"] = "[Insert]", 13 | ["ic"] = "[Insert]", 14 | ["R"] = "[Replace]", 15 | ["Rv"] = "[Visual replace]", 16 | ["c"] = "[Command]", 17 | ["cv"] = "[Vim ex]", 18 | ["ce"] = "[Ex]", 19 | ["r"] = "[Prompt]", 20 | ["rm"] = "[Moar]", 21 | ["r?"] = "[Confirm]", 22 | ["!"] = "[Shell]", 23 | ["t"] = "[Terminal]", 24 | ["nt"] = "[Terminal]", 25 | } 26 | 27 | local function mode() 28 | local current_mode = vim.api.nvim_get_mode().mode 29 | return string.format("%s", modes[current_mode]) 30 | end 31 | 32 | local function update_mode_colors() 33 | local current_mode = vim.api.nvim_get_mode().mode 34 | local mode_color = "%#StatusLineAccent#" 35 | if current_mode == "n" then 36 | mode_color = "%#StatusLineAccent#" 37 | elseif current_mode == "i" or current_mode == "ic" then 38 | mode_color = "%#StatusLineInsertAccent#" 39 | elseif current_mode == "v" or current_mode == "V" or current_mode == "" then 40 | mode_color = "%#StatusLineVisualAccent#" 41 | elseif current_mode == "R" then 42 | mode_color = "%#StatusLineReplaceAccent#" 43 | elseif current_mode == "c" then 44 | mode_color = "%#StatusLineCmdLineAccent#" 45 | elseif current_mode == "t" or current_mode == "nt" then 46 | mode_color = "%#StatusLineTerminalAccent#" 47 | end 48 | return mode_color 49 | end 50 | 51 | local function filepath() 52 | local fpath = vim.fn.fnamemodify(vim.fn.expand("%"), ":~:.:h") 53 | if fpath == "" or fpath == "." then 54 | return " " 55 | end 56 | if string.find(fpath, "oil://") then 57 | fpath = string.gsub(fpath, "oil://", "") 58 | end 59 | fpath = fpath:gsub(vim.env.HOME, "~", 1) 60 | 61 | local is_wide = vim.api.nvim_win_get_width(0) > 80 62 | 63 | if not is_wide then 64 | fpath = vim.fn.pathshorten(fpath) 65 | end 66 | 67 | return string.format("%%<%s/", fpath) 68 | end 69 | 70 | local function filename() 71 | local fname = vim.fn.expand("%:t") 72 | if fname == "" then 73 | return "" 74 | end 75 | return fname .. " " 76 | end 77 | 78 | local function lsp() 79 | local count = {} 80 | local levels = { 81 | errors = "Error", 82 | warnings = "Warn", 83 | info = "Info", 84 | hints = "Hint", 85 | } 86 | 87 | for k, level in pairs(levels) do 88 | count[k] = vim.tbl_count(vim.diagnostic.get(0, {severity = level})) 89 | end 90 | 91 | local errors = "" 92 | local warnings = "" 93 | local hints = "" 94 | local info = "" 95 | 96 | if count["errors"] ~= 0 then 97 | errors = " %#StatusLineDiagnosticSignError#" .. "E" .. count["errors"] 98 | end 99 | if count["warnings"] ~= 0 then 100 | warnings = " %#StatusLineDiagnosticSignWarn#" .. "W" .. count["warnings"] 101 | end 102 | if count["hints"] ~= 0 then 103 | hints = " %#StatusLineDiagnosticSignHint#" .. "H" .. count["hints"] 104 | end 105 | if count["info"] ~= 0 then 106 | info = " %#StatusLineDiagnosticSignInfo#" .. "I" .. count["info"] 107 | end 108 | 109 | return errors .. warnings .. hints .. info .. "%#Statusline# " 110 | end 111 | 112 | local vcs = function() 113 | local git_info = vim.b.gitsigns_status_dict 114 | if not git_info or git_info.head == "" then 115 | return "" 116 | end 117 | local added = git_info.added and 118 | ("%#StatusLineGitSignsAdd#" .. Utils.icons.git.added .. " " .. git_info.added .. " ") or 119 | "" 120 | local changed = git_info.changed and 121 | ("%#StatusLineGitSignsChange#" .. Utils.icons.git.changed .. " " .. git_info.changed .. " ") or "" 122 | local removed = git_info.removed and 123 | ("%#StatusLineGitSignsDelete#" .. Utils.icons.git.deleted .. " " .. git_info.removed .. " ") or "" 124 | if git_info.added == 0 then 125 | added = "" 126 | end 127 | if git_info.changed == 0 then 128 | changed = "" 129 | end 130 | if git_info.removed == 0 then 131 | removed = "" 132 | end 133 | return table.concat({ 134 | " ", 135 | Utils.icons.git.branch2, 136 | " ", 137 | git_info.head, 138 | " ", 139 | added, 140 | changed, 141 | removed, 142 | }) 143 | end 144 | 145 | local function filetype() 146 | return string.format(" %s ", vim.bo.filetype) 147 | end 148 | 149 | local function modified() 150 | return "%m" 151 | end 152 | 153 | local function lineinfo() 154 | if vim.bo.filetype == "alpha" then 155 | return "" 156 | end 157 | return " %P %l:%c " 158 | end 159 | 160 | local M = {} 161 | 162 | -- Active statusline 163 | function M.active() 164 | return table.concat({ 165 | -- update_mode_colors(), 166 | -- mode(), 167 | "%#Statusline# ", 168 | filepath(), 169 | filename(), 170 | modified(), 171 | vcs(), 172 | "%#Statusline#", 173 | "%=%#StatusLineExtra#", 174 | lsp(), 175 | filetype(), 176 | lineinfo(), 177 | }) 178 | end 179 | 180 | -- Inactive statusline, usually when a window is not focused 181 | function M.inactive() 182 | return " %f " 183 | end 184 | 185 | function M.help() 186 | return table.concat({ 187 | "%#Statusline# ", 188 | filepath(), 189 | filename(), 190 | "%#Statusline#", 191 | "%=%#StatusLineExtra#", 192 | filetype(), 193 | lineinfo(), 194 | }) 195 | end 196 | 197 | -- Oil statusline 198 | function M.oil() 199 | return table.concat({ 200 | "%#Statusline#  ", 201 | filepath(), 202 | }) 203 | end 204 | 205 | return M 206 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/browse.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local config = { 4 | default_engine = "google", 5 | query_map = { 6 | google = "https://www.google.com/search?q=%s", 7 | bing = "https://cn.bing.com/search?q=%s", 8 | duckduckgo = "https://duckduckgo.com/?q=%s", 9 | wikipedia = "https://en.wikipedia.org/w/index.php?search=%s", 10 | }, 11 | } 12 | 13 | local function looks_like_url(input) 14 | local pat = "[%w%.%-_]+%.[%w%.%-_/]+" 15 | return input:match(pat) ~= nil 16 | end 17 | 18 | local function extract_prefix(input) 19 | local pat = "@(%w+)" 20 | local prefix = input:match(pat) 21 | if not prefix or not config.query_map[prefix] then 22 | return vim.trim(input), config.default_engine 23 | end 24 | local query = input:gsub("@" .. prefix, "") 25 | return vim.trim(query), prefix 26 | end 27 | 28 | function M.query_browser(input) 29 | local q, prefix = extract_prefix(input) 30 | if not looks_like_url(input) then 31 | local format = config.query_map[prefix] 32 | q = format:format(vim.uri_encode(q)) 33 | end 34 | vim.ui.open(q) 35 | end 36 | 37 | return M 38 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/colors.lua: -------------------------------------------------------------------------------- 1 | -- Taken from https://github.com/rachartier/tiny-inline-diagnostic.nvim 2 | ---@param hex string 3 | local function hex_to_rgb(hex) 4 | if hex == nil or hex == 'None' then 5 | return {0, 0, 0} 6 | end 7 | 8 | hex = hex:gsub('#', '') 9 | hex = string.lower(hex) 10 | 11 | return { 12 | tonumber(hex:sub(1, 2), 16), 13 | tonumber(hex:sub(3, 4), 16), 14 | tonumber(hex:sub(5, 6), 16), 15 | } 16 | end 17 | 18 | -- Taken from https://github.com/rachartier/tiny-inline-diagnostic.nvim 19 | ---@param foreground string foreground color 20 | ---@param background string background color 21 | ---@param alpha number|string number between 0 and 1. 0 results in bg, 1 results in fg 22 | local function blend(foreground, background, alpha) 23 | alpha = type(alpha) == 'string' and (tonumber(alpha, 16) / 0xff) or alpha 24 | 25 | local fg = hex_to_rgb(foreground) 26 | local bg = hex_to_rgb(background) 27 | 28 | local blend_channel = function(i) 29 | local ret = (alpha * fg[i] + ((1 - alpha) * bg[i])) 30 | return math.floor(math.min(math.max(0, ret), 255) + 0.5) 31 | end 32 | 33 | return string.format('#%02x%02x%02x', blend_channel(1), blend_channel(2), blend_channel(3)):upper() 34 | end 35 | 36 | return {blend = blend} 37 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/fzf.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---@param client_name string LSP client name 4 | local function open_lsp_float(client_name) 5 | local client = vim.lsp.get_clients({ name = client_name }) 6 | 7 | if #client == 0 then 8 | vim.notify("No active LSP clients found with this name: " .. client_name, vim.log.levels.WARN) 9 | return 10 | end 11 | 12 | -- Create a temporary buffer to show the configuration 13 | local buf = vim.api.nvim_create_buf(false, true) 14 | vim.api.nvim_open_win(buf, true, { 15 | relative = "editor", 16 | width = math.floor(vim.o.columns * 0.75), 17 | height = math.floor(vim.o.lines * 0.90), 18 | col = math.floor(vim.o.columns * 0.125), 19 | row = math.floor(vim.o.lines * 0.05), 20 | border = "single", 21 | title = " " .. (client_name:gsub("^%l", string.upper)) .. ": LSP Configuration ", 22 | title_pos = "center", 23 | }) 24 | 25 | local lines = {} 26 | for i, this_client in ipairs(client) do 27 | if i > 1 then 28 | table.insert(lines, string.rep("-", 80)) 29 | end 30 | table.insert(lines, "Client: " .. this_client.name) 31 | table.insert(lines, "ID: " .. this_client.id) 32 | table.insert(lines, "") 33 | table.insert(lines, "Configuration:") 34 | 35 | local config_lines = vim.split(vim.inspect(this_client.config), "\n") 36 | vim.list_extend(lines, config_lines) 37 | end 38 | 39 | -- Set the lines in the buffer 40 | vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) 41 | 42 | -- Set buffer options 43 | vim.bo[buf].modifiable = false 44 | vim.bo[buf].filetype = "lua" 45 | vim.bo[buf].bh = "delete" 46 | 47 | vim.api.nvim_buf_set_keymap(buf, "n", "q", ":q", { noremap = true, silent = true }) 48 | end 49 | 50 | -- Inspects active LSPs configuration 51 | -- Taken from https://www.reddit.com/r/neovim/comments/1gf7kyn/lsp_configuration_debugging/ 52 | function M.inspect_lsp_client() 53 | local fzf = require("fzf-lua") 54 | local clients = vim.lsp.get_clients() 55 | local client_names = {} 56 | 57 | for _, client in ipairs(clients) do 58 | table.insert(client_names, client.name) 59 | end 60 | 61 | fzf.fzf_exec(client_names, { 62 | prompt = "LSP Client name: ", 63 | winopts = { height = 0.33 }, 64 | actions = { 65 | ["default"] = function(selected, opts) 66 | local selected_client = selected[1] 67 | open_lsp_float(selected_client) 68 | end, 69 | }, 70 | }) 71 | end 72 | 73 | function M.scratch_select() 74 | local entries = {} 75 | local items = Snacks.scratch.list() 76 | local item_map = {} 77 | local utils = require("fzf-lua.utils") 78 | 79 | local function hl_validate(hl) 80 | return not utils.is_hl_cleared(hl) and hl or nil 81 | end 82 | 83 | local function ansi_from_hl(hl, s) 84 | return utils.ansi_from_hl(hl_validate(hl), s) 85 | end 86 | 87 | for _, item in ipairs(items) do 88 | item.icon = item.icon or Snacks.util.icon(item.ft, "filetype") 89 | item.branch = item.branch and ("branch:%s"):format(item.branch) or "" 90 | item.cwd = item.cwd and vim.fn.fnamemodify(item.cwd, ":p:~") or "" 91 | local display = string.format("%s %s %s %s", item.cwd, item.icon, item.name, item.branch) -- same as what Snacks.scratch uses to display items 92 | table.insert(entries, display) 93 | item_map[display] = item 94 | end 95 | 96 | local fzf = require("fzf-lua") 97 | 98 | fzf.fzf_exec(entries, { 99 | prompt = "Scratch buffers: ", 100 | fzf_opts = { 101 | ["--header"] = string.format( 102 | ":: <%s> to %s | <%s> to %s", 103 | ansi_from_hl("FzfLuaHeaderBind", "enter"), 104 | ansi_from_hl("FzfLuaHeaderText", "Select Scratch"), 105 | ansi_from_hl("FzfLuaHeaderBind", "ctrl-x"), 106 | ansi_from_hl("FzfLuaHeaderText", "Delete Scratch") 107 | ), 108 | }, 109 | winopts = { height = 0.5 }, 110 | actions = { 111 | ["default"] = function(selected) 112 | local item = item_map[selected[1]] 113 | Snacks.scratch.open({ 114 | icon = item.icon, 115 | file = item.file, 116 | name = item.name, 117 | ft = item.ft, 118 | width = 150, 119 | height = 40, 120 | border = "single", 121 | }) 122 | end, 123 | ["ctrl-x"] = { 124 | function(selected) 125 | local selected_item = selected[1] 126 | local item = item_map[selected_item] 127 | vim.fn.delete(item.file) 128 | vim.notify("Deleted scratch file: " .. item.file) 129 | M.scratch_select() 130 | end, 131 | }, 132 | }, 133 | }) 134 | end 135 | 136 | -- Folder grep function 137 | -- Allows selecting a folder and running grep in it 138 | function M.folder_grep() 139 | local fzf = require("fzf-lua") 140 | 141 | fzf.fzf_exec("find . -type d", { 142 | prompt = "Folder: ", 143 | actions = { 144 | ["default"] = function(selected) 145 | if selected and #selected > 0 then 146 | fzf.live_grep({ cwd = selected[1] }) 147 | end 148 | end, 149 | }, 150 | }) 151 | end 152 | 153 | return M 154 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/icons.lua: -------------------------------------------------------------------------------- 1 | return { 2 | diagnostics = { 3 | Error = ' ', 4 | Warn = ' ', 5 | Hint = ' ', 6 | Info = ' ', 7 | }, 8 | git = { 9 | added = '󰜄', 10 | changed = '󱗝', 11 | deleted = '󰛲', 12 | branch = '', 13 | branch2 = '', 14 | }, 15 | dap = { 16 | Stopped = {'󰁕 ', 'DiagnosticSignWarn', 'DapStoppedLine'}, 17 | Breakpoint = {' ', 'DiagnosticSignInfo'}, 18 | BreakpointCondition = {' ', 'DiagnosticSignHint'}, 19 | BreakpointRejected = {' ', 'DiagnosticSignError'}, 20 | LogPoint = '.>', 21 | }, 22 | misc = { 23 | folder = '', 24 | folder_outline = '', 25 | file = '', 26 | file2 = '', 27 | file_outline = '󰧮', 28 | search = '', 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/init.lua: -------------------------------------------------------------------------------- 1 | local M = { 2 | colors = require("utils.colors"), 3 | icons = require("utils.icons"), 4 | fzf = require("utils.fzf"), 5 | lsp = require("utils.lsp"), 6 | redir = require("utils.redir"), 7 | browse = require("utils.browse"), 8 | } 9 | 10 | -- Merge two tables 11 | ---@param t1 table 12 | ---@param t2 table 13 | M.merge_table = function(t1, t2) 14 | for k, v in pairs(t2) do 15 | t1[k] = v 16 | end 17 | return t1 18 | end 19 | 20 | -- Create a function that returns a tagged keymap description 21 | ---@param plugin_name string 22 | M.plugin_keymap_desc = function(plugin_name) 23 | ---@param desc string 24 | return function(desc) 25 | -- Capitalize plugin name and concat with desc 26 | -- Examples: 27 | -- - 'nvim-tree': 'Nvim-tree: ${desc}' 28 | -- - 'conform': 'Conform: ${desc}' 29 | return plugin_name:gsub("^%l", string.upper) .. ": " .. desc 30 | end 31 | end 32 | 33 | -- Create a command that centers the screen after running the callback 34 | ---@param callback function 35 | M.cmd_center = function(callback) 36 | return function() 37 | callback() 38 | vim.cmd("normal! zz") 39 | end 40 | end 41 | 42 | --- Gets a path to a package in the Mason registry. 43 | --- Prefer this to `get_package`, since the package might not always be 44 | --- available yet and trigger errors. 45 | ---@param pkg string 46 | ---@param path? string 47 | function M.get_pkg_path(pkg, path) 48 | pcall(require, "mason") -- make sure Mason is loaded. Will fail when generating docs 49 | local root = vim.env.MASON or (vim.fn.stdpath("data") .. "/mason") 50 | path = path or "" 51 | local ret = root .. "/packages/" .. pkg .. "/" .. path 52 | return ret 53 | end 54 | 55 | -- Check if a command-line tool exists 56 | -- @param cmd string: The command to check 57 | -- @return boolean: True if the command exists, false otherwise 58 | function M.check_cmd_exists(cmd) 59 | if not cmd or cmd == "" then 60 | return false 61 | end 62 | 63 | -- Use vim.fn.executable to check if the command exists 64 | return vim.fn.executable(cmd) == 1 65 | end 66 | 67 | return M 68 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/lsp.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---@param opts table 4 | function M.execute(opts) 5 | local params = { 6 | command = opts.command, 7 | arguments = opts.arguments, 8 | } 9 | if opts.open then 10 | -- require('trouble').open({ 11 | -- mode = 'lsp_command', 12 | -- params = params, 13 | -- }) 14 | else 15 | return vim.lsp.buf_request(0, "workspace/executeCommand", params, opts.handler) 16 | end 17 | end 18 | 19 | ---@param on_attach fun(client:vim.lsp.Client, buffer) 20 | ---@param name? string 21 | function M.on_attach(on_attach, name) 22 | return vim.api.nvim_create_autocmd("LspAttach", { 23 | callback = function(args) 24 | local buffer = args.buf ---@type number 25 | local client = vim.lsp.get_client_by_id(args.data.client_id) 26 | if client and (not name or client.name == name) then 27 | return on_attach(client, buffer) 28 | end 29 | end, 30 | }) 31 | end 32 | 33 | return M 34 | -------------------------------------------------------------------------------- /.config/nvim/lua/utils/redir.lua: -------------------------------------------------------------------------------- 1 | -- Display command output in neovim split window 2 | -- Taken from: https://gist.github.com/Leenuus/7a2ea47b88bfe16430b42e4e48122718 3 | local M = {} 4 | 5 | local function redir_open_win(buf, vertical, stderr_p) 6 | local wn = stderr_p and 'redir_sterr_win' or 'redir_win' 7 | if vim.g[wn] == nil then 8 | local win = vim.api.nvim_open_win(buf, true, { 9 | vertical = vertical, 10 | }) 11 | vim.api.nvim_create_autocmd('WinClosed', { 12 | pattern = {string.format('%d', win)}, 13 | callback = function() 14 | vim.g[wn] = nil 15 | end, 16 | }) 17 | vim.g[wn] = win 18 | else 19 | vim.api.nvim_win_set_buf(vim.g[wn], buf) 20 | end 21 | end 22 | 23 | local function redir_vim_command(cmd, vertical) 24 | vim.cmd('redir => output') 25 | vim.cmd('silent ' .. cmd) 26 | vim.cmd('redir END') 27 | local output = vim.fn.split(vim.g.output, '\n') 28 | local buf = vim.api.nvim_create_buf(false, true) 29 | vim.api.nvim_buf_set_lines(buf, 0, 0, false, output) 30 | 31 | redir_open_win(buf, vertical) 32 | end 33 | 34 | local function redir_shell_command(cmd, lines, vertical, stderr_p) 35 | local shell_cmd = { 36 | 'sh', 37 | '-c', 38 | cmd, 39 | } 40 | 41 | local stdin = nil 42 | if #lines ~= 0 then 43 | stdin = lines 44 | end 45 | 46 | local stdout_buf = vim.api.nvim_create_buf(false, true) 47 | vim.api.nvim_set_option_value('ft', 'redir_stdout', {buf = stdout_buf}) 48 | redir_open_win(stdout_buf, vertical) 49 | 50 | local stderr = nil 51 | if stderr_p then 52 | local stderr_buf = vim.api.nvim_create_buf(false, true) 53 | vim.api.nvim_set_option_value('ft', 'redir_sterr', {buf = stderr_buf}) 54 | redir_open_win(stderr_buf, vertical, true) 55 | stderr = function(_, data) 56 | vim.schedule_wrap(function() 57 | if data ~= nil then 58 | local output = vim.fn.split(data, '\n') 59 | vim.api.nvim_buf_set_lines(stderr_buf, -1, -1, false, output) 60 | end 61 | end)() 62 | end 63 | end 64 | 65 | vim.system(shell_cmd, { 66 | text = true, 67 | stdout = function(_, stdout) 68 | vim.schedule_wrap(function() 69 | if stdout ~= nil then 70 | local output = vim.fn.split(stdout, '\n') 71 | vim.api.nvim_buf_set_lines(stdout_buf, -1, -1, false, output) 72 | end 73 | end)() 74 | end, 75 | stderr = stderr, 76 | stdin = stdin, 77 | }, function(completed) 78 | -- NOTE: 79 | -- placeholder to make call async 80 | end) 81 | end 82 | 83 | function M.redir(args) 84 | local cmd = args.args 85 | local vertical = args.smods.vertical 86 | local stderr_p = args.bang 87 | 88 | if cmd:sub(1, 1) == '!' then 89 | local range = args.range 90 | local lines 91 | if range == 0 then 92 | lines = {} 93 | else 94 | local line1 = args.line1 - 1 95 | local line2 = args.line2 96 | line2 = line1 == line2 and line1 + 1 or line2 97 | lines = vim.api.nvim_buf_get_lines(0, line1, line2, false) 98 | end 99 | 100 | cmd = cmd:sub(2) 101 | redir_shell_command(cmd, lines, vertical, stderr_p) 102 | else 103 | redir_vim_command(cmd, vertical) 104 | end 105 | end 106 | 107 | function M.evaler(range) 108 | return function(bang) 109 | local line = vim.fn.getline(1) 110 | local it = string.match(line, '^#!(.*)') 111 | 112 | local cmd = string.format('%sRedir%s !', range, bang and '!' or '') 113 | 114 | if it and it ~= '' then 115 | vim.cmd(cmd .. it) 116 | else 117 | vim.fn.feedkeys(':' .. cmd, 'tn') 118 | end 119 | end 120 | end 121 | 122 | return M 123 | -------------------------------------------------------------------------------- /.config/nvim/snippets/lua/snippets.lua: -------------------------------------------------------------------------------- 1 | local desc = Utils.plugin_keymap_desc('luasnip') 2 | 3 | local ls = require('luasnip') 4 | local fmt = require('luasnip.extras.fmt').fmt 5 | local rep = require('luasnip.extras').rep 6 | 7 | local t = ls.text_node 8 | local i = ls.insert_node 9 | local c = ls.choice_node 10 | local f = ls.function_node 11 | local d = ls.dynamic_node 12 | local snippet = ls.s 13 | local snippet_from_nodes = ls.sn 14 | 15 | -- Keymaps 16 | vim.keymap.set('n', 's', 'source ~/.config/nvim/after/plugin/snippets.lua', { 17 | desc = desc('Source snippets'), 18 | }) 19 | vim.keymap.set({'i', 's'}, '', function() 20 | if ls.choice_active() then 21 | ls.change_choice(1) 22 | end 23 | end, {desc = desc('Next choice')}) 24 | 25 | -- Snippets 26 | ls.add_snippets('all', { 27 | snippet('date', { 28 | f(function() 29 | return string.format(string.gsub(vim.bo.commentstring, '%%s', ' %%s'), os.date()) 30 | end, {}), 31 | }), 32 | snippet('todo', { 33 | c(1, { 34 | t('TODO: (gonza) - '), 35 | t('NOTE: (gonza) - '), 36 | t('FIX: (gonza) - '), 37 | t('WARNING: (gonza) - '), 38 | t('HACK: (gonza) - '), 39 | t('PERF: (gonza) - '), 40 | }), 41 | }), 42 | }) 43 | 44 | ls.add_snippets('lua', { 45 | snippet('req', fmt("local {} = require('{}')", { 46 | f(function(import_name) 47 | local parts = vim.split(import_name[1][1], '.', {plain = true}) 48 | return parts[#parts] or '' 49 | end, {1}), 50 | i(1, 'module'), 51 | })), 52 | }) 53 | 54 | local typescript_snippets = { 55 | snippet('izod', t("import {z} from 'zod'")), 56 | snippet('iar', t("import * as React from 'react'")), 57 | snippet('log', fmt('console.log({})', {i(1)})), 58 | snippet('logging', fmt("console.log('logging {}: ', {})", { 59 | f(function(import_name) 60 | local parts = vim.split(import_name[1][1], '.', {plain = true}) 61 | return parts[#parts] or '' 62 | end, {1}), 63 | i(1), 64 | })), 65 | snippet('rsc', {c(1, {t("'use server'"), t("'use client'")})}), 66 | snippet('func', { 67 | c(1, { 68 | fmt([[function {}({}) {{ 69 | {} 70 | }}]], {i(1), i(2), i(3)}), 71 | fmt([[async function {}({}) {{ 72 | {} 73 | }}]], {i(1), i(2), i(3)}), 74 | }), 75 | }), 76 | snippet('ust', fmt('const [{}] = React.useState{}({})', {i(1), i(2), i(3)})), 77 | snippet('uef', fmt([[React.useEffect(() => {{ 78 | {} 79 | }}, [])]], {i(1)})), 80 | } 81 | 82 | local react_snippets = { 83 | snippet('rc', { 84 | c(1, { 85 | fmt([[import * as React from 'react' 86 | 87 | export function {}() {{ 88 | return
{} 89 | }}]], {i(1), i(2)}), 90 | fmt([[import * as React from 'react' 91 | 92 | type Props = {{ 93 | {} 94 | }} 95 | 96 | export function {}({{{}}}: Props) {{ 97 | return
{} 98 | }}]], {i(1), i(2), i(3), i(4)}), 99 | }), 100 | }), 101 | } 102 | 103 | local merged_snippets = {} 104 | for _, v in ipairs(typescript_snippets) do 105 | table.insert(merged_snippets, v) 106 | end 107 | 108 | for _, v in ipairs(react_snippets) do 109 | table.insert(merged_snippets, v) 110 | end 111 | 112 | ls.add_snippets('typescript', typescript_snippets) 113 | ls.add_snippets('javascript', typescript_snippets) 114 | ls.add_snippets('typescriptreact', merged_snippets) 115 | ls.add_snippets('javascriptreact', merged_snippets) 116 | -------------------------------------------------------------------------------- /.config/nvim/snippets/nvim/all.json: -------------------------------------------------------------------------------- 1 | { 2 | "Add a TODO": { 3 | "description": "Add a TODO", 4 | "prefix": "todo", 5 | "body": ["TODO: (gonza) - ${1:Implement this}"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.config/nvim/snippets/nvim/lua.json: -------------------------------------------------------------------------------- 1 | { 2 | "require a module": { 3 | "description": "Require a lua module", 4 | "prefix": "req", 5 | "body": ["local ${2:name} = require('${1:module}')"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.config/nvim/snippets/nvim/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snippets", 3 | "contributes": { 4 | "snippets": [ 5 | { 6 | "language": "lua", 7 | "path": "./lua.json" 8 | }, 9 | { 10 | "language": [ 11 | "javascript", 12 | "typescript", 13 | "javascriptreact", 14 | "typescriptreact" 15 | ], 16 | "path": "./ts-js.json" 17 | }, 18 | { 19 | "language": [ 20 | "javascriptreact", 21 | "typescriptreact" 22 | ], 23 | "path": "./react.json" 24 | }, 25 | { 26 | "language": "all", 27 | "path": "./all.json" 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.config/nvim/snippets/nvim/react.json: -------------------------------------------------------------------------------- 1 | { 2 | "React component": { 3 | "description": "Create a React component", 4 | "prefix": "rc", 5 | "body": [ 6 | "import * as React from 'react';", 7 | "", 8 | "export function $1($2) {", 9 | " return (", 10 | "
", 11 | " $3", 12 | "
", 13 | " );", 14 | "}" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.config/nvim/snippets/nvim/ts-js.json: -------------------------------------------------------------------------------- 1 | { 2 | "Console log": { 3 | "description": "Log output to console", 4 | "prefix": "log", 5 | "body": [ 6 | "console.log($1)" 7 | ] 8 | }, 9 | "Console log with prefix": { 10 | "description": "Log output to console with a prefix", 11 | "prefix": "logging", 12 | "body": [ 13 | "console.log('logging $1:', $1)" 14 | ] 15 | }, 16 | "Function": { 17 | "description": "Create a function", 18 | "prefix": "fn", 19 | "body": [ 20 | "function $1($2) {", 21 | " $3", 22 | "}" 23 | ] 24 | }, 25 | "Arrow function": { 26 | "description": "Create an arrow function", 27 | "prefix": "afn", 28 | "body": [ 29 | "const $1 = $2($3) => {", 30 | " $4", 31 | "}" 32 | ] 33 | }, 34 | "Async function": { 35 | "description": "Create an async function", 36 | "prefix": "asyncfn", 37 | "body": [ 38 | "async function $1($2) {", 39 | " $3", 40 | "}" 41 | ] 42 | }, 43 | "Async arrow function": { 44 | "description": "Create an async arrow function", 45 | "prefix": "asyncafn", 46 | "body": [ 47 | "const $1 = async $2($3) => {", 48 | " $4", 49 | "}" 50 | ] 51 | }, 52 | "RSC client component": { 53 | "description": "Create a RSC client component", 54 | "prefix": "ucl", 55 | "body": "'use client'" 56 | }, 57 | "RSC server component": { 58 | "description": "Create a RSC server component", 59 | "prefix": "usl", 60 | "body": "'use server'" 61 | }, 62 | "useState": { 63 | "description": "Create a useState hook", 64 | "prefix": "ust", 65 | "body": [ 66 | "const [$1, set$2] = React.useState$3($4)" 67 | ] 68 | }, 69 | "useEffect": { 70 | "description": "Create a useEffect hook", 71 | "prefix": "uef", 72 | "body": [ 73 | "React.useEffect(() => {", 74 | " $1", 75 | "}, [$2])" 76 | ] 77 | }, 78 | "Import React": { 79 | "description": "Import React", 80 | "prefix": "iar", 81 | "body": "import * as React from 'react'" 82 | }, 83 | "Import zod": { 84 | "description": "Import zod", 85 | "prefix": "iz", 86 | "body": "import {z} from 'zod'" 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /.config/nvim/stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | indent_width = 4 3 | quote_style = "AutoPreferDouble" 4 | call_parentheses = "Always" 5 | 6 | [sort_requires] 7 | enabled = true 8 | -------------------------------------------------------------------------------- /.config/obsidian/.vimrc: -------------------------------------------------------------------------------- 1 | nmap j gj 2 | nmap k gk 3 | 4 | set clipboard=unnamed 5 | -------------------------------------------------------------------------------- /.config/obsidian/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "readableLineLength": false, 3 | "showLineNumber": true, 4 | "showIndentGuide": false, 5 | "autoPairBrackets": false, 6 | "vimMode": true 7 | } -------------------------------------------------------------------------------- /.config/obsidian/appearance.json: -------------------------------------------------------------------------------- 1 | { 2 | "accentColor": "#437e91", 3 | "cssTheme": "Rose Pine", 4 | "interfaceFontFamily": "Inter", 5 | "textFontFamily": "JetBrainsMonoNL Nerd Font Mono", 6 | "monospaceFontFamily": "JetBrainsMonoNL Nerd Font Mono", 7 | "translucency": false, 8 | "theme": "system" 9 | } -------------------------------------------------------------------------------- /.config/obsidian/community-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "obsidian-vimrc-support", 3 | "obsidian-excalidraw-plugin", 4 | "obsidian-relative-line-numbers" 5 | ] -------------------------------------------------------------------------------- /.config/obsidian/core-plugins.json: -------------------------------------------------------------------------------- 1 | { 2 | "file-explorer": true, 3 | "global-search": true, 4 | "switcher": true, 5 | "graph": true, 6 | "backlink": true, 7 | "canvas": true, 8 | "outgoing-link": true, 9 | "tag-pane": true, 10 | "properties": false, 11 | "page-preview": true, 12 | "daily-notes": true, 13 | "templates": true, 14 | "note-composer": true, 15 | "command-palette": true, 16 | "slash-command": false, 17 | "editor-status": true, 18 | "bookmarks": true, 19 | "markdown-importer": false, 20 | "zk-prefixer": false, 21 | "random-note": false, 22 | "outline": true, 23 | "word-count": true, 24 | "slides": false, 25 | "audio-recorder": false, 26 | "workspaces": false, 27 | "file-recovery": true, 28 | "publish": false, 29 | "sync": true, 30 | "webviewer": false 31 | } -------------------------------------------------------------------------------- /.config/obsidian/themes/Rose Pine/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Rose Pine", 3 | "version": "0.1.5", 4 | "minAppVersion": "1.0.0", 5 | "author": "rose-pine", 6 | "authorUrl": "https://github.com/JTrenerry" 7 | } 8 | -------------------------------------------------------------------------------- /.config/tmux-sessionizer/default: -------------------------------------------------------------------------------- 1 | tmux neww -n scratch 2 | tmux prev 3 | tmux renamew vim 4 | -------------------------------------------------------------------------------- /.config/tmux-sessionizer/directories: -------------------------------------------------------------------------------- 1 | ~/dev 2 | ~/dev/** 3 | ~/dev/playground/** 4 | ~/dev/playground/**/** 5 | ~/courses/** 6 | ~ 7 | -------------------------------------------------------------------------------- /.config/tmux/bin/toggle-theme.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Toggle the current window (all panes) between light and dark themes. 4 | set -e 5 | 6 | dark_status_style='fg=#c5c9c5,bg=#282727' 7 | light_status_style='fg=black,bg=#cfc1ba' 8 | 9 | current_status_style=$(tmux show -Av status-style) 10 | 11 | case $current_status_style in 12 | "$dark_status_style"|'default') 13 | # Change to the alternate window style. 14 | tmux set status-style $light_status_style 15 | tmux set pane-border-style $light_status_style 16 | tmux set pane-active-border-style $light_status_style 17 | ;; 18 | *) 19 | # Change back to the default window style. 20 | tmux set status-style $dark_status_style 21 | tmux set pane-border-style $dark_status_style 22 | tmux set pane-active-border-style $dark_status_style 23 | ;; 24 | esac 25 | -------------------------------------------------------------------------------- /.config/tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | # Enable Colours 2 | # set -g default-terminal 'tmux-256color' 3 | 4 | # enable full colors if TERM outside is xterm-256color 5 | # this is required for using nvim's :set termguicolors 6 | # set-option -sa terminal-overrides ',xterm-256color:RGB' 7 | # set-option -sa terminal-overrides ',screen-256color:RGB' 8 | 9 | # Global options 10 | set -s escape-time 0 11 | set -g bell-action none 12 | set -g base-index 1 13 | set -g detach-on-destroy off 14 | set -g allow-passthrough on 15 | set -g history-limit 50000 16 | set -g display-time 4000 17 | set -g status-interval 5 18 | set -g focus-events on 19 | 20 | # Copy mode 21 | set -g mode-style "fg=yellow,bg=default,reverse" 22 | set-hook -g after-copy-mode 'set -p cursor-color white' 23 | 24 | # Status bar styles 25 | set -g window-style 'bg=default' 26 | set -g window-active-style 'bg=default' 27 | set -g status-style 'fg=#c5c9c5,bg=#282727' 28 | set -g status-left-length 25 29 | set -g status-left ' #[bg=default][#S] ' 30 | set -g status-right "#(cut -d "." -f 1 <<< "#H") | %a %d %b - %H:%M " 31 | 32 | # pane border 33 | set-option -g pane-border-style 'fg=red,bg=default' 34 | set-option -g pane-active-border-style 'fg=green,bg=default' 35 | 36 | # Map Default Prefix 37 | set -g prefix C-f 38 | unbind C-b 39 | bind-key C-f send-prefix 40 | 41 | # Split Windows 42 | unbind % 43 | bind | split-window -h 44 | unbind '"' 45 | bind - split-window -v 46 | 47 | # Reload Config 48 | unbind r 49 | bind r source-file ~/.config/tmux/tmux.conf 50 | 51 | # skip "kill-pane 1? (y/n)" prompt 52 | bind-key x kill-pane 53 | 54 | # Resize Panes 55 | bind -r up resize-pane -D 56 | bind -r down resize-pane -U 57 | bind -r right resize-pane -R 58 | bind -r left resize-pane -L 59 | bind -r C-m resize-pane -Z 60 | bind C-p previous-window 61 | bind C-n next-window 62 | 63 | # vim-like pane switching 64 | bind -r ^ last-window 65 | bind -r k select-pane -U 66 | bind -r j select-pane -D 67 | bind -r h select-pane -L 68 | bind -r l select-pane -R 69 | 70 | # Previous session 71 | bind -r L switch-client -l 72 | 73 | # Prompt styles 74 | set -ag message-style 'fg=black bg=magenta' 75 | 76 | # Enable Mouse 77 | set -g mouse on 78 | 79 | # Terminal Scrollback 80 | set -g history-limit 50000 81 | 82 | # Focus events enabled for terminals that support them 83 | set -g focus-events on 84 | 85 | # Enable xterm keys 86 | set -g xterm-keys on 87 | 88 | # Enable tmux command line vim motions 89 | set -g status-keys vi 90 | 91 | # Enable VIM motions 92 | set-window-option -g mode-keys vi 93 | bind-key -T copy-mode-vi 'v' send -X begin-selection 94 | bind-key -T copy-mode-vi 'y' send -X copy-selection 95 | 96 | # Enable Mouse Dragging 97 | unbind -T copy-mode-vi MouseDragEnd1Pane 98 | 99 | # Shell commands 100 | bind-key -r e run-shell "~/.config/tmux/bin/toggle-theme.sh" 101 | bind-key -r S run-shell "tmux neww -S -n tmux-sessionizer tmux-sessionizer" 102 | bind-key -r B run-shell "~/.config/bin/tmux-sessionizer ~/.dotfiles" 103 | 104 | # T Smart tmux session manager options 105 | set -g @t-fzf-find-binding 'ctrl-f:change-prompt( )+reload(fd -H -d 3 -t d . ~)' 106 | 107 | set -g @plugin 'tmux-plugins/tpm' 108 | set -g @plugin 'tmux-plugins/tmux-resurrect' 109 | set -g @plugin 'christoomey/vim-tmux-navigator' 110 | 111 | run '$HOMEBREW_PREFIX/opt/tpm/share/tpm/tpm' 112 | -------------------------------------------------------------------------------- /.config/wezterm/.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", 3 | "workspace.checkThirdParty": false, 4 | "diagnostics": { 5 | "disable": [ "deprecated", "missing-fields" ] 6 | }, 7 | "format": { 8 | "enable": true, 9 | "defaultConfig": { 10 | "indent_size": "2", 11 | "tab_width": "2", 12 | "quote_style": "single", 13 | "call_arg_parentheses": "keep", 14 | "trailing_table_separator": "smart", 15 | "space_around_table_field_list": "false", 16 | "space_before_attribute": "false", 17 | "space_inside_square_brackets": "false", 18 | "align_call_args": "false", 19 | "align_function_params": "false", 20 | "align_continuous_assign_statement": "false", 21 | "align_continuous_rect_table_field": "false", 22 | "align_if_branch": "false", 23 | "align_array_table": "false" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.config/wezterm/colors/kanagawa.lua: -------------------------------------------------------------------------------- 1 | local theme_names = { 2 | light = 'kanagawa_light', 3 | dark = 'kanagawa_dark', 4 | } 5 | 6 | return { 7 | dark = theme_names.dark, 8 | light = theme_names.light, 9 | 10 | color_schemes = { 11 | [theme_names.dark] = { 12 | foreground = '#c5c9c5', 13 | background = '#000000', 14 | 15 | cursor_bg = '#c8c093', 16 | cursor_fg = '#c8c093', 17 | cursor_border = '#c8c093', 18 | 19 | selection_fg = '#c8c093', 20 | selection_bg = '#2d4f67', 21 | 22 | scrollbar_thumb = '#16161d', 23 | split = '#16161d', 24 | 25 | ansi = { 26 | '#0d0c0c', -- black 27 | '#c4746e', -- red 28 | '#8a9a7b', -- green 29 | '#c4b28a', -- yellow 30 | '#8ba4b0', -- blue 31 | '#a292a3', -- magenta 32 | '#8ea4a2', -- cyan 33 | '#c8c093', -- white 34 | }, 35 | 36 | brights = { 37 | '#a6a69c', -- black 38 | '#E46876', -- red 39 | '#87a987', -- green 40 | '#E6C384', -- yellow 41 | '#7FB4CA', -- blue 42 | '#938AA9', -- magenta 43 | '#7AA89F', -- cyan 44 | '#c5c9c5', -- white 45 | }, 46 | 47 | indexed = {[16] = '#b6927b', [17] = '#b98d7b'}, 48 | }, 49 | 50 | [theme_names.light] = { 51 | foreground = '#545464', 52 | background = '#f0edec', 53 | 54 | cursor_fg = '#f2ecbc', 55 | cursor_bg = '#43436c', 56 | cursor_border = '#c8c093', 57 | 58 | selection_fg = '#43436c', 59 | selection_bg = '#c9cbd1', 60 | 61 | scrollbar_thumb = '#16161d', 62 | split = '#16161d', 63 | 64 | ansi = { 65 | '#1f1f28', -- black 66 | '#c84053', -- red 67 | '#6f894e', -- green 68 | '#77713f', -- yellow 69 | '#4d699b', -- blue 70 | '#b35b79', -- magenta 71 | '#597b75', -- cyan 72 | '#545464', -- white 73 | }, 74 | 75 | brights = { 76 | '#8a8980', -- black 77 | '#d7474b', -- red 78 | '#6e915f', -- green 79 | '#836f4a', -- yellow 80 | '#6693bf', -- blue 81 | '#624c83', -- magenta 82 | '#5e857a', -- cyan 83 | '#43436c', -- white 84 | }, 85 | 86 | indexed = {[16] = '#cc6d00', [17] = '#e82424'}, 87 | }, 88 | }, 89 | } 90 | -------------------------------------------------------------------------------- /.config/wezterm/fonts.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---@param fontFamily 'sf' | 'jetbrains' | 'fira' | 'hack' | 'literation' | 'geist' 4 | M.getFonts = function(fontFamily) 5 | local families = { 6 | sf = { 7 | family = 'SFMono Nerd Font', 8 | weight = 'Regular', 9 | italic = false, 10 | stretch = 'Normal', 11 | }, 12 | jetbrains = { 13 | family = 'JetBrainsMono Nerd Font', 14 | weight = 'Regular', 15 | italic = false, 16 | stretch = 'Normal', 17 | }, 18 | fira = { 19 | family = 'FiraCode Nerd Font', 20 | weight = 'Regular', 21 | italic = false, 22 | stretch = 'Normal', 23 | }, 24 | hack = { 25 | family = 'Hack Nerd Font', 26 | weight = 400, 27 | italic = false, 28 | stretch = 'Normal', 29 | }, 30 | literation = { 31 | family = 'LiterationMono Nerd Font', 32 | weight = 450, 33 | italic = false, 34 | stretch = 'Normal', 35 | }, 36 | geist = { 37 | family = 'GeistMono Nerd Font', 38 | weight = 400, 39 | italic = false, 40 | stretch = 'Normal', 41 | }, 42 | } 43 | 44 | local fonts = {} 45 | for family, font in pairs(families) do 46 | if family ~= fontFamily then 47 | table.insert(fonts, font) 48 | end 49 | end 50 | 51 | table.insert(fonts, 1, families[fontFamily]) 52 | table.insert(fonts, {family = 'Apple Color Emoji'}) 53 | return fonts 54 | end 55 | 56 | return M 57 | -------------------------------------------------------------------------------- /.config/wezterm/utils/keys.lua: -------------------------------------------------------------------------------- 1 | local act = require('wezterm').action 2 | local M = {} 3 | 4 | M.key_table = function(mods, key, action) 5 | return {mods = mods, key = key, action = action} 6 | end 7 | 8 | M.cmd_key = function(key, action) 9 | return M.key_table('CMD', key, action) 10 | end 11 | 12 | ---@param tmux_key string 13 | ---@param tmux_mods? string 14 | M.send_tmux_key = function(tmux_key, tmux_mods) 15 | return act.Multiple({ 16 | act.SendKey({mods = 'CTRL', key = 'f'}), 17 | act.SendKey({mods = tmux_mods, key = tmux_key}), 18 | }) 19 | end 20 | 21 | ---@alias KeyToTmux {mods: string, key: string, tmux_key: string, tmux_mods?: string} 22 | ---@param opts KeyToTmux 23 | M.key_to_tmux = function(opts) 24 | return M.key_table(opts.mods, opts.key, M.send_tmux_key(opts.tmux_key, opts.tmux_mods)) 25 | end 26 | 27 | return M 28 | -------------------------------------------------------------------------------- /.config/wezterm/wallpapers/vader.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gonstoll/dotfiles/4ced11d875e98498c366144536f9e275538e3794/.config/wezterm/wallpapers/vader.jpg -------------------------------------------------------------------------------- /.config/wezterm/wezterm.lua: -------------------------------------------------------------------------------- 1 | local wezterm = require('wezterm') --[[@as Wezterm]] 2 | local act = wezterm.action 3 | local keys = require('utils.keys') 4 | local fonts = require('fonts') 5 | local kanagawa = require('colors.kanagawa') 6 | 7 | wezterm.on('toggle-kanagawa-theme', function(window) 8 | local overrides = window:get_config_overrides() or {} 9 | 10 | if not overrides.color_scheme then 11 | overrides.color_scheme = kanagawa.dark 12 | end 13 | 14 | if string.find(overrides.color_scheme, 'kanagawa') then 15 | overrides.color_scheme = overrides.color_scheme == kanagawa.dark and kanagawa.light or kanagawa.dark 16 | end 17 | 18 | window:set_config_overrides(overrides) 19 | end) 20 | 21 | wezterm.on('format-tab-title', function(tab) 22 | local title = tab.tab_title 23 | if not title or #title == 0 then 24 | title = tab.active_pane.title 25 | end 26 | return { 27 | {Text = ' [' .. tab.tab_index + 1 .. ':' .. title .. ']'}, 28 | } 29 | end) 30 | 31 | return { 32 | -- Font 33 | font = wezterm.font_with_fallback(fonts.getFonts('jetbrains')), 34 | font_size = 18.0, 35 | harfbuzz_features = {'calt=0', 'clig=0', 'liga=0'}, 36 | use_cap_height_to_scale_fallback_fonts = true, 37 | 38 | -- Colors 39 | color_schemes = kanagawa.color_schemes, 40 | color_scheme = kanagawa.dark, 41 | 42 | -- Window 43 | window_decorations = 'RESIZE', 44 | use_fancy_tab_bar = false, 45 | show_new_tab_button_in_tab_bar = false, 46 | hide_tab_bar_if_only_one_tab = true, 47 | tab_bar_at_bottom = true, 48 | tab_max_width = 26, 49 | window_frame = { 50 | font = wezterm.font_with_fallback(fonts.getFonts('sf')), 51 | font_size = 14.0, 52 | }, 53 | window_padding = { 54 | left = '10px', 55 | right = '10px', 56 | top = '10px', 57 | bottom = 0, 58 | }, 59 | initial_rows = 120, 60 | initial_cols = 350, 61 | enable_scroll_bar = false, 62 | 63 | -- Cursor 64 | cursor_blink_rate = 500, 65 | default_cursor_style = 'BlinkingBlock', 66 | cursor_blink_ease_in = 'Constant', 67 | cursor_blink_ease_out = 'Constant', 68 | force_reverse_video_cursor = true, 69 | 70 | -- Other 71 | underline_thickness = 3.0, 72 | max_fps = 240, 73 | term = 'wezterm', 74 | set_environment_variables = { 75 | TERMINFO_DIRS = '~/.terminfo/', 76 | }, 77 | 78 | -- Keymaps 79 | keys = { 80 | {key = 'c', mods = 'CMD|SHIFT', action = wezterm.action.ActivateCopyMode}, 81 | 82 | -- Pane navigation 83 | -- {key = 'd', mods = 'CMD', action = wezterm.action.SplitPane({direction = 'Right', size = {Percent = 50}})}, 84 | {key = 'd', mods = 'CMD|SHIFT', action = wezterm.action.SplitPane({direction = 'Down', size = {Percent = 50}})}, 85 | {key = 'w', mods = 'CMD', action = wezterm.action.CloseCurrentPane({confirm = true})}, 86 | {key = 'h', mods = 'CTRL|CMD', action = act.ActivatePaneDirection('Left')}, 87 | {key = 'l', mods = 'CTRL|CMD', action = act.ActivatePaneDirection('Right')}, 88 | {key = 'k', mods = 'CTRL|CMD', action = act.ActivatePaneDirection('Up')}, 89 | {key = 'j', mods = 'CTRL|CMD', action = act.ActivatePaneDirection('Down')}, 90 | {key = 'LeftArrow', mods = 'CTRL|CMD', action = act.AdjustPaneSize({'Left', 1})}, 91 | {key = 'RightArrow', mods = 'CTRL|CMD', action = act.AdjustPaneSize({'Right', 1})}, 92 | {key = 'UpArrow', mods = 'CTRL|CMD', action = act.AdjustPaneSize({'Up', 1})}, 93 | {key = 'DownArrow', mods = 'CTRL|CMD', action = act.AdjustPaneSize({'Down', 1})}, 94 | 95 | -- tmux 96 | {key = 'e', mods = 'CMD', action = act.Multiple({act.EmitEvent('toggle-gruvbox-theme'), keys.send_tmux_key('e')})}, -- Toggle wezterm and tmux theme 97 | {key = 'k', mods = 'CMD', action = act.Multiple({act.EmitEvent('toggle-kanagawa-theme'), keys.send_tmux_key('e')})}, -- Toggle wezterm and tmux theme 98 | keys.key_to_tmux({mods = 'CMD', key = 's', tmux_key = 'S'}), -- Open tmux-sessionizer 99 | keys.key_to_tmux({mods = 'CMD', key = 'j', tmux_key = 'T'}), -- Open t - tmux smart session manager 100 | keys.key_to_tmux({mods = 'CMD', key = 'b', tmux_key = 'B'}), -- Open dotfiles session 101 | }, 102 | } 103 | -------------------------------------------------------------------------------- /.config/yazi/theme.toml: -------------------------------------------------------------------------------- 1 | [manager] 2 | find_keyword = {bg = "black", fg = "red", reversed = true} 3 | 4 | marker_copied = {fg = "green", bg = "green"} 5 | marker_cut = {fg = "red", bg = "red"} 6 | marker_marked = {fg = "magenta", bg = "magenta"} 7 | marker_selected = {fg = "cyan", bg = "cyan"} 8 | 9 | cwd = {fg = "yellow"} 10 | hovered = {reversed = true} 11 | preview_hovered = {reversed = true} 12 | 13 | tab_active = {reversed = true} 14 | tab_inactive = {} 15 | tab_width = 1 16 | 17 | count_copied = {fg = "black", bg = "green"} 18 | count_cut = {fg = "black", bg = "red"} 19 | count_selected = {fg = "black", bg = "yellow"} 20 | 21 | border_style = {fg = "white"} 22 | 23 | [status] 24 | separator_open = "" 25 | separator_close = "" 26 | separator_style = {fg = "reset", bg = "reset"} 27 | 28 | mode_normal = {fg = "blue", bg = "reset"} 29 | mode_select = {fg = "magenta", bg = "reset"} 30 | mode_unset = {fg = "yellow", bg = "reset"} 31 | 32 | progress_label = {fg = "blue", bg = "black", bold = true} 33 | progress_normal = {fg = "darkgrey", bg = "black"} 34 | progress_error = {fg = "darkgrey", bg = "black"} 35 | 36 | permissions_t = {fg = "green"} 37 | permissions_r = {fg = "yellow"} 38 | permissions_w = {fg = "red"} 39 | permissions_x = {fg = "cyan"} 40 | permissions_s = {fg = "magenta"} 41 | 42 | [select] 43 | border = {fg = "blue"} 44 | active = {fg = "magenta"} 45 | inactive = {} 46 | -------------------------------------------------------------------------------- /.config/yazi/yazi.toml: -------------------------------------------------------------------------------- 1 | # A TOML linter such as https://taplo.tamasfe.dev/ can use this schema to validate your config. 2 | # If you encounter any issues, please make an issue at https://github.com/yazi-rs/schemas. 3 | "$schema" = "https://yazi-rs.github.io/schemas/yazi.json" 4 | 5 | # general 6 | [manager] 7 | show_hidden = true 8 | ratio = [2, 2, 4] 9 | -------------------------------------------------------------------------------- /.config/zsh/.zprofile: -------------------------------------------------------------------------------- 1 | eval "$(/opt/homebrew/bin/brew shellenv)" 2 | 3 | # Added by OrbStack: command-line tools and integration 4 | source ~/.orbstack/shell/init.zsh 2>/dev/null || : 5 | -------------------------------------------------------------------------------- /.config/zsh/.zshrc: -------------------------------------------------------------------------------- 1 | autoload -U colors && colors 2 | 3 | if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then 4 | source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" 5 | fi 6 | 7 | LANG=en_US.UTF-8 8 | 9 | # Configs 10 | source $ZDOTDIR/config/options.zsh 11 | source $ZDOTDIR/config/aliases.zsh 12 | if [[ -f $ZDOTDIR/config/custom.zsh ]]; then 13 | source $ZDOTDIR/config/custom.zsh 14 | fi 15 | 16 | # tmux messes up LS colors, reset to default 17 | [[ ! -z $TMUX ]] && unset LS_COLORS 18 | 19 | # Completions 20 | if type brew &>/dev/null; then 21 | FPATH=$(brew --prefix)/share/zsh-completions:$FPATH 22 | fi 23 | 24 | # History 25 | HISTFILE=$ZDOTDIR/.zsh_history 26 | HISTSIZE=1100000000 27 | SAVEHIST=1000000000 28 | bindkey "^[[A" history-search-backward 29 | bindkey "^[[B" history-search-forward 30 | 31 | # Disable the highlighting of text pasted into the terminal. 32 | zle_highlight=('paste:none') 33 | 34 | autoload -U +X compinit 35 | zstyle ':completion:*' menu select 36 | zmodload zsh/complist 37 | compinit 38 | _comp_options+=(globdots) 39 | 40 | # Vi mode 41 | bindkey -v 42 | 43 | # Use vim keys in tab complete menu (2nd tab press): 44 | bindkey -M menuselect 'h' vi-backward-char 45 | bindkey -M menuselect 'k' vi-up-line-or-history 46 | bindkey -M menuselect 'l' vi-forward-char 47 | bindkey -M menuselect 'j' vi-down-line-or-history 48 | 49 | # By default backspace (^?) is bound to `vi-backward-delete-char` 50 | # we want it to have the same bahvior as vim/nvim (i.e. backspace=del) 51 | # without the below we will get stuck unable to backspace after Esc-k-A 52 | bindkey -v '^?' backward-delete-char 53 | 54 | # Better searching in vi command mode 55 | bindkey -M vicmd '/' history-incremental-search-forward 56 | bindkey -M vicmd '?' history-incremental-search-backward 57 | bindkey -M vicmd '^r' history-incremental-search-backward 58 | bindkey -M viins '^r' history-incremental-search-backward 59 | 60 | # Start tmux-sessionizer: 61 | # Terminal binds cmd+s to Ctrl-f+s. This binds Ctrl-f+s to `s` which is an 62 | # alias for tmux-sessionizer) 63 | bindkey -s "^FS" "s\n" 64 | 65 | source $HOMEBREW_PREFIX/share/powerlevel10k/powerlevel10k.zsh-theme 66 | 67 | # To customize prompt, run `p10k configure` or edit ~/.config/zsh//.p10k.zsh. 68 | if [[ -f $ZDOTDIR/.p10k.zsh ]]; then 69 | source $ZDOTDIR/.p10k.zsh 70 | fi 71 | 72 | # Load bun 73 | if [[ -s "$HOME/.config/bun/_bun" ]]; then 74 | source "$HOME/.config/bun/_bun" 75 | fi 76 | 77 | # Load rust 78 | if [[ -s "$XDG_CONFIG_HOME/rust/.cargo/env" ]]; then 79 | source "$XDG_CONFIG_HOME/rust/.cargo/env" 80 | fi 81 | 82 | source $HOMEBREW_PREFIX/share/zsh-autosuggestions/zsh-autosuggestions.zsh 83 | 84 | # Zoxide 85 | eval "$(zoxide init zsh)" 86 | 87 | # Fzf 88 | source $ZDOTDIR/fzf 89 | source <(fzf --zsh) 90 | 91 | # Edit command line in vim 92 | autoload -U edit-command-line 93 | zle -N edit-command-line 94 | bindkey "^X^E" edit-command-line 95 | 96 | # Use fzf for history search 97 | # bindkey '^R' fzf-history-widget 98 | 99 | # Loading syntax highlighting last on purpose 100 | source $(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh 101 | 102 | # Load nvm if present 103 | if [ -s "$NVM_DIR/nvm.sh" ]; then 104 | source "$NVM_DIR/nvm.sh" 105 | fi 106 | 107 | # Functions 108 | source $ZDOTDIR/functions 109 | 110 | # Set up neovim as the default editor. 111 | export EDITOR="$(which nvim)" 112 | export VISUAL="$EDITOR" 113 | export GIT_EDITOR="$EDITOR" 114 | -------------------------------------------------------------------------------- /.config/zsh/config/aliases.zsh: -------------------------------------------------------------------------------- 1 | # Fzf 2 | alias fd="cd \$(find . -type d | fzf)" # cd into a directory 3 | 4 | # Git 5 | alias lg="lazygit" 6 | alias g="git" 7 | 8 | # Neovim 9 | alias vim="nvim" 10 | alias vi="nvim" 11 | 12 | # Navigation 13 | alias ..="cd .. && cd .." 14 | 15 | # MySQL 16 | alias mysql=/usr/local/mysql/bin/mysql 17 | alias mysqladmin=/usr/local/mysql/bin/mysqladmin 18 | 19 | # Tmux 20 | alias s="tmux-sessionizer" 21 | alias tn="tmux new -s $(pwd | sed 's/.*\///g')" 22 | 23 | # Eza (better ls) 24 | alias ls="eza --icons=always" 25 | 26 | # Docker 27 | alias ld="lazydocker" 28 | -------------------------------------------------------------------------------- /.config/zsh/config/options.zsh: -------------------------------------------------------------------------------- 1 | setopt extendedglob 2 | setopt nocaseglob 3 | setopt rcexpandparam 4 | setopt nobeep 5 | setopt appendhistory 6 | setopt inc_append_history 7 | setopt histignorealldups 8 | setopt autocd 9 | setopt histignorespace 10 | setopt share_history 11 | setopt hist_expire_dups_first 12 | setopt hist_ignore_dups 13 | setopt hist_verify 14 | # set -o vi 15 | 16 | # "If a completion is performed with the cursor within a word, and a 17 | # full completion is inserted, the cursor is moved to the end of the 18 | # word." 19 | # https://zsh.sourceforge.io/Doc/Release/Options.html#Completion-4 20 | setopt always_to_end 21 | 22 | # "If the internal history needs to be trimmed to add the current 23 | # command line, setting this option will cause the oldest history 24 | # event that has a duplicate to be lost before losing a unique event 25 | # from the list." 26 | # https://zsh.sourceforge.io/Doc/Release/Options.html#History 27 | setopt hist_expire_dups_first 28 | 29 | # "When searching for history entries in the line editor, do not 30 | # display duplicates of a line previously found, even if the 31 | # duplicates are not contiguous." 32 | # https://zsh.sourceforge.io/Doc/Release/Options.html#History 33 | setopt hist_find_no_dups 34 | 35 | # "Turns on interactive comments; comments begin with a #." 36 | # https://zsh.sourceforge.io/Intro/intro_16.html 37 | # 38 | # That is, enable comments in the terminal. Nice when copying and 39 | # pasting from documentation/tutorials, and disable part of 40 | # a command pulled up from history. 41 | setopt interactivecomments 42 | -------------------------------------------------------------------------------- /.config/zsh/functions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Header logging 4 | function print_header() { 5 | printf "\n$(tput setaf 7)%s$(tput sgr0)\n" "$@" 6 | } 7 | 8 | # Success logging 9 | function print_success() { 10 | printf "$(tput setaf 65) $(tput sgr0) %s\n" "$@" 11 | } 12 | 13 | # Error logging 14 | function print_error() { 15 | printf "$(tput setaf 1) $(tput sgr0) %s\n" "$@" 16 | } 17 | 18 | # Warning logging 19 | function print_warning() { 20 | printf "$(tput setaf 137) $(tput sgr0) %s\n" "$@" 21 | } 22 | 23 | # Use fzf to view and focus on aerospace windows 24 | function ff() { 25 | aerospace list-windows --all | fzf --bind 'enter:execute(bash -c "aerospace focus --window-id {1}")+abort' 26 | } 27 | 28 | # Yazi (file manager system) 29 | # Use y to change the current directory when exiting yazi 30 | function y() { 31 | local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" 32 | yazi "$@" --cwd-file="$tmp" 33 | if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then 34 | cd -- "$cwd" 35 | fi 36 | rm -f -- "$tmp" 37 | } 38 | 39 | # Advanced customization of fzf options via _fzf_comprun function 40 | # - The first argument to the function is the name of the command. 41 | # - You should make sure to pass the rest of the arguments to fzf. 42 | function _fzf_comprun() { 43 | local command=$1 44 | shift # Remove the first argument of the function 45 | case "$command" in 46 | cd) fzf --preview 'eza --tree --color=always {} | head -200' "$@" ;; 47 | export|unset) fzf --preview "eval 'echo \${}'" "$@" ;; 48 | ssh) fzf --preview 'dig {}' "$@" ;; 49 | *) fzf --preview "$show_file_or_dir_preview" "$@" ;; 50 | esac 51 | } 52 | -------------------------------------------------------------------------------- /.config/zsh/fzf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Setup fzf 4 | # --------- 5 | if [[ ! "$PATH" == */opt/homebrew/opt/fzf/bin* ]]; then 6 | PATH="${PATH:+${PATH}:}/opt/homebrew/opt/fzf/bin" 7 | fi 8 | 9 | # Auto-completion 10 | # --------------- 11 | if [[ $- == *i* ]]; then 12 | source "/opt/homebrew/opt/fzf/shell/completion.zsh" 2> /dev/null 13 | fi 14 | 15 | # Key bindings 16 | # ------------ 17 | source "/opt/homebrew/opt/fzf/shell/key-bindings.zsh" 18 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [alias] 2 | aco = add -A && commit -m 3 | a = "!git add ." 4 | d = diff 5 | co = checkout 6 | ci = commit 7 | ps = "!git push origin $(git rev-parse --abbrev-ref HEAD)" 8 | pl = "!git pull origin $(git rev-parse --abbrev-ref HEAD)" 9 | st = status 10 | br = branch 11 | undo = reset --soft HEAD~1 12 | [pull] 13 | rebase = false 14 | [push] 15 | autoSetupRemote = true 16 | [core] 17 | editor = "nvim" 18 | ignorecase = false 19 | excludesfile = ~/.gitignore_global 20 | [user] 21 | name = Gonzalo Stoll 22 | email = stollgonzalo@gmail.com 23 | [github] 24 | user = gonstoll 25 | [rerere] 26 | enable = true 27 | [init] 28 | defaultBranch = master 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # zsh 4 | .histfile 5 | .zcompdump 6 | .zsh_* 7 | .z_database 8 | custom.zsh 9 | 10 | # Wallpapers 11 | other/images/wallpapers/images/*/*.jpg 12 | other/images/wallpapers/images/*/*.png 13 | other/images/wallpapers/images/*/*.jpeg 14 | !other/images/wallpapers/images/*/output.heic 15 | 16 | # .config dirs 17 | .config/bun 18 | .config/configstore 19 | .config/fontforge 20 | .config/github-copilot 21 | .config/planetscale 22 | .config/raycast 23 | .config/rust 24 | .config/gh 25 | .config/gh-copilot 26 | .config/nvm 27 | .config/go 28 | .config/dlv 29 | 30 | # iTerm2 31 | .config/iTerm2/* 32 | !.config/iTerm2/com.googlecode.iterm2.plist 33 | Library/Application Support/iTerm2/* 34 | !Library/Application Support/iTerm2/DynamicProfiles 35 | 36 | # tmux 37 | .config/tmux/plugins/* 38 | 39 | # Obsidian 40 | .config/obsidian/plugins/* 41 | .config/obsidian/workspace 42 | .config/obsidian/workspace.json 43 | .config/obsidian/types.json 44 | .config/obsidian/graph.json 45 | -------------------------------------------------------------------------------- /.gitignore_global: -------------------------------------------------------------------------------- 1 | .tmux-sessionizer 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "other/images/wallpapers/wallpapper"] 2 | path = other/images/wallpapers/wallpapper 3 | url = https://github.com/mczachurski/wallpapper.git 4 | -------------------------------------------------------------------------------- /.stow-local-ignore: -------------------------------------------------------------------------------- 1 | # Comments and blank lines are allowed. 2 | 3 | RCS 4 | .+,v 5 | 6 | CVS 7 | \.\#.+ # CVS conflict files / emacs lock files 8 | \.cvsignore 9 | 10 | \.svn 11 | _darcs 12 | \.hg 13 | 14 | \.git 15 | \.gitignore 16 | \.gitmodules 17 | 18 | .+~ # emacs backup files 19 | \#.*\# # emacs autosave files 20 | 21 | ^/README.* 22 | ^/LICENSE.* 23 | ^/COPYING 24 | 25 | Brewfile 26 | other 27 | -------------------------------------------------------------------------------- /.vimrc: -------------------------------------------------------------------------------- 1 | syntax on 2 | set termguicolors 3 | set nu 4 | set rnu 5 | set rtp+=/opt/homebrew/opt/fzf 6 | set clipboard+=unnamedplus 7 | set cursorline! 8 | set shiftwidth=2 9 | -------------------------------------------------------------------------------- /.zshenv: -------------------------------------------------------------------------------- 1 | # XDG base directories. 2 | export XDG_CACHE_HOME="$HOME/.cache" 3 | export XDG_CONFIG_HOME="$HOME/.config" 4 | 5 | # PATH 6 | export PATH="$HOME/.local/bin:$PATH" # Local scripts 7 | export PATH="$XDG_CONFIG_HOME/bin:$PATH" # Custom scripts 8 | export PATH="$XDG_CONFIG_HOME/tmux/bin:$PATH" # Tmux scripts 9 | export PATH="$XDG_CONFIG_HOME/rust/.cargo/bin:$PATH" # Cargo 10 | export PATH="$XDG_CONFIG_HOME/go/bin:$PATH" # Go binaries 11 | 12 | # Brew bundle file 13 | export HOMEBREW_BUNDLE_FILE="$HOME/.dotfiles/Brewfile" 14 | 15 | # zsh configuration. 16 | export ZDOTDIR="$XDG_CONFIG_HOME/zsh" 17 | 18 | # Man pages 19 | export MANPAGER='nvim +Man!' 20 | 21 | # Don't let Ghostty mess up with the cursor. 22 | export GHOSTTY_SHELL_INTEGRATION_NO_CURSOR=1 23 | 24 | # Rust 25 | export RUSTUP_HOME="$XDG_CONFIG_HOME/rust/.rustup" 26 | export CARGO_HOME="$XDG_CONFIG_HOME/rust/.cargo" 27 | 28 | # Go 29 | export GOPATH="$XDG_CONFIG_HOME/go" 30 | export GOBIN="$XDG_CONFIG_HOME/go/bin" 31 | 32 | # Bun 33 | export BUN_INSTALL="$HOME/.config/bun" 34 | export PATH="$BUN_INSTALL/bin:$PATH" 35 | 36 | # Bat 37 | export BAT_CONFIG_PATH="$HOME/.config/bat/bat.conf" 38 | 39 | # Fzf 40 | show_file_or_dir_preview="if [ -d {} ]; then eza --tree --color=always {} | head -200; else bat -n --color=always --line-range :500 {}; fi" 41 | export FZF_CTRL_T_OPTS="--preview '$show_file_or_dir_preview'" 42 | 43 | # Set 1ms timeout for Esc press so we can switch 44 | # between vi "normal" and "command" modes faster 45 | export KEYTIMEOUT=1 46 | 47 | # nvm 48 | export NVM_DIR="$XDG_CONFIG_HOME/nvm" 49 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | tap "homebrew/bundle" 2 | tap "homebrew/services" 3 | tap "dotenvx/brew" 4 | tap "jesseduffield/lazygit" 5 | tap "jesseduffield/lazydocker/lazydocker" 6 | tap "libsql/sqld" 7 | tap "planetscale/tap" 8 | tap "tursodatabase/tap" 9 | tap "epk/epk" 10 | tap "FelixKratz/formulae" 11 | 12 | brew "bat" 13 | brew "borders" 14 | brew "btop" 15 | brew "delve" 16 | brew "dotenvx/brew/dotenvx" 17 | brew "python@3.12" 18 | brew "efm-langserver" 19 | brew "eza" 20 | brew "fd" 21 | brew "fzf" 22 | brew "gh" 23 | brew "git" 24 | brew "gnu-sed" 25 | brew "gum" 26 | brew "imagemagick" 27 | brew "jesseduffield/lazygit/lazygit" 28 | brew "jq" 29 | brew "luarocks" 30 | brew "neofetch" 31 | brew "neovim" 32 | brew "node" 33 | brew "php", restart_service: true 34 | brew "planetscale/tap/pscale" 35 | brew "pnpm" 36 | brew "powerlevel10k" 37 | brew "ripgrep" 38 | brew "shellcheck" 39 | brew "stow" 40 | brew "tldr" 41 | brew "tmux" 42 | brew "tree-sitter" 43 | brew "tursodatabase/tap/turso" 44 | brew "tokei" 45 | brew "tpm" 46 | brew "viu" 47 | brew "yazi" 48 | brew "zig" 49 | brew "zoxide" 50 | brew "zsh-autosuggestions" 51 | brew "zsh-completions" 52 | brew "zsh-syntax-highlighting" 53 | 54 | cask "arc" 55 | cask "font-fira-code-nerd-font" 56 | cask "font-geist-mono-nerd-font" 57 | cask "font-jetbrains-mono-nerd-font" 58 | cask "font-sf-mono-nerd-font" 59 | cask "ghostty" 60 | cask "keycastr" 61 | cask "nikitabobko/tap/aerospace" 62 | cask "obsidian" 63 | cask "raycast" 64 | -------------------------------------------------------------------------------- /Library/Application Support/Code/User/extensions: -------------------------------------------------------------------------------- 1 | adpyke.codesnap 2 | alefragnani.project-manager 3 | bierner.markdown-emoji 4 | bradlc.vscode-tailwindcss 5 | cev.overnight 6 | chad.nord-operator-theme 7 | dbaeumer.vscode-eslint 8 | eamodio.gitlens 9 | enkia.tokyo-night 10 | esbenp.prettier-vscode 11 | formulahendry.auto-close-tag 12 | formulahendry.auto-rename-tag 13 | github.copilot 14 | github.copilot-chat 15 | github.vscode-github-actions 16 | github.vscode-pull-request-github 17 | gruntfuggly.todo-tree 18 | illixion.vscode-vibrancy-continued 19 | joshbolduc.story-explorer 20 | madprops.nordico 21 | metaphore.kanagawa-vscode-color-theme 22 | mikestead.dotenv 23 | mvllow.rose-pine 24 | orta.vscode-twoslash-queries 25 | pkief.material-icon-theme 26 | pmndrs.pmndrs 27 | prisma.prisma 28 | sainnhe.gruvbox-material 29 | sanity-io.vscode-sanity 30 | sdras.night-owl 31 | shardulm94.trailing-spaces 32 | styled-components.vscode-styled-components 33 | visualstudioexptteam.intellicode-api-usage-examples 34 | visualstudioexptteam.vscodeintellicode 35 | vscodevim.vim 36 | wicked-labs.wvsc-serendipity 37 | yoavbls.pretty-ts-errors 38 | -------------------------------------------------------------------------------- /Library/Application Support/Code/User/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.startupEditor": "none", 3 | "window.zoomLevel": 1, 4 | "window.titleBarStyle": "custom", 5 | "workbench.panel.defaultLocation": "right", 6 | "workbench.colorTheme": "Rosé Pine Moon (no italics)", 7 | "workbench.iconTheme": "material-icon-theme", 8 | "workbench.editor.enablePreview": true, 9 | "workbench.colorCustomizations": { 10 | "editorCursor.background": "#ffffff", 11 | "terminalCursor.background": "#ffffff" 12 | }, 13 | "editor.fontSize": 15, 14 | "editor.fontFamily": "JetBrainsMonoNL Nerd Font Mono", 15 | "editor.lineHeight": 1.35, 16 | "editor.tabSize": 2, 17 | "editor.formatOnPaste": true, 18 | "editor.acceptSuggestionOnCommitCharacter": false, 19 | "editor.bracketPairColorization.enabled": false, 20 | "editor.suggest.snippetsPreventQuickSuggestions": false, 21 | "editor.accessibilitySupport": "off", 22 | "editor.rulers": [90], 23 | "editor.wordWrapColumn": 90, 24 | "editor.minimap.enabled": false, 25 | "editor.wordWrap": "wordWrapColumn", 26 | "editor.wrappingStrategy": "advanced", 27 | "editor.formatOnSave": true, 28 | "editor.inlineSuggest.enabled": true, 29 | "editor.quickSuggestions": {"strings": true}, 30 | "editor.defaultFormatter": "esbenp.prettier-vscode", 31 | "prettier.arrowParens": "avoid", 32 | "prettier.singleQuote": true, 33 | "prettier.bracketSpacing": false, 34 | "prettier.semi": false, 35 | "prettier.printWidth": 80, 36 | "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false, 37 | "typescript.preferences.quoteStyle": "double", 38 | "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false, 39 | "material-icon-theme.folders.color": "#0778d4", 40 | "material-icon-theme.folders.theme": "specific", 41 | "material-icon-theme.activeIconPack": "react_redux", 42 | "material-icon-theme.opacity": 1, 43 | "material-icon-theme.hidesExplorerArrows": false, 44 | "material-icon-theme.saturation": 0.7, 45 | "github.copilot.advanced": { 46 | "indentationMode": { 47 | "python": false, 48 | "javascript": false, 49 | "javascriptreact": false, 50 | "jsx": false, 51 | "typescript": false, 52 | "typescriptreact": false, 53 | "go": false, 54 | "ruby": false, 55 | "*": true 56 | } 57 | }, 58 | "github.copilot.enable": { 59 | "*": true, 60 | "yaml": false, 61 | "plaintext": false, 62 | "markdown": true, 63 | "scminput": false, 64 | "typescriptreact": true, 65 | "typescript": true 66 | }, 67 | "git.confirmSync": false, 68 | "[prisma]": { 69 | "editor.defaultFormatter": "Prisma.prisma" 70 | }, 71 | "security.workspace.trust.untrustedFiles": "open", 72 | "terminal.integrated.fontSize": 15, 73 | "notebook.output.wordWrap": true, 74 | "files.associations": {"*.css": "tailwindcss"}, 75 | "vim.useSystemClipboard": true, 76 | "vim.useCtrlKeys": true, 77 | "vim.leader": "", 78 | "vim.hlsearch": true, 79 | "vim.cursorStylePerMode.visualline": "block", 80 | "vim.cursorStylePerMode.visualblock": "block", 81 | "vim.cursorStylePerMode.replace": "block", 82 | "vim.cursorStylePerMode.insert": "block", 83 | "vim.highlightedyank.enable": true, 84 | "vim.highlightedyank.color": "#f2594b", 85 | "vim.highlightedyank.textColor": "#000000", 86 | "vim.enableNeovim": true 87 | } 88 | -------------------------------------------------------------------------------- /Library/Application Support/Code/User/snippets/javascript.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Print to console": { 3 | "scope": "javascript,typescript,javascriptreact,typescriptreact", 4 | "prefix": "logging", 5 | "body": ["console.log('logging $1', $1)"], 6 | "description": "Log output to console" 7 | }, 8 | "Export a function": { 9 | "scope": "javascript,typescript,javascriptreact,typescriptreact", 10 | "prefix": "efunc", 11 | "body": ["export function ${1:Function}() {$0}"], 12 | "description": "Exports a function" 13 | }, 14 | "Export an async function": { 15 | "scope": "javascript,typescript,javascriptreact,typescriptreact", 16 | "prefix": "eafunc", 17 | "body": ["export async function ${1:Function}() {$0}"], 18 | "description": "Exports an async function" 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /Library/Application Support/Code/User/snippets/react.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Import all react": { 3 | "scope": "javascriptreact,typescriptreact", 4 | "prefix": "iar", 5 | "body": ["import * as React from 'react'"], 6 | "description": "Imports React and all it's primitives" 7 | }, 8 | "Create a react component": { 9 | "scope": "javascriptreact,typescriptreact", 10 | "prefix": "react component", 11 | "body": [ 12 | "import * as React from 'react'", 13 | "", 14 | "export default function ${1:Component}() {", 15 | " return
$0", 16 | "}" 17 | ], 18 | "description": "Imports React and all it's primitives" 19 | }, 20 | "Create a react component with props": { 21 | "scope": "javascriptreact,typescriptreact", 22 | "prefix": "react component with props", 23 | "body": [ 24 | "import * as React from 'react'", 25 | "", 26 | "interface Props {", 27 | " ${2:prop}: ${3:string};", 28 | "}", 29 | "export default function ${1:Component}({${2:prop}}: Props) {", 30 | " return
$0", 31 | "}" 32 | ], 33 | "description": "Imports React and all it's primitives" 34 | }, 35 | "Import zod": { 36 | "scope": "javascriptreact,typescriptreact", 37 | "prefix": "izod", 38 | "body": ["import {z} from 'zod'"], 39 | "description": "Imports z from the zod package" 40 | }, 41 | "Use server": { 42 | "scope": "javascriptreact,typescriptreact", 43 | "prefix": "useserv", 44 | "body": ["'use server'", ""], 45 | "description": "Adds 'use server' RSC directive" 46 | }, 47 | "Use client": { 48 | "scope": "javascriptreact,typescriptreact", 49 | "prefix": "usecli", 50 | "body": ["'use client'", ""], 51 | "description": "Adds 'use client' RSC directive" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gonzalo Stoll's dotfiles 2 | 3 | Dotfiles screenshot 4 | 5 | These are my dotfiles. They are not meant to be used as is, but feel free to 6 | take whatever you want from them. 7 | 8 | ## Installation 9 | 10 | You can install these dotfiles in two ways: 11 | 12 | #### With cURL (recommended) 13 | 14 | Execute the following command: 15 | 16 | ```sh 17 | bash -c "$(curl -fsSL raw.github.com/gonstoll/dotfiles/master/.config/bin/dotfiles)" 18 | ``` 19 | 20 | #### Cloning the repository 21 | 22 | Clone the repository and execute the `dotfiles` script: 23 | 24 | ```sh 25 | git clone https://github.com/gonstoll/dotfiles.git ~/.dotfiles 26 | chmod +x ~/.dotfiles/.config/bin/dotfiles && ~/.dotfiles/config/bin/dotfiles 27 | ``` 28 | 29 | ## What does the installation script do? 30 | 31 | The script will guide you through the installation process. It will attempt to 32 | install [homebrew](https://brew.sh/), [git](https://git-scm.com/), sync its git 33 | submodules and link its packages by using [GNU 34 | Stow](https://www.gnu.org/software/stow/). 35 | 36 | It also supports having your own intial script that you wish to run after the 37 | dotfiles are installed. You can do this by having a `init_script` file in you 38 | $HOME directory. This file will be executed after the dotfiles are installed. 39 | This is useful for setting up some environment variables or installing some 40 | packages that are not included in the dotfiles. 41 | 42 | You can customize its installation by setting some flags: 43 | 44 | #### No homebrew and runtime packages 45 | 46 | This script installs all homebrew and runtime (`npm`, `bun`, `cargo`, etc.) 47 | packages. You can opt-out of this by setting the `--no-packages` flag: 48 | 49 | ```sh 50 | # First time installing: 51 | bash -c "$(curl -fsSL raw.github.com/gonstoll/dotfiles/master/.config/bin/dotfiles) -- --no-packages" 52 | 53 | # ...or after installation: 54 | dotfiles --no-packages 55 | ``` 56 | 57 | #### No git syncronization 58 | 59 | Git syncronization checks for updates in the dotfiles repository and installs 60 | its submodules. You can opt-out of this by setting the `--no-sync` flag: 61 | 62 | ```sh 63 | # First time installing: 64 | bash -c "$(curl -fsSL raw.github.com/gonstoll/dotfiles/master/.config/bin/dotfiles) -- --no-sync" 65 | 66 | # ...or after installation: 67 | dotfiles --no-sync 68 | ``` 69 | 70 | ## Acknowledgements 71 | 72 | A lot of inspiration for the architecture of these dotfiles came from: 73 | 74 | - [@necolas](https://github.com/necolas/dotfiles/tree/master) 75 | - [@typecraft](https://github.com/typecraft-dev/dotfiles) 76 | - [@andrew8088](https://github.com/andrew8088/dotfiles) 77 | -------------------------------------------------------------------------------- /other/images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gonstoll/dotfiles/4ced11d875e98498c366144536f9e275538e3794/other/images/screenshot.png -------------------------------------------------------------------------------- /other/images/wallpapers/README.md: -------------------------------------------------------------------------------- 1 | # Wallpapers 2 | 3 | Using [wallpapper](https://github.com/mczachurski/wallpapper) by mczachurski, this creates dynamic wallpapers for macOS. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | cd $HOME/.dotfiles/other/images/wallpapers/wallpapper/ 9 | ./build.sh 10 | sudo cp .output/wallpapper /usr/local/bin 11 | sudo cp .output/wallpapper-exif /usr/local/bin 12 | ``` 13 | 14 | ## Usage 15 | 16 | Usage is very simple, and you can refer to the original repo's 17 | [README](https://github.com/mczachurski/wallpapper#getting-started). I'm personally using it based on OS apperance 18 | settings (light/dark), which is also the simples API to use. 19 | 20 | Under `images`, create a folder with the name of your choice. Inside this folder, put an image for the light theme, and 21 | one for the dark theme. 22 | 23 | Under the same folder, create a `config.json` file as follows: 24 | 25 | ```json 26 | [ 27 | { 28 | "fileName": "1.png", 29 | "isPrimary": true, 30 | "isForLight": true 31 | }, 32 | { 33 | "fileName": "2.png", 34 | "isForDark": true 35 | } 36 | ] 37 | ``` 38 | 39 | Once this is setup, navigate to this folder and run 40 | 41 | ```bash 42 | wallpapper -i config.json 43 | ``` 44 | 45 | This will in turn create an `output.heic` image, that you can now safely set as a dynamic wallpaper. 46 | 47 | For more information, run 48 | 49 | ```bash 50 | wallpapper -h 51 | ``` 52 | -------------------------------------------------------------------------------- /other/images/wallpapers/images/edinburgh-northernlights/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "fileName": "edinburgh.jpg", 4 | "isPrimary": true, 5 | "isForLight": true 6 | }, 7 | { 8 | "fileName": "northern-lights.jpg", 9 | "isForDark": true 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /other/images/wallpapers/images/edinburgh-northernlights/output.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gonstoll/dotfiles/4ced11d875e98498c366144536f9e275538e3794/other/images/wallpapers/images/edinburgh-northernlights/output.heic -------------------------------------------------------------------------------- /other/images/wallpapers/images/tokyo-nyc/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "fileName": "tokyo.jpg", 4 | "isPrimary": true, 5 | "isForLight": true 6 | }, 7 | { 8 | "fileName": "new-york.jpg", 9 | "isForDark": true 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /other/images/wallpapers/images/tokyo-nyc/output.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gonstoll/dotfiles/4ced11d875e98498c366144536f9e275538e3794/other/images/wallpapers/images/tokyo-nyc/output.heic -------------------------------------------------------------------------------- /other/lib/colors: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # shellcheck disable=SC2034 4 | # A set of pre-defined color escape codes for use in prompts and with `echo`. 5 | 6 | black="\[\e[0;30m\]" 7 | red="\[\e[0;31m\]" 8 | green="\[\e[0;32m\]" 9 | yellow="\[\e[0;33m\]" 10 | blue="\[\e[0;34m\]" 11 | purple="\[\e[0;35m\]" 12 | cyan="\[\e[0;36m\]" 13 | white="\[\e[0;37m\]" 14 | orange="\[\e[0;91m\]" 15 | 16 | bold_black="\[\e[30;1m\]" 17 | bold_red="\[\e[31;1m\]" 18 | bold_green="\[\e[32;1m\]" 19 | bold_yellow="\[\e[33;1m\]" 20 | bold_blue="\[\e[34;1m\]" 21 | bold_purple="\[\e[35;1m\]" 22 | bold_cyan="\[\e[36;1m\]" 23 | bold_white="\[\e[37;1m\]" 24 | bold_orange="\[\e[91;1m\]" 25 | 26 | underline_black="\[\e[30;4m\]" 27 | underline_red="\[\e[31;4m\]" 28 | underline_green="\[\e[32;4m\]" 29 | underline_yellow="\[\e[33;4m\]" 30 | underline_blue="\[\e[34;4m\]" 31 | underline_purple="\[\e[35;4m\]" 32 | underline_cyan="\[\e[36;4m\]" 33 | underline_white="\[\e[37;4m\]" 34 | underline_orange="\[\e[91;4m\]" 35 | 36 | background_black="\[\e[40m\]" 37 | background_red="\[\e[41m\]" 38 | background_green="\[\e[42m\]" 39 | background_yellow="\[\e[43m\]" 40 | background_blue="\[\e[44m\]" 41 | background_purple="\[\e[45m\]" 42 | background_cyan="\[\e[46m\]" 43 | background_white="\[\e[47;1m\]" 44 | background_orange="\[\e[101m\]" 45 | 46 | normal="\[\e[0m\]" 47 | reset_color="\[\e[39m\]" 48 | 49 | # These colors are meant to be used with `echo -e` 50 | echo_black="\033[0;30m" 51 | echo_red="\033[0;31m" 52 | echo_green="\033[0;32m" 53 | echo_yellow="\033[0;33m" 54 | echo_blue="\033[0;34m" 55 | echo_purple="\033[0;35m" 56 | echo_cyan="\033[0;36m" 57 | echo_white="\033[0;37;1m" 58 | echo_orange="\033[0;91m" 59 | 60 | echo_bold_black="\033[30;1m" 61 | echo_bold_red="\033[31;1m" 62 | echo_bold_green="\033[32;1m" 63 | echo_bold_yellow="\033[33;1m" 64 | echo_bold_blue="\033[34;1m" 65 | echo_bold_purple="\033[35;1m" 66 | echo_bold_cyan="\033[36;1m" 67 | echo_bold_white="\033[37;1m" 68 | echo_bold_orange="\033[91;1m" 69 | 70 | echo_underline_black="\033[30;4m" 71 | echo_underline_red="\033[31;4m" 72 | echo_underline_green="\033[32;4m" 73 | echo_underline_yellow="\033[33;4m" 74 | echo_underline_blue="\033[34;4m" 75 | echo_underline_purple="\033[35;4m" 76 | echo_underline_cyan="\033[36;4m" 77 | echo_underline_white="\033[37;4m" 78 | echo_underline_orange="\033[91;4m" 79 | 80 | echo_background_black="\033[40m" 81 | echo_background_red="\033[41m" 82 | echo_background_green="\033[42m" 83 | echo_background_yellow="\033[43m" 84 | echo_background_blue="\033[44m" 85 | echo_background_purple="\033[45m" 86 | echo_background_cyan="\033[46m" 87 | echo_background_white="\033[47;1m" 88 | echo_background_orange="\033[101m" 89 | 90 | echo_normal="\033[0m" 91 | echo_reset_color="\033[39m" 92 | -------------------------------------------------------------------------------- /other/lib/help: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function run_help() { 4 | 5 | cat </dev/null 2>&1; then 6 | luarocks install --server=https://luarocks.org/dev luaformatter 7 | fi 8 | 9 | # NPM global packages 10 | if command -v npm >/dev/null 2>&1; then 11 | npm install -g depcheck eslint prettier prettier-plugin-tailwindcss typescript typescript-language-server vscode-langservers-extracted stylelint-lsp 12 | fi 13 | 14 | # Bun 15 | curl -fsSL https://bun.sh/install | bash 16 | 17 | # Rust 18 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 19 | 20 | # Give permissions to Alacritty 21 | if [ -z "$(brew search alacritty)" ]; then 22 | xattr -dr com.apple.quarantine "/Applications/Alacritty.app" 23 | fi 24 | 25 | # Wezterm terminfo file 26 | tempfile=$(mktemp) \ 27 | && curl -o $tempfile https://raw.githubusercontent.com/wez/wezterm/master/termwiz/data/wezterm.terminfo \ 28 | && tic -x -o ~/.terminfo $tempfile \ 29 | && rm $tempfile 30 | } 31 | -------------------------------------------------------------------------------- /other/lib/utils: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Header logging 4 | function e_header() { 5 | printf "\n$(tput setaf 7)%s$(tput sgr0)\n" "$@" 6 | } 7 | 8 | # Success logging 9 | function e_success() { 10 | printf "$(tput setaf 65) $(tput sgr0) %s\n" "$@" 11 | } 12 | 13 | # Error logging 14 | function e_error() { 15 | printf "$(tput setaf 1) $(tput sgr0) %s\n" "$@" 16 | } 17 | 18 | # Warning logging 19 | function e_warning() { 20 | printf "$(tput setaf 137) $(tput sgr0) %s\n" "$@" 21 | } 22 | 23 | # Ask for confirmation before proceeding 24 | function seek_confirmation() { 25 | printf "\n" 26 | e_warning "$@" 27 | read -p "Continue? (y/n) " -n 1 28 | printf "\n" 29 | } 30 | 31 | # Test whether the result of an 'ask' is a confirmation 32 | function is_confirmed() { 33 | if [[ "$REPLY" =~ ^[Yy]$ ]]; then 34 | return 0 35 | fi 36 | return 1 37 | } 38 | 39 | # Test whether we're in a git repo 40 | function is_git_repo() { 41 | $(git rev-parse --is-inside-work-tree &> /dev/null) 42 | } 43 | 44 | # Test whether a command exists 45 | # $1 - cmd to test 46 | function type_exists() { 47 | if [ "$(type -P $1)" ]; then 48 | return 0 49 | fi 50 | return 1 51 | } 52 | --------------------------------------------------------------------------------