├── .github └── workflows │ ├── lint_lua.yml │ └── lint_shell.yml ├── .gitignore ├── LICENSE ├── README.md ├── bin └── screenshot ├── config ├── X11 │ ├── .Xresources │ └── .xinitrc ├── bat │ ├── config │ └── themes │ │ └── catppuccin-mocha.tmTheme ├── bspwm │ ├── bspwmrc │ └── scripts │ │ └── external_rules ├── delta │ └── themes.gitconfig ├── dunst │ └── dunstrc ├── firefox │ └── user.js ├── nvim │ ├── .gitignore │ ├── .stylua.toml │ ├── after │ │ ├── ftplugin │ │ │ ├── c.lua │ │ │ ├── gitcommit.lua │ │ │ ├── help.lua │ │ │ ├── html.lua │ │ │ ├── javascript.lua │ │ │ ├── javascriptreact.lua │ │ │ ├── markdown.lua │ │ │ ├── qf.lua │ │ │ ├── sh.lua │ │ │ ├── typescript.lua │ │ │ ├── typescriptreact.lua │ │ │ └── vim.lua │ │ └── queries │ │ │ ├── ecma │ │ │ ├── highlights.scm │ │ │ └── textobjects.scm │ │ │ └── jsx │ │ │ └── highlights.scm │ ├── ftplugin │ │ └── fugitiveblame.lua │ ├── init.lua │ ├── lazy-lock.json │ ├── lsp │ │ ├── emmet_language_server.lua │ │ ├── eslint.lua │ │ ├── jsonls.lua │ │ ├── lua_ls.lua │ │ ├── tailwindcss.lua │ │ ├── ts_ls.lua │ │ └── vtsls.lua │ ├── lua │ │ ├── core │ │ │ ├── abbrev.lua │ │ │ ├── autocmds.lua │ │ │ ├── env.lua │ │ │ ├── filetype.lua │ │ │ ├── highlights.lua │ │ │ ├── icons.lua │ │ │ ├── init.lua │ │ │ ├── mappings.lua │ │ │ ├── options.lua │ │ │ ├── plugins.lua │ │ │ └── utils.lua │ │ └── plugins │ │ │ ├── alpha.lua │ │ │ ├── bufferline.lua │ │ │ ├── codecompanion.lua │ │ │ ├── colorizer.lua │ │ │ ├── colorscheme.lua │ │ │ ├── comment.lua │ │ │ ├── conform.lua │ │ │ ├── extras.lua │ │ │ ├── fidget.lua │ │ │ ├── flash.lua │ │ │ ├── gitsigns.lua │ │ │ ├── indent-blankline.lua │ │ │ ├── kulala.lua │ │ │ ├── lsp │ │ │ ├── autocmds.lua │ │ │ ├── diagnostics.lua │ │ │ ├── init.lua │ │ │ ├── mappings.lua │ │ │ ├── packages.lua │ │ │ └── utils.lua │ │ │ ├── lualine.lua │ │ │ ├── luasnip.lua │ │ │ ├── markdown-preview.lua │ │ │ ├── neogen.lua │ │ │ ├── nvim-autopairs.lua │ │ │ ├── nvim-cmp.lua │ │ │ ├── nvim-lint.lua │ │ │ ├── nvim-tree.lua │ │ │ ├── nvim-treesitter.lua │ │ │ ├── nvim-ufo.lua │ │ │ ├── telescope.lua │ │ │ └── which-key.lua │ ├── snippets │ │ ├── luasnippets │ │ │ ├── all.lua │ │ │ ├── javascript.lua │ │ │ ├── javascriptreact.lua │ │ │ ├── lua.lua │ │ │ └── markdown.lua │ │ └── snipmate │ │ │ └── javascript.snippets │ └── spell │ │ └── en.utf-8.add ├── picom │ └── picom.conf ├── polybar │ ├── bin │ │ ├── bluetooth │ │ └── powermenu │ ├── colors.ini │ ├── config.ini │ ├── launch.sh │ └── modules.ini ├── rofi │ ├── config.rasi │ ├── styles │ │ ├── powermenu.rasi │ │ └── powermenu_confirm.rasi │ └── themes │ │ └── catppuccin.rasi ├── sxhkd │ └── sxhkdrc ├── vscode │ ├── install.sh │ ├── keybindings.json │ ├── settings.json │ └── snippets │ │ ├── javascript.json │ │ ├── markdown.json │ │ ├── package.json │ │ └── react.json ├── wezterm │ ├── .stylua.toml │ ├── colors │ │ └── catppuccin.lua │ ├── events.lua │ ├── keybindings.lua │ ├── utils.lua │ └── wezterm.lua └── zsh │ ├── .gitignore │ ├── .zshenv │ ├── .zshrc │ ├── plugins.toml │ ├── plugins │ ├── aliases.zsh │ ├── completion.zsh │ ├── fzf.zsh │ ├── git.zsh │ ├── history.zsh │ ├── keybindings.zsh │ ├── node.zsh │ └── ssh.zsh │ └── starship.toml ├── etc ├── Hack.ttf ├── X11 │ └── xorg.conf.d │ │ ├── 20-amdgpu.conf │ │ └── 30-touchpad.conf ├── gnome.conf ├── reflector.conf └── vimium-options.json ├── lint.sh └── scripts ├── git-setup.sh ├── termux.sh └── utils.sh /.github/workflows/lint_lua.yml: -------------------------------------------------------------------------------- 1 | name: Lint lua files 2 | on: 3 | push: 4 | paths: 5 | - "**.lua" 6 | pull_request: 7 | paths: 8 | - "**.lua" 9 | 10 | jobs: 11 | stylua: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Check formatting with stylua 16 | uses: JohnnyMorganz/stylua-action@v4 17 | with: 18 | token: ${{ secrets.TOKEN }} 19 | version: latest 20 | # args passed to stylua 21 | args: --check -f config/nvim/.stylua.toml . 22 | -------------------------------------------------------------------------------- /.github/workflows/lint_shell.yml: -------------------------------------------------------------------------------- 1 | name: Lint shell scripts 2 | on: [push, pull_request] 3 | jobs: 4 | lint: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Install shfmt and fd 9 | run: | 10 | sudo snap install shfmt 11 | 12 | - name: Linting with shfmt and shellcheck 13 | run: | 14 | find . -type f \( -executable -or -name "*.sh" \) -not -path "./.git/*" -print0 | 15 | while IFS= read -r -d '' file; do 16 | shellcheck -s bash -e SC1090,SC1091 "$file" 17 | shfmt -d -ci -i 4 "$file" 18 | done 19 | 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env.local* 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2021 Saurabh Charde 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

🏠

2 |

~ There's no other place like $HOME ~

3 | 4 |
5 | Lint Lua 6 | Lint Scripts 7 |
8 | 9 | ### Current Setup 10 | 11 | - **DE:** [GNOME](https://www.gnome.org/) 12 | - **OS:** [Arch Linux](https://archlinux.org) 13 | - **Terminal:** [Wezterm](https://github.com/wez/wezterm) 14 | - **Shell:** [zsh](https://wiki.archlinux.org/index.php/Zsh) 15 | - **Editor:** [neovim](https://github.com/neovim/neovim) 16 | - **Color Scheme:** [catppuccin](https://github.com/catppuccin) 17 | 18 | ### Table of Contents 19 | 20 | - [ZSH](#ZSH) 21 | - [Neovim](#Neovim) 22 | - [Termux](#Termux) 23 | 24 | --- 25 | 26 | ### ZSH 27 | 28 | #### Installation 29 | 30 | Make sure you have [sheldon](https://github.com/rossmacarthur/sheldon) plugin manager installed in your system. 31 | 32 | ```bash 33 | # Clone the repo 34 | git clone https://github.com/schardev/dotfiles ~/dotfiles 35 | 36 | # Symlink zsh directory to $HOME/.config/zsh and zsh/.zshenv to $HOME 37 | ln -sf ~/dotfiles/config/zsh ${HOME}/.config/zsh 38 | ln -sf ~/dotfiles/config/zsh/.zshenv ${HOME} 39 | 40 | # restart shell/terminal 41 | exec zsh 42 | ``` 43 | 44 | ### Neovim 45 | 46 | #### Requirements 47 | 48 | - patched font (eg. [Powerline Fonts](https://github.com/powerline/fonts) or [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts)) 49 | - `clang`/`gcc` - For [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) 50 | - `wget`/`curl` and `gzip`/`tar` - For fetching language servers 51 | - `nodejs` and `npm` - For installing language servers 52 | - `ripgrep` and/or `fd` - For telescope 53 | 54 | #### Installation 55 | 56 | ```bash 57 | # Clone the repo 58 | git clone https://github.com/schardev/dotfiles ~/dotfiles 59 | 60 | # Either symlink the nvim directory to your $HOME/.config or copy the contents 61 | ln -sf ~/dotfiles/config/nvim ~/.config/nvim 62 | 63 | # Open nvim and it'll automatically start installing plugins 64 | nvim --headless "+Lazy! sync" +qa 65 | ``` 66 | 67 | ### Termux 68 | 69 | When I'm not on my laptop (or just too lazy to boot it up) I use [Termux](https://github.com/termux) to get my stuff done. It's pretty awesome! 70 | 71 | The script will setup termux to have [Catppuccin](https://github.com/catppuccin) colorscheme and [Hack](https://github.com/source-foundry/Hack) fonts by default. It also does my git and dotfiles setup. 72 | 73 | #### Installation 74 | 75 | ```bash 76 | # Clone the repo 77 | git clone https://github.com/schardev/dotfiles ~/dotfiles 78 | 79 | # Run the script 80 | ./dotfiles/scripts/termux 81 | ``` 82 | -------------------------------------------------------------------------------- /bin/screenshot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: MIT 3 | # Copyright (C) 2020-2022 Saurabh Charde 4 | # 5 | # Utility script for taking screenshots 6 | 7 | source "$DOTS_DIR"/scripts/utils.sh 8 | 9 | time=$(date +%d-%m-%Y-%I-%M-%S) 10 | dir="$(xdg-user-dir PICTURES)/Screenshots" 11 | filename="Screenshot-${time}.png" 12 | 13 | # Default options 14 | maim_options=(--hidecursor "--format=png" --quiet) 15 | dunst_options=("--urgency=normal" "--timeout=4000" "--replace=69") 16 | reason="Screenshot Saved " 17 | delay=5 18 | 19 | # Notifies user when screenshot is taken successfully 20 | notify() { 21 | if command -v dunstify >/dev/null; then 22 | if [[ ! -f "$dir/$filename" ]]; then 23 | dunst_options+=("--icon=camera") 24 | else 25 | dunst_options+=("--icon=$dir/$filename") 26 | fi 27 | 28 | dunstify "${dunst_options[@]}" "$reason" 29 | fi 30 | } 31 | 32 | # Countdown timer for delayed screenshots 33 | timer() { 34 | if command -v dunstify >/dev/null; then 35 | for sec in $(seq $delay -1 1); do 36 | dunstify --timeout 1000 --replace=69 --icon=alarm-timer "Taking screenshot in: $sec" 37 | sleep 1 38 | done 39 | fi 40 | } 41 | 42 | show_usage() { 43 | cat </dev/null; then 9 | "$@" & 10 | fi 11 | } 12 | 13 | ## BSPWM desktop layout 14 | bspc monitor -d 1 2 3 4 5 15 | 16 | ## BSPWM config 17 | config border_width 1 18 | config window_gap 7 19 | config split_ratio 0.52 20 | config borderless_monocle true 21 | config gapless_monocle true 22 | config focused_border_color "$(xrdb -query | awk '/color5:/ {print $2}')" 23 | config presel_feedback_color "$(xrdb -query | awk '/color15:/ {print $2}')" 24 | # config focus_follows_pointer true 25 | config pointer_modifier mod4 # super 26 | config pointer_action1 move # super + left click 27 | config pointer_action2 resize_side # super + middle click 28 | config pointer_action3 resize_corner # super + right click 29 | config external_rules_command "$HOME"/.config/bspwm/scripts/external_rules 30 | 31 | ## BSPWM rules 32 | rule firefox desktop=2 follow=on 33 | rule firefox:Places state=floating # FF downloads/history windows 34 | rule Google-chrome desktop=2 follow=on 35 | rule TelegramDesktop desktop=3 follow=on 36 | rule obs desktop=5 follow=off 37 | 38 | ## Autostart few services 39 | # Start picom 40 | picom --config "$HOME"/.config/picom/picom.conf & 41 | 42 | # Set wallpaper 43 | feh --bg-fill "$HOME"/Downloads/bg.jpg 44 | 45 | # Start sxhkd (hotkey daemon) 46 | start sxhkd 47 | 48 | # Start systray services 49 | start nm-applet # network manager systray 50 | start dunst # Notification daemon 51 | start /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 # authentication prompt for root apps 52 | 53 | # Launch Polybar 54 | ~/.config/polybar/launch.sh 55 | 56 | # Set proper cursor 57 | xsetroot -cursor_name left_ptr & 58 | 59 | # Use caps lock as escape key 60 | setxkbmap -option "caps:escape" & 61 | -------------------------------------------------------------------------------- /config/bspwm/scripts/external_rules: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | window_id=$1 4 | window_class=$2 5 | window_instance=$3 6 | window_options=$4 7 | window_title="$(xwininfo -id "$window_id" | sed '/^xwininfo/!d ; s,.*"\(.*\)".*,\1,')" 8 | window_type="$(xprop -id "$window_id" _NET_WM_WINDOW_TYPE | sed '/^_NET_WM_WINDOW_TYPE/!d ; s/^.* = \(.*\),.*/\1/')" 9 | debug=false 10 | 11 | case "$window_class" in 12 | # Declare all window classes that'll be set to floating 13 | Nm-* | *calculator* | Pavucontrol) 14 | eval "$window_options" 15 | echo "state=${state:-floating}" # explicitly set state=floating if `$state` isn't defined already 16 | ;; 17 | MEGAsync) 18 | echo "state=floating border=off" 19 | ;; 20 | esac 21 | 22 | # Loggings 23 | if "$debug"; then 24 | logfile=/tmp/bspwm_external_rules.log 25 | cat <>"$logfile" 26 | Id: $window_id 27 | Class: $window_class 28 | Instance: $window_instance 29 | Title: $window_title 30 | Type: $window_type 31 | window_options: $window_options 32 | --- 33 | EOF 34 | fi 35 | -------------------------------------------------------------------------------- /config/delta/themes.gitconfig: -------------------------------------------------------------------------------- 1 | ; https://github.com/catppuccin/delta/commit/e9e21cffd98787f1b59e6f6e42db599f9b8ab399 2 | [delta "catppuccin-mocha"] 3 | blame-palette = "#1e1e2e #181825 #11111b #313244 #45475a" 4 | dark = true 5 | file-decoration-style = box ul "#6c7086" 6 | file-style = "#cdd6f4" 7 | hunk-header-decoration-style = "#6c7086" box ul 8 | hunk-header-file-style = bold 9 | hunk-header-line-number-style = bold "#a6adc8" 10 | hunk-header-style = omit 11 | line-numbers-left-style = "#6c7086" 12 | line-numbers-minus-style = bold "#f38ba8" 13 | line-numbers-plus-style = bold "#a6e3a1" 14 | line-numbers-right-style = "#6c7086" 15 | line-numbers-zero-style = "#6c7086" 16 | ; minus-emph-style = "#000 red" 17 | ; minus-style = "syntax #35293b" 18 | ; plus-emph-style = "#000 green" 19 | ; plus-style = "syntax #2c333a" 20 | minus-emph-style = bold syntax "#53394c" 21 | minus-style = syntax "#34293a" 22 | plus-emph-style = bold syntax "#404f4a" 23 | plus-style = syntax "#2c3239" 24 | map-styles = \ 25 | bold purple => syntax "#494060", \ 26 | bold blue => syntax "#384361", \ 27 | bold cyan => syntax "#384d5d", \ 28 | bold yellow => syntax "#544f4e" 29 | # Should match the name of the bat theme 30 | syntax-theme = "catppuccin-mocha" 31 | 32 | [delta] 33 | file-added-label = [A] 34 | file-copied-label = [==] 35 | file-modified-label = [M] 36 | file-removed-label = [D] 37 | file-renamed-label = [->] 38 | features = catppuccin-mocha 39 | -------------------------------------------------------------------------------- /config/firefox/user.js: -------------------------------------------------------------------------------- 1 | // Disable about:config warning 2 | user_pref("browser.aboutConfig.showWarning", false); 3 | 4 | // After every update manjaro keeps setting its website as homepage so 5 | // set firefox home as default 6 | user_pref("browser.startup.homepage", "about:home"); 7 | 8 | // Enable autoscroll by pressing mousewheel (default behaviour in Windows) 9 | user_pref("general.autoScroll", true); 10 | 11 | // Sober scrolling 12 | user_pref("mousewheel.system_scroll_override.enabled", false); 13 | -------------------------------------------------------------------------------- /config/nvim/.gitignore: -------------------------------------------------------------------------------- 1 | packer_compiled.lua 2 | viminfo 3 | swap 4 | backup 5 | .netrwhist 6 | spell/*.spl 7 | -------------------------------------------------------------------------------- /config/nvim/.stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 80 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 2 5 | quote_style = "AutoPreferDouble" 6 | call_parentheses = "Always" 7 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/c.lua: -------------------------------------------------------------------------------- 1 | -- Hax to prevent c.vim from clearing tabs highlighting for cpp.vim, since vim 2 | -- sources c.vim for cpp files as well (see /usr/share/[n]vim/runtime/ftplugin/c.vim) 3 | if vim.bo.filetype ~= "c" then 4 | return 5 | end 6 | 7 | -- Set indentation to match linux-kernel coding style 8 | vim.bo.expandtab = false 9 | vim.bo.shiftwidth = 8 10 | vim.bo.softtabstop = 8 11 | vim.bo.tabstop = 8 12 | 13 | vim.opt_local.spell = true 14 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/gitcommit.lua: -------------------------------------------------------------------------------- 1 | vim.bo.textwidth = 80 2 | vim.bo.spellcapcheck = "" 3 | vim.opt_local.spell = true 4 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/help.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.colorcolumn = "" 2 | 3 | -- Wrap text by default and don't break words 4 | vim.opt_local.wrap = true 5 | vim.opt_local.linebreak = true 6 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/html.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.colorcolumn = "" 2 | vim.opt_local.spell = true 3 | vim.opt_local.wrap = true 4 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/javascript.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.spell = true 2 | vim.opt_local.spelloptions:append("camel") 3 | vim.opt_local.spellcapcheck = "" 4 | 5 | vim.keymap.set("n", "no", function() 6 | vim.cmd("botright terminal node") 7 | vim.cmd("wincmd J | startinsert") 8 | end, { desc = "Open node repl in a termial split below" }) 9 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/javascriptreact.lua: -------------------------------------------------------------------------------- 1 | -- Source javascript ftplugin 2 | vim.cmd("runtime! ftplugin/javascript.lua") 3 | 4 | -- React directives 5 | vim.cmd.inoreabbrev("uc", '"use client";') 6 | vim.cmd.inoreabbrev("us", '"use server";') 7 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/markdown.lua: -------------------------------------------------------------------------------- 1 | local installed, surround = pcall(require, "nvim-surround") 2 | 3 | if installed then 4 | surround.buffer_setup({ 5 | surrounds = { 6 | -- https://github.com/kylechui/nvim-surround/discussions/53 7 | ["l"] = { 8 | add = function() 9 | local clipboard = vim.fn.getreg("+"):gsub("\n", "") 10 | return { 11 | { "[" }, 12 | { "](" .. clipboard .. ")" }, 13 | } 14 | end, 15 | find = "%b[]%b()", 16 | delete = "^(%[)().-(%]%b())()$", 17 | change = { 18 | target = "^()()%b[]%((.-)()%)$", 19 | replacement = function() 20 | local clipboard = vim.fn.getreg("+"):gsub("\n", "") 21 | return { 22 | { "" }, 23 | { clipboard }, 24 | } 25 | end, 26 | }, 27 | }, 28 | }, 29 | }) 30 | end 31 | 32 | -- There should be no restriction for 80-char limit in markdown files, so wrap 33 | -- them but don't break words (easier to read that way) 34 | vim.opt_local.wrap = true 35 | vim.opt_local.linebreak = true 36 | vim.opt_local.colorcolumn = "" 37 | 38 | vim.opt_local.spell = true 39 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/qf.lua: -------------------------------------------------------------------------------- 1 | -- https://github.com/b0o/nvim-conf/blob/dad348a6988266c648d59891caee8debc0550d59/lua/user/mappings.lua#L393 2 | local function is_loclist(winid) 3 | return vim.fn.win_gettype(winid) == "loclist" 4 | end 5 | 6 | local function get_list(winid) 7 | return is_loclist(winid) and vim.fn.getloclist(winid) or vim.fn.getqflist() 8 | end 9 | 10 | local function set_list(winid, list, action) 11 | if is_loclist(winid) then 12 | vim.fn.setloclist(winid, list, action) 13 | else 14 | vim.fn.setqflist(list, action) 15 | end 16 | end 17 | 18 | vim.keymap.set("n", "dd", function() 19 | local winid = vim.api.nvim_get_current_win() 20 | local line = vim.fn.line(".") 21 | set_list( 22 | winid, 23 | vim.fn.filter(get_list(winid), function(idx) 24 | return idx ~= line - 1 25 | end), 26 | "r" 27 | ) 28 | vim.fn.setpos(".", { 0, line, 1, 0 }) 29 | end, { desc = "Delete item from quickfix list", buffer = true }) 30 | 31 | vim.keymap.set("v", "d", function() 32 | vim.schedule(function() 33 | local winid = vim.api.nvim_get_current_win() 34 | local start = vim.fn.line("'<") 35 | local finish = vim.fn.line("'>") 36 | set_list( 37 | winid, 38 | vim.fn.filter(get_list(winid), function(idx) 39 | return idx < start - 1 or idx >= finish 40 | end), 41 | "r" 42 | ) 43 | vim.fn.setpos(".", { 0, start, 1, 0 }) 44 | end) 45 | vim.cmd([[call feedkeys("\", 'n')]]) 46 | end, { desc = "Delete item from quickfix list", buffer = true }) 47 | 48 | vim.cmd.packadd("cfilter") 49 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/sh.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.shiftwidth = 4 2 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/typescript.lua: -------------------------------------------------------------------------------- 1 | -- Source javascript ftplugin 2 | vim.cmd("runtime! ftplugin/javascript.lua") 3 | 4 | ---@type string|nil 5 | local tsc_process_cwd = nil 6 | 7 | --- Gets the current node package manager 8 | local function get_package_manager() 9 | local git_root = vim.fs.root(0, ".git") 10 | 11 | if vim.uv.fs_stat(vim.fs.joinpath(git_root, "package-lock.json")) then 12 | return "npm" 13 | elseif vim.uv.fs_stat(vim.fs.joinpath(git_root, "yarn.lock")) then 14 | return "yarn" 15 | else 16 | return "pnpm" 17 | end 18 | end 19 | 20 | ---@param output string 21 | local function get_qf_from_errors(output) 22 | local quickfix_entries = {} 23 | local lines = vim.split(output, "\n", { trimempty = true }) 24 | 25 | for _, line in ipairs(lines) do 26 | local filename, lnum, col, msg = 27 | string.match(line, "(.+)%((%d+),(%d+)%):%s*error%s*(.*)") 28 | if filename then 29 | table.insert(quickfix_entries, { 30 | filename = filename, 31 | lnum = tonumber(lnum), 32 | col = tonumber(col), 33 | text = msg, 34 | type = "E", 35 | }) 36 | end 37 | end 38 | 39 | return quickfix_entries 40 | end 41 | 42 | ---@param out vim.SystemCompleted 43 | local function on_exit(out) 44 | tsc_process_cwd = nil 45 | 46 | if out.code == 0 then 47 | vim.notify("TypeScript compilation successful!") 48 | else 49 | vim.notify("TypeScript compilation failed!") 50 | local quickfix_entries = get_qf_from_errors(out.stdout) 51 | if #quickfix_entries > 0 then 52 | vim.schedule(function() 53 | vim.fn.setqflist(quickfix_entries) 54 | -- vim.cmd("copen") -- Open the quickfix list 55 | end) 56 | end 57 | end 58 | end 59 | 60 | local function compile() 61 | local pkg_manager = get_package_manager() 62 | local current_directory = vim.fn.getcwd() 63 | if tsc_process_cwd == current_directory then 64 | vim.print("TS compilation already in process at " .. tsc_process_cwd) 65 | else 66 | tsc_process_cwd = current_directory 67 | vim.system( 68 | { pkg_manager, "tsc", "--noEmit" }, 69 | { text = true }, 70 | vim.schedule_wrap(on_exit) 71 | ) 72 | end 73 | end 74 | 75 | vim.keymap.set( 76 | "n", 77 | "", 78 | compile, 79 | { buffer = true, desc = "Compile using TS" } 80 | ) 81 | 82 | -- Surround 83 | local installed, surround = pcall(require, "nvim-surround") 84 | 85 | if not installed then 86 | return 87 | end 88 | 89 | local config = require("nvim-surround.config") 90 | 91 | surround.buffer_setup({ 92 | surrounds = { 93 | -- https://github.com/kylechui/nvim-surround/discussions/53 94 | ["g"] = { 95 | add = function() 96 | local result = config.get_input("Enter the generic name: ") 97 | if result then 98 | return { { result .. "<" }, { ">" } } 99 | end 100 | end, 101 | find = function() 102 | return config.get_selection({ node = "generic_type" }) 103 | end, 104 | delete = "^(.-<)().-(>)()$", 105 | change = { 106 | target = "^(.-<)().-(>)()$", 107 | replacement = function() 108 | local result = config.get_input("Enter the generic name: ") 109 | if result then 110 | return { { result .. "<" }, { ">" } } 111 | end 112 | end, 113 | }, 114 | }, 115 | }, 116 | }) 117 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/typescriptreact.lua: -------------------------------------------------------------------------------- 1 | -- Source typescript and jsx ftplugin 2 | vim.cmd("runtime! ftplugin/typescript.lua") 3 | vim.cmd("runtime! ftplugin/javascriptreact.lua") 4 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/vim.lua: -------------------------------------------------------------------------------- 1 | vim.opt_local.foldmethod = "marker" 2 | vim.opt_local.spell = true 3 | -------------------------------------------------------------------------------- /config/nvim/after/queries/ecma/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | [ 3 | (identifier) 4 | ] @spell 5 | -------------------------------------------------------------------------------- /config/nvim/after/queries/ecma/textobjects.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | (ternary_expression consequence: (_) @user.ternary.inner) 3 | (ternary_expression alternative: (_) @user.ternary.inner) 4 | -------------------------------------------------------------------------------- /config/nvim/after/queries/jsx/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; extends 2 | 3 | (jsx_element (_ (identifier) @nospell)) 4 | (jsx_self_closing_element (identifier) @nospell) 5 | (string_fragment) @spell 6 | -------------------------------------------------------------------------------- /config/nvim/ftplugin/fugitiveblame.lua: -------------------------------------------------------------------------------- 1 | -- Disable smooth horizontal scrolling due to performance issues on larger 2 | -- diffs/git blame 3 | vim.go.sidescroll = 0 4 | -------------------------------------------------------------------------------- /config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | require("core") 2 | -------------------------------------------------------------------------------- /config/nvim/lazy-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, 3 | "LuaSnip": { "branch": "master", "commit": "faf3c94a44508cec1b961406d36cc65113ff3b98" }, 4 | "alpha-nvim": { "branch": "main", "commit": "a35468cd72645dbd52c0624ceead5f301c566dff" }, 5 | "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, 6 | "catppuccin": { "branch": "main", "commit": "387b4b19568cbda82c1d6def9ded31fd6ae7fb99" }, 7 | "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, 8 | "cmp-calc": { "branch": "main", "commit": "5947b412da67306c5b68698a02a846760059be2e" }, 9 | "cmp-git": { "branch": "main", "commit": "b24309c386c9666c549a1abaedd4956541676d06" }, 10 | "cmp-nvim-lsp": { "branch": "main", "commit": "a8912b88ce488f411177fc8aed358b04dc246d7b" }, 11 | "cmp-nvim-lsp-signature-help": { "branch": "main", "commit": "031e6ba70b0ad5eee49fd2120ff7a2e325b17fa7" }, 12 | "cmp-path": { "branch": "main", "commit": "c6635aae33a50d6010bf1aa756ac2398a2d54c32" }, 13 | "cmp-spell": { "branch": "master", "commit": "694a4e50809d6d645c1ea29015dad0c293f019d6" }, 14 | "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, 15 | "codecompanion.nvim": { "branch": "main", "commit": "43185768e353065f910dcf5915386404f0e950da" }, 16 | "conform.nvim": { "branch": "master", "commit": "6feb2f28f9a9385e401857b21eeac3c1b66dd628" }, 17 | "fidget.nvim": { "branch": "main", "commit": "d9ba6b7bfe29b3119a610892af67602641da778e" }, 18 | "flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" }, 19 | "gitsigns.nvim": { "branch": "main", "commit": "8bdaccdb897945a3c99c1ad8df94db0ddf5c8790" }, 20 | "indent-blankline.nvim": { "branch": "master", "commit": "005b56001b2cb30bfa61b7986bc50657816ba4ba" }, 21 | "kulala.nvim": { "branch": "main", "commit": "aa462decb4aa2f0cb9783fba4ad8f401b042c3be" }, 22 | "lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" }, 23 | "lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" }, 24 | "lualine.nvim": { "branch": "master", "commit": "0c6cca9f2c63dadeb9225c45bc92bb95a151d4af" }, 25 | "luvit-meta": { "branch": "main", "commit": "1df30b60b1b4aecfebc785aa98943db6c6989716" }, 26 | "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, 27 | "mason-lspconfig.nvim": { "branch": "main", "commit": "67da97f8c2fd12d05427bb485ce07ee6418e0a51" }, 28 | "mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" }, 29 | "neogen": { "branch": "main", "commit": "d7f9461727751fb07f82011051338a9aba07581d" }, 30 | "nvim-autopairs": { "branch": "master", "commit": "4d74e75913832866aa7de35e4202463ddf6efd1b" }, 31 | "nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" }, 32 | "nvim-colorizer.lua": { "branch": "master", "commit": "517df88cf2afb36652830df2c655df2da416a0ae" }, 33 | "nvim-lint": { "branch": "master", "commit": "b47cbb249351873e3a571751c3fb66ed6369852f" }, 34 | "nvim-lspconfig": { "branch": "master", "commit": "03bc581e05e81d33808b42b2d7e76d70adb3b595" }, 35 | "nvim-surround": { "branch": "main", "commit": "8dd9150ca7eae5683660ea20cec86edcd5ca4046" }, 36 | "nvim-tree.lua": { "branch": "master", "commit": "ebcaccda1c575fa19a8087445276e6671e2b9b37" }, 37 | "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, 38 | "nvim-treesitter-textobjects": { "branch": "master", "commit": "0f051e9813a36481f48ca1f833897210dbcfffde" }, 39 | "nvim-ts-context-commentstring": { "branch": "main", "commit": "1b212c2eee76d787bbea6aa5e92a2b534e7b4f8f" }, 40 | "nvim-ufo": { "branch": "main", "commit": "3c7a3570e9c9dc198a2ad4491b0b0e51c4d4ba08" }, 41 | "nvim-vtsls": { "branch": "main", "commit": "60b493e641d3674c030c660cabe7a2a3f7a914be" }, 42 | "nvim-web-devicons": { "branch": "master", "commit": "1fb58cca9aebbc4fd32b086cb413548ce132c127" }, 43 | "persistence.nvim": { "branch": "main", "commit": "166a79a55bfa7a4db3e26fc031b4d92af71d0b51" }, 44 | "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" }, 45 | "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" }, 46 | "rainbow-delimiters.nvim": { "branch": "master", "commit": "55ad4fb76ab68460f700599b7449385f0c4e858e" }, 47 | "schemastore.nvim": { "branch": "main", "commit": "59d6bfa8c109675065f68a81664c17557cc19a9c" }, 48 | "telescope-fzf-native.nvim": { "branch": "main", "commit": "1f08ed60cafc8f6168b72b80be2b2ea149813e55" }, 49 | "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" }, 50 | "telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" }, 51 | "undotree": { "branch": "master", "commit": "b951b87b46c34356d44aa71886aecf9dd7f5788a" }, 52 | "vim-fugitive": { "branch": "master", "commit": "4a745ea72fa93bb15dd077109afbb3d1809383f2" }, 53 | "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" } 54 | } 55 | -------------------------------------------------------------------------------- /config/nvim/lsp/emmet_language_server.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config("emmet_language_server", { 2 | filetypes = { 3 | "html", 4 | "javascriptreact", 5 | "markdown", 6 | "typescriptreact", 7 | -- "css", 8 | }, 9 | 10 | -- For possible options, see: https://github.com/emmetio/emmet/blob/master/src/config.ts 11 | init_options = { 12 | -- change completion kind to `Snippet` 13 | showSuggestionsAsSnippets = true, 14 | 15 | html = { 16 | options = { 17 | ["bem.enabled"] = true, 18 | ["bem.modifier"] = "--", 19 | }, 20 | }, 21 | jsx = { 22 | options = { 23 | ["bem.enabled"] = true, 24 | ["jsx.enabled"] = true, 25 | ["output.selfClosingStyle"] = "xhtml", 26 | }, 27 | }, 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /config/nvim/lsp/eslint.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config("eslint", { 2 | settings = { 3 | experimental = { 4 | useFlatConfig = false, 5 | }, 6 | }, 7 | }) 8 | -------------------------------------------------------------------------------- /config/nvim/lsp/jsonls.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config("jsonls", { 2 | -- https://github.com/microsoft/vscode/tree/main/extensions/json-language-features/server#settings 3 | settings = { 4 | json = { 5 | validate = { enable = true }, 6 | schemas = require("schemastore").json.schemas(), 7 | }, 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /config/nvim/lsp/lua_ls.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config("lua_ls", { 2 | settings = { 3 | Lua = { 4 | completion = { 5 | callSnippet = "Disable", 6 | }, 7 | workspace = { 8 | checkThirdParty = false, 9 | }, 10 | }, 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /config/nvim/lsp/tailwindcss.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config("tailwindcss", { 2 | root_dir = function(bufnr, on_dir) 3 | local util = require("lspconfig.util") 4 | local root_files = { 5 | "tailwind.config.js", 6 | "tailwind.config.cjs", 7 | "tailwind.config.mjs", 8 | "tailwind.config.ts", 9 | -- 'postcss.config.js', 10 | -- 'postcss.config.cjs', 11 | -- 'postcss.config.mjs', 12 | -- 'postcss.config.ts', 13 | } 14 | local fname = vim.api.nvim_buf_get_name(bufnr) 15 | root_files = util.insert_package_json(root_files, "tailwindcss", fname) 16 | on_dir( 17 | vim.fs.dirname( 18 | vim.fs.find(root_files, { path = fname, upward = true })[1] 19 | ) 20 | ) 21 | end, 22 | settings = { 23 | tailwindCSS = { 24 | experimental = { 25 | classRegex = { 26 | -- clsx, cn 27 | -- https://github.com/tailwindlabs/tailwindcss-intellisense/issues/682#issuecomment-1364585313 28 | { [[clsx\(([^)]*)\)]], [["([^"]*)"]] }, 29 | { [[cn\(([^)]*)\)]], [["([^"]*)"]] }, 30 | -- Tailwind Variants 31 | -- https://www.tailwind-variants.org/docs/getting-started#intellisense-setup-optional 32 | { [[tv\(([^)]*)\)]], [==[["'`]([^"'`]*).*?["'`]]==] }, 33 | }, 34 | }, 35 | }, 36 | }, 37 | }) 38 | -------------------------------------------------------------------------------- /config/nvim/lsp/ts_ls.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.config("ts_ls", { 2 | -- https://github.com/yioneko/vtsls/blob/main/packages/service/configuration.schema.json 3 | settings = { 4 | typescript = { 5 | -- https://code.visualstudio.com/docs/typescript/typescript-editing#_inlay-hints 6 | inlayHints = { 7 | enumMemberValues = { enabled = true }, 8 | functionLikeReturnTypes = { enabled = true }, 9 | parameterNames = { enabled = "literals" }, 10 | parameterTypes = { enabled = true }, 11 | propertyDeclarationTypes = { enabled = true }, 12 | variableTypes = { enabled = true }, 13 | }, 14 | }, 15 | }, 16 | }) 17 | -------------------------------------------------------------------------------- /config/nvim/lsp/vtsls.lua: -------------------------------------------------------------------------------- 1 | local ts_ls_config = vim.lsp.config.ts_ls.settings 2 | 3 | -- https://github.com/yioneko/vtsls/blob/main/packages/service/configuration.schema.json 4 | vim.lsp.config("vtsls", { 5 | settings = vim.tbl_extend("force", ts_ls_config, { 6 | vtsls = { 7 | -- Automatically use workspace version of TypeScript lib on startup 8 | autoUseWorkspaceTsdk = true, 9 | experimental = { 10 | -- Truncate inlay hint 11 | -- https://github.com/neovim/neovim/issues/27240 12 | maxInlayHintLength = 40, 13 | completion = { 14 | -- Execute fuzzy match of completion items on server side. Enable this 15 | -- will help filter out useless completion items from tsserver 16 | enableServerSideFuzzyMatch = true, 17 | -- entriesLimit = 200, 18 | }, 19 | }, 20 | }, 21 | }), 22 | }) 23 | -------------------------------------------------------------------------------- /config/nvim/lua/core/abbrev.lua: -------------------------------------------------------------------------------- 1 | vim.cmd.inoreabbrev("SC", "Saurabh Charde") 2 | vim.cmd.inoreabbrev("SCR", "saurabhchardereal") 3 | vim.cmd.inoreabbrev("SEM", "saurabhchardereal@gmail.com") 4 | -------------------------------------------------------------------------------- /config/nvim/lua/core/autocmds.lua: -------------------------------------------------------------------------------- 1 | local autocmd = vim.api.nvim_create_autocmd 2 | local map = require("core.utils").map 3 | 4 | local user_core_augroup = vim.api.nvim_create_augroup("user.core", {}) 5 | 6 | autocmd("WinEnter", { 7 | group = user_core_augroup, 8 | pattern = "*", 9 | callback = function() 10 | if vim.fn.win_gettype() == "popup" then 11 | return 12 | end 13 | vim.wo.cursorline = true 14 | vim.wo.colorcolumn = "80" 15 | end, 16 | desc = "Highlight cursorline and colorcolumn on active window", 17 | }) 18 | 19 | autocmd("WinLeave", { 20 | group = user_core_augroup, 21 | pattern = "*", 22 | callback = function() 23 | vim.wo.cursorline = false 24 | vim.wo.colorcolumn = "" 25 | end, 26 | desc = "Remove cursorline and colorcolumn from inactive window", 27 | }) 28 | 29 | autocmd("FileType", { 30 | group = user_core_augroup, 31 | pattern = { 32 | "checkhealth", 33 | "help", 34 | "lspinfo", 35 | "qf", 36 | "query", 37 | "startuptime", 38 | "tsplayground", 39 | }, 40 | callback = function(e) 41 | -- Map q to exit in non-filetype buffers 42 | vim.bo[e.buf].buflisted = false 43 | map("n", "q", ":q", { buffer = e.buf }) 44 | end, 45 | desc = "Maps q to exit on non-filetypes", 46 | }) 47 | 48 | autocmd("TextYankPost", { 49 | group = user_core_augroup, 50 | pattern = "*", 51 | callback = function() 52 | vim.highlight.on_yank({ higroup = "IncSearch", timeout = 400 }) 53 | end, 54 | desc = "Highlight text on yank (copy)", 55 | }) 56 | -------------------------------------------------------------------------------- /config/nvim/lua/core/env.lua: -------------------------------------------------------------------------------- 1 | return { 2 | NVIM_USER_USE_TS_LS = vim.env.NVIM_USER_USE_TS_LS and true or false, 3 | NVIM_USER_ONLY_CORE = vim.env.NVIM_USER_ONLY_CORE and true or false, 4 | } 5 | -------------------------------------------------------------------------------- /config/nvim/lua/core/filetype.lua: -------------------------------------------------------------------------------- 1 | vim.filetype.add({ 2 | extension = { 3 | cjsn = "jsonc", 4 | cjson = "jsonc", 5 | mdx = "markdown", 6 | gitconfig = "gitconfig", 7 | }, 8 | filename = { 9 | [".eslintrc.json"] = "jsonc", 10 | ["coc-settings.json"] = "jsonc", 11 | ["keybindings.json"] = "jsonc", 12 | }, 13 | pattern = { 14 | [".*/zsh/functions/.*"] = "zsh", 15 | ["tsconfig.*.json"] = "jsonc", 16 | [".env%..*"] = "sh", 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /config/nvim/lua/core/highlights.lua: -------------------------------------------------------------------------------- 1 | local autocmd = vim.api.nvim_create_autocmd 2 | local fn = vim.fn 3 | 4 | -- Whitespace highlighting 5 | -- Taken from https://github.com/akinsho/dotfiles 6 | 7 | -- Do not highlight whitespaces in below filetypes 8 | local ignore_filetypes = { 9 | "c", 10 | "kconfig", 11 | "make", 12 | } 13 | 14 | local function is_floating_win() 15 | return fn.win_gettype() == "popup" 16 | end 17 | 18 | local function is_invalid_buf() 19 | return vim.bo.filetype == "" or vim.bo.buftype ~= "" or not vim.bo.modifiable 20 | end 21 | 22 | local function is_ignored() 23 | return vim.tbl_contains(ignore_filetypes, vim.bo.filetype) 24 | end 25 | 26 | local function highlight_trailing() 27 | if is_invalid_buf() or is_floating_win() or is_ignored() then 28 | return 29 | end 30 | 31 | local space_pattern = [[\s\+$]] 32 | if vim.w.space_match_number then 33 | fn.matchdelete(vim.w.space_match_number) 34 | fn.matchadd("ExtraWhitespace", space_pattern, 10, vim.w.space_match_number) 35 | else 36 | vim.w.space_match_number = fn.matchadd("ExtraWhitespace", space_pattern) 37 | end 38 | 39 | local tabs_pattern = [[\t]] 40 | if vim.w.tabs_match_number then 41 | fn.matchdelete(vim.w.tabs_match_number) 42 | fn.matchadd("Tabs", tabs_pattern, 11, vim.w.tabs_match_number) 43 | else 44 | vim.w.tabs_match_number = fn.matchadd("Tabs", tabs_pattern) 45 | end 46 | end 47 | 48 | autocmd({ "BufEnter", "FileType", "InsertLeave" }, { 49 | pattern = "*", 50 | callback = highlight_trailing, 51 | desc = "Highlight trailing whitespace", 52 | }) 53 | -------------------------------------------------------------------------------- /config/nvim/lua/core/icons.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.lspkind = { 4 | Class = "󰠱", 5 | Color = "󰏘", 6 | Constant = "󰏿", 7 | Constructor = "", 8 | Enum = "", 9 | EnumMember = "", 10 | Event = "", 11 | Field = "󰜢", 12 | File = "󰈚", 13 | Folder = "", 14 | Function = "󰆧", 15 | Interface = "", 16 | Keyword = "󰌋", 17 | Method = "󰆧", 18 | Module = "", 19 | Operator = "󰆕", 20 | Property = "󰜢", 21 | Reference = "󰈇", 22 | Snippet = "", 23 | Struct = "󰙅", 24 | Text = "󰉿", 25 | TypeParameter = "", 26 | Unit = "󰑭", 27 | Value = "󰎠", 28 | Variable = "󰀫", 29 | } 30 | 31 | M.diagnostics = { 32 | error = "", 33 | warning = "", 34 | info = "", 35 | hint = "", 36 | } 37 | 38 | M.devicons = { 39 | format = "󰉼", 40 | lock = "", 41 | download = "", 42 | flash = "", 43 | file = "", 44 | folder = " ", 45 | search = "", 46 | files = "", 47 | update = "󰚰", 48 | check = "", 49 | speedometer = "󰾅", 50 | plus_circle = "󰐗", 51 | } 52 | 53 | M.git = { 54 | untracked = "", 55 | } 56 | 57 | return M 58 | -------------------------------------------------------------------------------- /config/nvim/lua/core/init.lua: -------------------------------------------------------------------------------- 1 | require("core.options") 2 | require("core.mappings") 3 | require("core.autocmds") 4 | require("core.highlights") 5 | require("core.filetype") 6 | require("core.abbrev") 7 | require("core.plugins") 8 | -------------------------------------------------------------------------------- /config/nvim/lua/core/mappings.lua: -------------------------------------------------------------------------------- 1 | local utils = require("core.utils") 2 | local map = utils.map 3 | 4 | -- No need to keep holding shift 5 | map({ "n", "v" }, ";", ":", { silent = false }) 6 | map("n", ";", ";", "Next f/t match") 7 | 8 | -- Join lines without losing cursor position 9 | map("n", "J", "mjJ`j") 10 | 11 | -- Navigating between windows 12 | map("n", "", function() 13 | utils.navigate_pane_or_window("k") 14 | end) 15 | map("n", "", function() 16 | utils.navigate_pane_or_window("j") 17 | end) 18 | map("n", "", function() 19 | utils.navigate_pane_or_window("h") 20 | end) 21 | map("n", "", function() 22 | utils.navigate_pane_or_window("l") 23 | end) 24 | map("n", "", function() 25 | utils.navigate_pane_or_window("k") 26 | end) 27 | map("n", "", function() 28 | utils.navigate_pane_or_window("j") 29 | end) 30 | map("n", "", function() 31 | utils.navigate_pane_or_window("h") 32 | end) 33 | map("n", "", function() 34 | utils.navigate_pane_or_window("l") 35 | end) 36 | 37 | -- Moving windows 38 | map("n", "", ":wincmd K") 39 | map("n", "", ":wincmd J") 40 | map("n", "", ":wincmd H") 41 | map("n", "", ":wincmd L") 42 | map("n", "", ":wincmd K") 43 | map("n", "", ":wincmd J") 44 | map("n", "", ":wincmd H") 45 | map("n", "", ":wincmd L") 46 | 47 | -- Resizing windows 48 | map("n", "", ":resize +2") 49 | map("n", "", ":resize -2") 50 | map("n", "", ":vertical resize +2") 51 | map("n", "", ":vertical resize -2") 52 | map("n", "", ":resize +2") 53 | map("n", "", ":resize -2") 54 | map("n", "", ":vertical resize +2") 55 | map("n", "", ":vertical resize -2") 56 | 57 | -- Quick moving around while keeping the cursor fixed in middle 58 | map("n", "", "zz") 59 | map("n", "", "zz") 60 | map("n", "n", "nzzzv") 61 | map("n", "N", "Nzzzv") 62 | 63 | -- Remap for dealing with word wrap 64 | map("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true }) 65 | map("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true }) 66 | 67 | -- Buffer management 68 | map("n", "L", ":bnext") 69 | map("n", "H", ":bprevious") 70 | map("n", "qw", ":bdelete") 71 | 72 | -- Toggle wrap 73 | map("n", "w", function() 74 | vim.wo.wrap = not vim.wo.wrap 75 | vim.notify("Wrap " .. (vim.o.wrap and "on" or "off"), vim.log.levels.INFO) 76 | end, "Toggle wrap") 77 | 78 | -- Don't put text in register on delete char 79 | map({ "n", "v" }, "x", '"_x') 80 | 81 | -- Copy to system clipboard 82 | map({ "x", "n" }, "y", [["+y]], "Yank to system clipboard") 83 | 84 | -- Replicate netrw functionality (gx/gf) 85 | map("n", "gx", utils.open, "Open link or file") 86 | 87 | -- Keep visual mode indenting 88 | map("v", "<", "", ">gv") 90 | 91 | -- Select all lines 92 | map("n", "vga", "ggVG") 93 | 94 | -- Quick source/run files 95 | map("n", "X", ":source %", "Source current file") 96 | map("n", "x", ":.lua", "Run current line with lua") 97 | map("v", "x", ":lua", "Run visual selection with lua") 98 | 99 | -- Diagnostics 100 | map("n", "td", function() 101 | local is_enabled = vim.diagnostic.is_enabled() 102 | vim.diagnostic.enable(not is_enabled) 103 | vim.notify( 104 | "[LSP] " .. (is_enabled and "Disabled" or "Enabled") .. " diagnostics." 105 | ) 106 | end, "Toggle diagnostics") 107 | 108 | -- Make to actually escape from terminal mode 109 | map("t", "", "") 110 | 111 | -- `dd` but don't yank if the line is empty 112 | map("n", "dd", function() 113 | if vim.api.nvim_get_current_line():match("^%s*$") then 114 | return [["_dd]] 115 | else 116 | return [[dd]] 117 | end 118 | end, { expr = true }) 119 | 120 | -- Toggle highlights 121 | map("n", "ts", ":set hlsearch!", "Toggle search highlighting") 122 | map("n", "tw", function() 123 | if vim.w.whitespace_highlight == true then 124 | vim.cmd("highlight clear Tabs") 125 | vim.cmd("highlight clear ExtraWhitespace") 126 | vim.notify("Disabled whitespace highlighting!") 127 | else 128 | vim.cmd([[ highlight Tabs ctermbg=yellow guibg=yellow ]]) 129 | vim.cmd([[ highlight ExtraWhitespace ctermbg=red guibg=red ]]) 130 | vim.notify("Enabled whitespace highlighting!") 131 | end 132 | vim.w.whitespace_highlight = not vim.w.whitespace_highlight 133 | end, "Toggle whitespace highlighting") 134 | 135 | --- Few mappings I stole from @akinsho :) 136 | ---@see https://github.com/akinsho/dotfiles/blob/main/.config/nvim/ 137 | 138 | -- Quick find and replace 139 | map( 140 | "v", 141 | "rr", 142 | [[:'<,'>s//]], 143 | { desc = "Within visually selected area", silent = false } 144 | ) 145 | map( 146 | "n", 147 | "rr", 148 | [[:%s//]], 149 | { desc = "Replace text", silent = false } 150 | ) 151 | map( 152 | "v", 153 | "rw", 154 | [["zy:%s/"/]], 155 | { desc = "Visually selected text", silent = false } 156 | ) 157 | map( 158 | "n", 159 | "rw", 160 | [[:%s/\<=expand("")\>/]], 161 | { desc = "Replace word under cursor", silent = false } 162 | ) 163 | 164 | -- Search visual selection 165 | -- map("v", "//", [[y/"]]) 166 | 167 | -- Multiple Cursor Replacement 168 | ---@see http://www.kevinli.co/posts/2017-01-19-multiple-cursors-in-500-bytes-of-vimscript/ 169 | -- 1. Position the cursor over a word; alternatively, make a selection. 170 | -- 2. Hit cq to start recording the macro. 171 | -- 3. Once you are done with the macro, go back to normal mode. 172 | -- 4. Hit Enter to repeat the macro over search matches. 173 | function Setup_CR() 174 | map( 175 | "n", 176 | "", 177 | [[:nnoremap Enter> n@zq:let @z=strpart(@z,0,strlen(@z)-1)n@z]], 178 | { buffer = true } 179 | ) 180 | end 181 | vim.g.mc = [[y/\V=escape(@", '/')]] 182 | 183 | map("n", "cn", "*``cgn") 184 | map("n", "cN", "*``cgN") 185 | 186 | -- xnoremap("cn", [[g:mc . "``cgn"]], { expr = true }) 187 | -- xnoremap("cN", [[g:mc . "``cgN"]], { expr = true }) 188 | 189 | map("n", "cq", [[:\call v:lua.Setup_CR()*``qz]]) 190 | map("n", "cQ", [[:\call v:lua.Setup_CR()#``qz]]) 191 | 192 | -- xnoremap( 193 | -- "cq", 194 | -- [[":\call v:lua.Setup_CR()gv" . g:mc . "``qz"]], 195 | -- { expr = true } 196 | -- ) 197 | -- xnoremap( 198 | -- "cQ", 199 | -- [[":\call v:lua.Setup_CR()gv" . substitute(g:mc, '/', '?', 'g') . "``qz"]], 200 | -- { expr = true } 201 | -- ) 202 | -------------------------------------------------------------------------------- /config/nvim/lua/core/options.lua: -------------------------------------------------------------------------------- 1 | local set = vim.o 2 | local opt = vim.opt 3 | 4 | -- Disable backup 5 | set.writebackup = false 6 | set.backup = false 7 | 8 | -- Preserve indentation while wrapping 9 | set.breakindent = true 10 | 11 | -- Set command panel height 12 | set.cmdheight = 2 13 | 14 | -- Highlight column and current line number 15 | set.colorcolumn = "80" 16 | set.cursorline = true 17 | 18 | -- Disable search highlighting 19 | set.hlsearch = false 20 | 21 | -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term 22 | set.ignorecase = true 23 | set.smartcase = true 24 | 25 | -- Enable global statusline 26 | set.laststatus = 3 27 | 28 | -- Don't redrawn while executing macros 29 | set.lazyredraw = true 30 | 31 | -- Show relative line numbers 32 | set.number = true 33 | set.numberwidth = 2 34 | set.relativenumber = true 35 | 36 | -- Don't show the mode, since it's already in the status line 37 | set.showmode = false 38 | 39 | -- Scroll offset 40 | set.scrolloff = 5 41 | set.spellfile = vim.fn.stdpath("config") .. "/spell/en.utf-8.add" 42 | 43 | -- Splits windows to the right by default 44 | set.splitright = true 45 | 46 | -- Don't highlight stuff that's longer than 200 columns 47 | set.synmaxcol = 200 48 | 49 | -- Ignore these directories/files while expanding `find` searches 50 | opt.wildignore:append({ 51 | "*.o", 52 | "*.pyc", 53 | "*/.git/*", 54 | "*/node_modules/*", 55 | "*pycache*", 56 | "*~", 57 | "*.gif", 58 | "*.avi", 59 | "*.ico", 60 | "*.jpeg", 61 | "*.jpg", 62 | "*.png", 63 | "*.wav", 64 | }) 65 | 66 | -- Ignore case while completing file 67 | set.wildignorecase = true 68 | 69 | -- Add rounded borders to floating windows by default 70 | -- set.winborder = "rounded" 71 | 72 | -- Do not wrap code by default 73 | set.wrap = false 74 | 75 | -- Set window title appropriately 76 | set.title = true 77 | 78 | -- Enable a subtle transparency effect on pop-up menu 79 | set.pumblend = 15 80 | 81 | -- Reserve space for atleast two signs 82 | set.signcolumn = "yes:2" 83 | 84 | -- Enable undo file 85 | set.undofile = true 86 | 87 | -- Set 88 | vim.g.mapleader = " " 89 | 90 | -- Set 91 | vim.g.maplocalleader = "," 92 | 93 | -- Indentation 94 | set.expandtab = true -- Expand to spaces 95 | set.shiftwidth = 2 -- Indents (`>>`, `<<`, etc) inserts this much width 96 | set.softtabstop = 2 -- Sets the number of columns for a 97 | set.tabstop = 2 -- The width of 98 | -------------------------------------------------------------------------------- /config/nvim/lua/core/plugins.lua: -------------------------------------------------------------------------------- 1 | local env = require("core.env") 2 | if env.NVIM_USER_ONLY_CORE then 3 | return 4 | end 5 | 6 | -- Bootstrap lazy.nvim 7 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 8 | if not vim.uv.fs_stat(lazypath) then 9 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 10 | local out = vim.fn.system({ 11 | "git", 12 | "clone", 13 | "--filter=blob:none", 14 | "--branch=stable", 15 | lazyrepo, 16 | lazypath, 17 | }) 18 | if vim.v.shell_error ~= 0 then 19 | vim.api.nvim_echo({ 20 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 21 | { out, "WarningMsg" }, 22 | { "\nPress any key to exit..." }, 23 | }, true, {}) 24 | vim.fn.getchar() 25 | os.exit(1) 26 | end 27 | end 28 | vim.opt.rtp:prepend(lazypath) 29 | 30 | -- Disable neovim providers 31 | local disabled_provider = { 32 | "node", 33 | "perl", 34 | "python", 35 | "python3", 36 | "pythonx", 37 | "ruby", 38 | } 39 | 40 | for _, d in pairs(disabled_provider) do 41 | vim.g["loaded_" .. d .. "_provider"] = 0 42 | end 43 | 44 | require("lazy").setup("plugins", { 45 | ui = { border = "rounded" }, 46 | defaults = { 47 | --lazy = true 48 | }, 49 | dev = { 50 | path = "~/dev", 51 | }, 52 | change_detection = { 53 | notify = false, 54 | }, 55 | rocks = { 56 | enabled = false, 57 | }, 58 | performance = { 59 | rtp = { 60 | disabled_plugins = { 61 | "tohtml", 62 | "gzip", 63 | "matchit", 64 | "netrw", 65 | "netrwFileHandlers", 66 | "netrwPlugin", 67 | "netrwSettings", 68 | "tar", 69 | "tarPlugin", 70 | "tutor", 71 | "tutor_mode_plugin", 72 | "zip", 73 | "zipPlugin", 74 | }, 75 | }, 76 | }, 77 | }) 78 | -------------------------------------------------------------------------------- /config/nvim/lua/core/utils.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | --- Creates a keymap 4 | ---@param mode string|string[] 5 | ---@param key string 6 | ---@param cmd string|function 7 | ---@param opts string|vim.keymap.set.Opts|nil 8 | function M.map(mode, key, cmd, opts) 9 | local final_opts 10 | if type(opts) == "string" then 11 | final_opts = { desc = opts, silent = true } 12 | else 13 | final_opts = vim.tbl_extend("keep", opts or {}, { silent = true }) 14 | end 15 | vim.keymap.set(mode, key, cmd, final_opts) 16 | end 17 | 18 | --- Navigate to the given direction if there exists a window in that direction 19 | --- else redirects the direction to `wezterm` to change the active pane 20 | ---@param direction string 21 | function M.navigate_pane_or_window(direction) 22 | local current_winnr = vim.fn.winnr() 23 | local wezterm_direction = { h = "Left", j = "Down", k = "Up", l = "Right" } 24 | if current_winnr ~= vim.fn.winnr(direction) then 25 | vim.cmd("wincmd " .. direction) 26 | else 27 | vim.system({ 28 | "wezterm", 29 | "cli", 30 | "activate-pane-direction", 31 | wezterm_direction[direction], 32 | }) 33 | end 34 | end 35 | 36 | --- Open the current file/word under cursor in vim if it exists else open it via xdg_open 37 | function M.open() 38 | local file = vim.fn.expand("") 39 | if file:match("https?://") then 40 | return vim.ui.open(file) 41 | end 42 | 43 | if vim.fn.filereadable(vim.fn.expand(file)) > 0 then 44 | return vim.cmd("edit " .. file) 45 | end 46 | 47 | -- consider anything that looks like string/string a github link 48 | local plugin_url_regex = "[%a%d%-%.%_]*%/[%a%d%-%.%_]*" 49 | local link = string.match(file, plugin_url_regex) 50 | if link then 51 | return vim.ui.open(string.format("https://www.github.com/%s", link)) 52 | end 53 | 54 | -- fallback to system open 55 | local _, err = vim.ui.open(file) 56 | if err then 57 | vim.notify(err, vim.log.levels.ERROR) 58 | end 59 | end 60 | 61 | --- Get language from the current cursor position 62 | function M.get_lang_from_cursor_pos() 63 | local has_parser, parser = pcall(vim.treesitter.get_parser) 64 | 65 | -- If no parser is found then just return the current filetype instead of failing 66 | if not has_parser then 67 | return vim.bo.filetype 68 | end 69 | 70 | local cursor = vim.api.nvim_win_get_cursor(0) 71 | cursor[1] = cursor[1] - 1 -- treesitter nodes are 0-indexed 72 | 73 | return parser 74 | :language_for_range({ 75 | cursor[1], 76 | cursor[2], 77 | cursor[1], 78 | cursor[2], 79 | }) 80 | :lang() 81 | end 82 | 83 | --- Common string utilities 84 | ---@see https://github.com/tbastos/lift/blob/master/lift/string.lua 85 | 86 | --- Returns a capitilzed string 87 | ---@param str string 88 | local function capitalize(str) 89 | return str:gsub("^%l", string.upper) 90 | end 91 | 92 | --- Converts a string to camelCase 93 | ---@param str string 94 | local function to_camel_case(str) 95 | return str:gsub("%W+(%w+)", capitalize) 96 | end 97 | 98 | --- Converts a string to PascalCase 99 | ---@param str string 100 | local function to_pascal_case(str) 101 | return str:gsub("%W*(%w+)", capitalize) 102 | end 103 | 104 | local function basename(str) 105 | return str:gsub("(.*)/(.*)", "%2") 106 | end 107 | 108 | M.string_utils = { 109 | capitalize = capitalize, 110 | to_camel_case = to_camel_case, 111 | to_pascal_case = to_pascal_case, 112 | basename = basename, 113 | } 114 | 115 | return M 116 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/alpha.lua: -------------------------------------------------------------------------------- 1 | local icons = require("core.icons") 2 | return { 3 | "goolord/alpha-nvim", 4 | event = "VimEnter", 5 | config = function() 6 | local alpha = require("alpha") 7 | local dashboard = require("alpha.themes.dashboard") 8 | 9 | local function pick_color() 10 | math.randomseed(os.time()) 11 | local colors = { "String", "Identifier", "Keyword", "Number" } 12 | return colors[math.random(#colors)] 13 | end 14 | 15 | local function footer() 16 | local stats = require("lazy").stats() 17 | local total_plugins = 18 | string.format("%s %s plugins", icons.devicons.download, stats.count) 19 | local ver = vim.version() 20 | local ver_info = string.format( 21 | "%s v%s.%s.%s", 22 | icons.diagnostics.info, 23 | ver.major, 24 | ver.minor, 25 | ver.patch 26 | ) 27 | local startuptime = string.format( 28 | "%s %sms startup", 29 | icons.devicons.flash, 30 | math.floor(stats.startuptime * 100) / 100 31 | ) 32 | 33 | return string.format( 34 | "%s %s %s", 35 | startuptime, 36 | total_plugins, 37 | ver_info 38 | ) 39 | end 40 | 41 | local logo = { 42 | " ", 43 | " ███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ ", 44 | " ████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║ ", 45 | " ██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║ ", 46 | " ██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ", 47 | " ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ", 48 | " ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ ", 49 | " ", 50 | } 51 | 52 | dashboard.section.header.val = logo 53 | dashboard.section.header.opts.hl = pick_color() 54 | dashboard.section.buttons.val = { 55 | dashboard.button( 56 | "n", 57 | string.format("%s New file", icons.devicons.file), 58 | ":ene startinsert " 59 | ), 60 | dashboard.button( 61 | "SPC f v", 62 | string.format("%s Find File", icons.devicons.search) 63 | ), 64 | dashboard.button( 65 | "SPC f o", 66 | string.format("%s Recent files", icons.devicons.files) 67 | ), 68 | dashboard.button( 69 | "", 70 | string.format("%s NvimTree", icons.devicons.folder) 71 | ), 72 | dashboard.button( 73 | "pu", 74 | string.format("%s Lazy Update", icons.devicons.update), 75 | "Lazy update" 76 | ), 77 | dashboard.button( 78 | "ps", 79 | string.format("%s Lazy Show", icons.devicons.check), 80 | "Lazy show" 81 | ), 82 | dashboard.button( 83 | "pp", 84 | string.format("%s Lazy Profile", icons.devicons.speedometer), 85 | "Lazy profile" 86 | ), 87 | dashboard.button( 88 | "ch", 89 | string.format("%s Check Health", icons.devicons.plus_circle), 90 | "checkhealth" 91 | ), 92 | dashboard.button( 93 | "q", 94 | string.format("%s Quit", icons.diagnostics.error), 95 | ":qa" 96 | ), 97 | } 98 | dashboard.section.footer.val = footer() 99 | dashboard.section.footer.opts.hl = "Constant" 100 | 101 | alpha.setup(dashboard.opts) 102 | 103 | vim.api.nvim_create_autocmd("User", { 104 | pattern = "LazyVimStarted", 105 | callback = function() 106 | dashboard.section.footer.val = footer() 107 | pcall(vim.cmd.AlphaRedraw) 108 | end, 109 | }) 110 | end, 111 | } 112 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/bufferline.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "akinsho/bufferline.nvim", 3 | event = "VeryLazy", 4 | opts = { 5 | options = { 6 | diagnostics = "nvim_lsp", 7 | separator_style = "thick", 8 | offsets = { { filetype = "NvimTree", text = "File Explorer" } }, 9 | }, 10 | highlights = { 11 | -- Color of current selected buffer 12 | close_button_selected = { 13 | fg = { 14 | attribute = "fg", 15 | highlight = "Error", 16 | }, 17 | }, 18 | }, 19 | }, 20 | keys = { 21 | -- Mappings 22 | { "L", "BufferLineCycleNext" }, 23 | { "H", "BufferLineCyclePrev" }, 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/codecompanion.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | { 4 | "olimorris/codecompanion.nvim", 5 | dependencies = { 6 | "nvim-lua/plenary.nvim", 7 | "nvim-treesitter/nvim-treesitter", 8 | }, 9 | keys = { 10 | { mode = { "n", "v" }, "ai", "CodeCompanion" }, 11 | { mode = { "n", "v" }, "aa", "CodeCompanionActions" }, 12 | { 13 | mode = { "n", "v" }, 14 | "ac", 15 | "CodeCompanionChat Toggle", 16 | }, 17 | }, 18 | opts = { 19 | -- strategies = { 20 | -- chat = { adapter = "anthropic" }, 21 | -- inline = { adapter = "anthropic" }, 22 | -- }, 23 | }, 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/colorizer.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "NvChad/nvim-colorizer.lua", 3 | cmd = "ColorizerAttachToBuffer", 4 | ft = { "css", "scss" }, 5 | opts = { 6 | filetypes = { "*" }, 7 | user_default_options = { 8 | RGB = true, -- #RGB hex codes 9 | RRGGBB = true, -- #RRGGBB hex codes 10 | names = true, -- "Name" codes like Blue 11 | RRGGBBAA = true, -- #RRGGBBAA hex codes 12 | rgb_fn = true, -- CSS rgb() and rgba() functions 13 | hsl_fn = true, -- CSS hsl() and hsla() functions 14 | css = true, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB 15 | css_fn = true, -- Enable all CSS *functions*: rgb_fn, hsl_fn 16 | }, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/colorscheme.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "catppuccin/nvim", 4 | name = "catppuccin", 5 | priority = 1000, 6 | ---@type CatppuccinOptions 7 | opts = { 8 | no_italic = true, 9 | 10 | -- use lighter color for comments so that I can actually *see* them 11 | highlight_overrides = { 12 | mocha = function(colors) 13 | return { 14 | WinSeparator = { fg = colors.overlay1 }, 15 | Folded = { bg = colors.surface0 }, 16 | } 17 | end, 18 | }, 19 | 20 | integrations = { 21 | fidget = true, 22 | leap = true, 23 | lsp_trouble = true, 24 | mason = true, 25 | neotest = true, 26 | telescope = { enabled = true, style = "nvchad" }, 27 | which_key = true, 28 | }, 29 | }, 30 | config = function(_, opts) 31 | require("catppuccin").setup(opts) 32 | vim.cmd("colorscheme catppuccin") 33 | end, 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/comment.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "numToStr/Comment.nvim", 3 | keys = { 4 | "gcc", 5 | "gbc", 6 | { "gc", mode = "v" }, 7 | { "gb", mode = "v" }, 8 | }, 9 | dependencies = { 10 | -- better comment support for jsx/tsx 11 | { 12 | "JoosepAlviste/nvim-ts-context-commentstring", 13 | config = function() 14 | vim.g.skip_ts_context_commentstring_module = true 15 | require("ts_context_commentstring").setup({ 16 | enable_autocmd = false, 17 | }) 18 | end, 19 | }, 20 | }, 21 | config = function() 22 | require("Comment").setup({ 23 | pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(), 24 | }) 25 | end, 26 | } 27 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/conform.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | "stevearc/conform.nvim", 4 | event = { "BufReadPost", "BufNewFile" }, 5 | dependencies = { "mason.nvim" }, 6 | config = function() 7 | local map = require("core.utils").map 8 | local conform = require("conform") 9 | local ignore_filetypes = {} 10 | vim.g.format_on_save = true 11 | vim.o.formatexpr = "v:lua.require'conform'.formatexpr()" 12 | 13 | map({ "n", "v" }, "F", function() 14 | require("conform").format({ 15 | formatters = { "injected" }, 16 | timeout_ms = 3000, 17 | }) 18 | end, "Format injected") 19 | 20 | map({ "n", "v" }, "f", function() 21 | require("conform").format() 22 | end, "Format") 23 | 24 | vim.api.nvim_create_autocmd({ "BufEnter" }, { 25 | group = vim.api.nvim_create_augroup( 26 | "user.plugin.conform", 27 | { clear = true } 28 | ), 29 | callback = function(args) 30 | local available_formatters = 31 | require("conform").list_formatters(args.buf) 32 | 33 | if #available_formatters > 0 then 34 | vim.b[args.buf].format_on_save = true 35 | end 36 | end, 37 | desc = "Enable format on save", 38 | }) 39 | 40 | vim.api.nvim_create_user_command("UserAutoFormatToggle", function(args) 41 | local ref = vim.g 42 | local scope = "globally" 43 | if args.bang then 44 | -- UserAutoFormatToggle! will disable formatting for current buffer 45 | ref = vim.b 46 | scope = "locally" 47 | end 48 | 49 | if not ref.format_on_save then 50 | ref.format_on_save = true 51 | else 52 | ref.format_on_save = false 53 | end 54 | 55 | vim.notify( 56 | string.format( 57 | "%s auto-formatting %s", 58 | ref.format_on_save and "Enabled" or "Disabled", 59 | scope 60 | ) 61 | ) 62 | end, { desc = "Toggle auto-formatting", bang = true }) 63 | 64 | ---@type conform.FiletypeFormatter 65 | local prettier = { 66 | "prettierd", 67 | "prettier", 68 | stop_after_first = true, 69 | } 70 | 71 | conform.setup({ 72 | -- log_level = vim.log.levels.DEBUG, 73 | formatters_by_ft = { 74 | bash = { "shfmt" }, 75 | css = prettier, 76 | html = prettier, 77 | javascript = prettier, 78 | javascriptreact = prettier, 79 | json = prettier, 80 | jsonc = prettier, 81 | lua = { "stylua" }, 82 | markdown = prettier, 83 | sass = prettier, 84 | scss = prettier, 85 | sh = { "shfmt" }, 86 | typescript = prettier, 87 | typescriptreact = prettier, 88 | yaml = prettier, 89 | -- run on files that don't have other formatters configured 90 | ["_"] = { "trim_newlines", "trim_whitespace" }, 91 | }, 92 | formatters = { 93 | shfmt = { 94 | append_args = { 95 | "-ci", -- format case statements 96 | "-i", 97 | "4", -- indents will have width of 4 spaces 98 | }, 99 | }, 100 | injected = { 101 | options = { 102 | ignore_errors = true, 103 | }, 104 | }, 105 | }, 106 | format_on_save = function(bufnr) 107 | -- Disable autoformat if turned off 108 | if not vim.g.format_on_save or not vim.b[bufnr].format_on_save then 109 | return 110 | end 111 | 112 | -- Disable autoformat on certain filetypes 113 | if vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype) then 114 | return 115 | end 116 | 117 | return { 118 | -- These options will be passed to conform.format() 119 | timeout_ms = 3000, 120 | lsp_format = "fallback", 121 | } 122 | end, 123 | -- log_level = vim.log.levels.DEBUG, 124 | notify_on_error = true, 125 | }) 126 | end, 127 | } 128 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/extras.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | 4 | -- Icons provider 5 | { "kyazdani42/nvim-web-devicons", lazy = true }, 6 | 7 | -- library used by other plugins 8 | { "nvim-lua/plenary.nvim", lazy = true }, 9 | 10 | -- Undo tree 11 | { "mbbill/undotree", cmd = "UndotreeToggle" }, 12 | 13 | -- Git plugin 14 | { 15 | "tpope/vim-fugitive", 16 | cmd = { "Git", "Gstatus", "Gblame", "Gpush", "Gpull", "G" }, 17 | }, 18 | 19 | -- Surrounding stuff efficiently 20 | { 21 | "kylechui/nvim-surround", 22 | event = { "BufReadPost", "BufNewFile" }, 23 | config = true, 24 | }, 25 | 26 | -- Rainbow brackets 27 | { 28 | "HiPhish/rainbow-delimiters.nvim", 29 | event = { "BufReadPost", "BufNewFile" }, 30 | dependencies = { "nvim-treesitter" }, 31 | submodules = false, 32 | config = function() 33 | vim.api.nvim_create_user_command("RainbowDelimitersToggle", function() 34 | require("rainbow-delimiters").toggle(0) 35 | end, { desc = "Toggle Rainbow Delimiters" }) 36 | 37 | vim.g.rainbow_delimiters = { 38 | -- log = { 39 | -- level = vim.log.levels.TRACE, 40 | -- }, 41 | blacklist = { "html", "lua", "json" }, 42 | } 43 | end, 44 | }, 45 | 46 | -- Session management 47 | { 48 | "folke/persistence.nvim", 49 | event = "BufReadPre", 50 | keys = { 51 | { 52 | "so", 53 | function() 54 | require("persistence").load() 55 | end, 56 | desc = "Load session for current directory", 57 | }, 58 | { 59 | "sl", 60 | function() 61 | require("persistence").load({ last = true }) 62 | end, 63 | desc = "Load last session", 64 | }, 65 | { 66 | "sq", 67 | function() 68 | require("persistence").stop() 69 | end, 70 | desc = "Stop session", 71 | }, 72 | }, 73 | config = true, 74 | }, 75 | } 76 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/fidget.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | "j-hui/fidget.nvim", 4 | event = "BufReadPost", 5 | opts = { 6 | notification = { 7 | window = { 8 | winblend = 25, 9 | }, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/flash.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | -- Blazingly fast movements 4 | "folke/flash.nvim", 5 | keys = { 6 | { 7 | "s", 8 | mode = { "n", "o" }, 9 | function() 10 | require("flash").jump() 11 | end, 12 | desc = "Flash", 13 | }, 14 | -- { 15 | -- "S", 16 | -- mode = { "n", "x", "o" }, 17 | -- function() 18 | -- require("flash").treesitter() 19 | -- end, 20 | -- desc = "Flash Treesitter", 21 | -- }, 22 | -- { 23 | -- "R", 24 | -- mode = { "o", "x" }, 25 | -- function() 26 | -- require("flash").treesitter_search() 27 | -- end, 28 | -- desc = "Treesitter Search", 29 | -- }, 30 | { 31 | "r", 32 | mode = "o", 33 | function() 34 | require("flash").remote() 35 | end, 36 | desc = "Remote Flash", 37 | }, 38 | { 39 | "", 40 | mode = { "c" }, 41 | function() 42 | require("flash").toggle() 43 | end, 44 | desc = "Toggle Flash Search", 45 | }, 46 | }, 47 | } 48 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/gitsigns.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "lewis6991/gitsigns.nvim", 3 | event = "BufReadPre", 4 | opts = { 5 | max_file_length = 5000, 6 | preview_config = { border = "rounded" }, 7 | on_attach = function(bufnr) 8 | local gs = require("gitsigns") 9 | local map = require("core.utils").map 10 | 11 | -- Mappings 12 | map("n", "]c", function() 13 | if vim.wo.diff then 14 | return "]c" 15 | end 16 | vim.schedule(function() 17 | gs.nav_hunk("next") 18 | end) 19 | return "" 20 | end, { desc = "Go to next hunk", expr = true, buffer = bufnr }) 21 | 22 | map("n", "[c", function() 23 | if vim.wo.diff then 24 | return "[c" 25 | end 26 | vim.schedule(function() 27 | gs.nav_hunk("prev") 28 | end) 29 | return "" 30 | end, { desc = "Go to prev hunk", expr = true, buffer = bufnr }) 31 | 32 | map("n", "gs", gs.stage_hunk, "Stage hunk") 33 | map("v", "gs", function() 34 | gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) 35 | end, "Stage hunk") 36 | map("n", "gS", gs.stage_buffer, "Stage buffer") 37 | map("n", "gu", gs.undo_stage_hunk, "Undo stage hunk") 38 | map("n", "gr", gs.reset_hunk, "Reset hunk") 39 | map("n", "gR", gs.reset_buffer, "Reset buffer") 40 | map("n", "gp", gs.preview_hunk, "Preview hunk") 41 | map("n", "gd", gs.diffthis, "Diffthis") 42 | -- map('n',"gD", function() 43 | -- gs.diffthis("~") 44 | -- end, { desc = "Diffthis" }) 45 | map("n", "gb", gs.blame_line, "Toggle line blame") 46 | end, 47 | }, 48 | } 49 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/indent-blankline.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- indent/scope highlighting 3 | "lukas-reineke/indent-blankline.nvim", 4 | dependencies = { "nvim-treesitter" }, 5 | event = { "BufReadPost", "BufNewFile" }, 6 | main = "ibl", 7 | opts = { 8 | -- char list for different indentation level 9 | indent = { 10 | char = { "|", "¦", "┆", "┊" }, 11 | -- char = { "│" }, 12 | }, 13 | 14 | exclude = { 15 | filetypes = { 16 | "NvimTree", 17 | "markdown", 18 | "startify", 19 | }, 20 | }, 21 | 22 | scope = { 23 | show_start = false, 24 | show_end = false, 25 | }, 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/kulala.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | "mistweaverco/kulala.nvim", 4 | ft = { "http", "rest" }, 5 | submodules = false, 6 | keys = { 7 | { mode = { "n", "v" }, "Rs", desc = "Send request" }, 8 | { mode = { "n", "v" }, "Ra", desc = "Send all requests" }, 9 | { "Rb", desc = "Open scratchpad" }, 10 | }, 11 | opts = { 12 | global_keymaps = true, 13 | global_keymaps_prefix = "R", 14 | kulala_keymaps_prefix = "", 15 | request_timeout = 10000, 16 | ui = { 17 | split_direction = "horizontal", 18 | scratchpad_default_contents = { 19 | "GET https://httpbin.org/get HTTP/1.1", 20 | "Accept: application/json", 21 | "Content-Type: application/json", 22 | }, 23 | }, 24 | kulala_keymaps = { 25 | ["Show headers"] = { 26 | "h", 27 | function() 28 | require("kulala.ui").show_headers() 29 | end, 30 | }, 31 | ["Show body"] = { 32 | "b", 33 | function() 34 | require("kulala.ui").show_body() 35 | end, 36 | }, 37 | ["Show headers and body"] = { 38 | "a", 39 | function() 40 | require("kulala.ui").show_headers_body() 41 | end, 42 | }, 43 | ["Show verbose"] = { 44 | "v", 45 | function() 46 | require("kulala.ui").show_verbose() 47 | end, 48 | }, 49 | ["Show script output"] = { 50 | "o", 51 | function() 52 | require("kulala.ui").show_script_output() 53 | end, 54 | }, 55 | ["Show stats"] = { 56 | "s", 57 | function() 58 | require("kulala.ui").show_stats() 59 | end, 60 | }, 61 | ["Show report"] = { 62 | "r", 63 | function() 64 | require("kulala.ui").show_report() 65 | end, 66 | }, 67 | }, 68 | }, 69 | } 70 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lsp/autocmds.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local autocmd = vim.api.nvim_create_autocmd 4 | M.lsp_attach_augroup_id = vim.api.nvim_create_augroup("user.lsp.attach", {}) 5 | M.lsp_detach_augroup_id = vim.api.nvim_create_augroup("user.lsp.detach", {}) 6 | 7 | M.attach = function(args) 8 | local bufnr = args.buf 9 | local client = vim.lsp.get_client_by_id(args.data.client_id) 10 | local methods = vim.lsp.protocol.Methods 11 | local highlight_augroup_id = 12 | vim.api.nvim_create_augroup("user.lsp.document-highlight", {}) 13 | 14 | if not client then 15 | return 16 | end 17 | 18 | if client:supports_method(methods.textDocument_documentHighlight) then 19 | autocmd({ "CursorHold", "CursorHoldI" }, { 20 | group = highlight_augroup_id, 21 | buffer = bufnr, 22 | callback = vim.lsp.buf.document_highlight, 23 | desc = "Highlights symbol under cursor", 24 | }) 25 | 26 | autocmd("CursorMoved", { 27 | group = highlight_augroup_id, 28 | buffer = bufnr, 29 | callback = vim.lsp.buf.clear_references, 30 | desc = "Clears symbol highlighting under cursor", 31 | }) 32 | 33 | autocmd("LspDetach", { 34 | group = M.lsp_detach_augroup_id, 35 | callback = function(e) 36 | vim.lsp.buf.clear_references() 37 | vim.api.nvim_clear_autocmds({ 38 | group = highlight_augroup_id, 39 | buffer = e.buf, 40 | }) 41 | end, 42 | }) 43 | end 44 | end 45 | 46 | return M 47 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lsp/diagnostics.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local icons = require("core.icons").diagnostics 3 | 4 | -- Diagnostic signs and highlight group 5 | local diagnostics_signs = { 6 | [vim.diagnostic.severity.ERROR] = { 7 | sign = string.format("%s ", icons.error), 8 | hl_group = "DiagnosticSignError", 9 | }, 10 | [vim.diagnostic.severity.WARN] = { 11 | sign = string.format("%s ", icons.warning), 12 | hl_group = "DiagnosticSignWarn", 13 | }, 14 | [vim.diagnostic.severity.HINT] = { 15 | sign = string.format("%s ", icons.hint), 16 | hl_group = "DiagnosticSignHint", 17 | }, 18 | [vim.diagnostic.severity.INFO] = { 19 | sign = string.format("%s ", icons.info), 20 | hl_group = "DiagnosticSignInfo", 21 | }, 22 | } 23 | 24 | ---@param diagnostic lsp.Diagnostic 25 | local diagnostics_prefix = function(diagnostic) 26 | local severity = diagnostics_signs[diagnostic.severity] 27 | return severity.sign, severity.hl_group 28 | end 29 | 30 | function M.setup() 31 | local signs = { text = {} } 32 | for severity, config in pairs(diagnostics_signs) do 33 | signs.text[severity] = config.sign 34 | end 35 | 36 | -- Global diagnostic config 37 | vim.diagnostic.config({ 38 | jump = { float = true }, 39 | signs = signs, 40 | virtual_text = { source = "if_many", prefix = diagnostics_prefix }, 41 | float = { 42 | max_width = 85, 43 | max_height = 30, 44 | border = "rounded", 45 | prefix = diagnostics_prefix, 46 | scope = "line", 47 | source = true, 48 | }, 49 | underline = { 50 | -- Do not underline text when severity is low (INFO or HINT). 51 | severity = { min = vim.diagnostic.severity.WARN }, 52 | }, 53 | }) 54 | end 55 | 56 | return M 57 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lsp/init.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | { 4 | "neovim/nvim-lspconfig", 5 | dependencies = { "mason-org/mason.nvim" }, 6 | config = function() 7 | local lsp_diagnostics = require("plugins.lsp.diagnostics") 8 | local lsp_autocmds = require("plugins.lsp.autocmds") 9 | local lsp_mappings = require("plugins.lsp.mappings") 10 | 11 | -- Update capabilities 12 | local capabilities = vim.lsp.protocol.make_client_capabilities() 13 | capabilities = vim.tbl_deep_extend( 14 | "force", 15 | capabilities, 16 | require("cmp_nvim_lsp").default_capabilities() 17 | ) 18 | 19 | -- Setup diagnostics config 20 | lsp_diagnostics.setup() 21 | 22 | -- Attach callbacks 23 | vim.api.nvim_create_autocmd("LspAttach", { 24 | group = lsp_autocmds.lsp_attach_augroup_id, 25 | callback = function(args) 26 | lsp_autocmds.attach(args) 27 | lsp_mappings.attach(args) 28 | end, 29 | }) 30 | end, 31 | }, 32 | 33 | -- LSP, Formatters, DAP installer 34 | { 35 | "mason-org/mason.nvim", 36 | build = ":MasonUpdate", 37 | ---@type MasonSettings 38 | opts = { 39 | ui = { 40 | border = "rounded", 41 | icons = { 42 | package_installed = "✓", 43 | package_pending = "➜", 44 | package_uninstalled = "✗", 45 | }, 46 | }, 47 | }, 48 | }, 49 | { 50 | "mason-org/mason-lspconfig.nvim", 51 | dependencies = { "mason-org/mason.nvim" }, 52 | config = function() 53 | local lsp_servers = require("plugins.lsp.packages").get_lsp_servers() 54 | require("mason-lspconfig").setup({ 55 | automatic_enable = lsp_servers, 56 | ensure_installed = lsp_servers, 57 | }) 58 | end, 59 | }, 60 | 61 | -- Typescript server utils 62 | { 63 | "yioneko/nvim-vtsls", 64 | ft = { 65 | "javascript", 66 | "javascriptreact", 67 | "typescript", 68 | "typescriptreact", 69 | }, 70 | dependencies = { "nvim-lspconfig" }, 71 | enabled = function() 72 | local env = require("core.env") 73 | return not env.NVIM_USER_USE_TS_LS 74 | end, 75 | }, 76 | 77 | -- Neovim API completions 78 | { 79 | "folke/lazydev.nvim", 80 | ft = "lua", 81 | opts = { 82 | library = { 83 | { path = "luvit-meta/library", words = { "vim%.uv" } }, 84 | "lazy.nvim", 85 | }, 86 | }, 87 | }, 88 | 89 | -- libuv types 90 | { "Bilal2453/luvit-meta", lazy = true }, 91 | 92 | -- schemas 93 | { "b0o/schemastore.nvim", lazy = true }, 94 | } 95 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lsp/mappings.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local map = require("core.utils").map 3 | local methods = vim.lsp.protocol.Methods 4 | 5 | M.attach = function(args) 6 | local client = vim.lsp.get_client_by_id(args.data.client_id) 7 | if not client then 8 | return 9 | end 10 | 11 | local bufnr = args.buf 12 | local lsp_utils = require("plugins.lsp.utils") 13 | 14 | map( 15 | "n", 16 | "wa", 17 | vim.lsp.buf.add_workspace_folder, 18 | { buffer = bufnr, desc = "LSP: Add workspace folder" } 19 | ) 20 | map( 21 | "n", 22 | "wr", 23 | vim.lsp.buf.remove_workspace_folder, 24 | { buffer = bufnr, desc = "LSP: Remove workspace folder" } 25 | ) 26 | map("n", "wl", function() 27 | print(vim.inspect(vim.lsp.buf.list_workspace_folders())) 28 | end, { buffer = bufnr, desc = "LSP: Print workspace folders" }) 29 | 30 | map( 31 | "n", 32 | "gD", 33 | vim.lsp.buf.declaration, 34 | { buffer = bufnr, desc = "LSP: Go to declaration" } 35 | ) 36 | map( 37 | "n", 38 | "gd", 39 | vim.lsp.buf.definition, 40 | { buffer = bufnr, desc = "LSP: Go to definition" } 41 | ) 42 | 43 | map( 44 | "n", 45 | "grt", 46 | vim.lsp.buf.type_definition, 47 | { buffer = bufnr, desc = "LSP: Go to type definition" } 48 | ) 49 | 50 | map( 51 | "n", 52 | "grr", 53 | "Telescope lsp_references", 54 | { buffer = bufnr, desc = "LSP: Go to references" } 55 | ) 56 | 57 | if client:supports_method(methods.textDocument_inlayHint) then 58 | map("n", "th", function() 59 | local is_enabled = vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }) 60 | vim.lsp.inlay_hint.enable(not is_enabled) 61 | 62 | vim.notify( 63 | string.format("%s inlay hint", (is_enabled and "Disabled" or "Enabled")), 64 | vim.log.levels.INFO 65 | ) 66 | end, "LSP: Toggle inlay hints") 67 | end 68 | 69 | if client.name == "ts_ls" or client.name == "vtsls" then 70 | local ts_mappings = lsp_utils.generate_ts_mappings(client.name) 71 | 72 | map( 73 | "n", 74 | "oi", 75 | ts_mappings.organize_imports, 76 | { buffer = bufnr, desc = "LSP: Organize Imports" } 77 | ) 78 | map( 79 | "n", 80 | "rf", 81 | ts_mappings.rename_file, 82 | { buffer = bufnr, desc = "LSP: Rename File" } 83 | ) 84 | map( 85 | "n", 86 | "gd", 87 | ts_mappings.go_to_source_definition, 88 | { buffer = bufnr, desc = "LSP: Go To Source Definition" } 89 | ) 90 | map( 91 | "n", 92 | "mi", 93 | ts_mappings.add_missing_imports, 94 | { buffer = bufnr, desc = "LSP: Add Missing Imports" } 95 | ) 96 | map( 97 | "n", 98 | "ru", 99 | ts_mappings.remove_unused_imports, 100 | { buffer = bufnr, desc = "LSP: Remove Unused" } 101 | ) 102 | end 103 | end 104 | 105 | return M 106 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lsp/packages.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | --- Returns LSP servers list to enable 4 | M.get_lsp_servers = function() 5 | local env = require("core.env") 6 | 7 | --- Server names are according to lspconfig (see `:h lspconfig-all`) 8 | local servers = { 9 | "cssls", 10 | -- "cssmodules_ls", 11 | "dockerls", 12 | "emmet_language_server", 13 | "eslint", 14 | "html", 15 | "jsonls", 16 | "lua_ls", 17 | "tailwindcss", 18 | "yamlls", 19 | "taplo", 20 | } 21 | 22 | if env.NVIM_USER_USE_TS_LS then 23 | table.insert(servers, "ts_ls") 24 | else 25 | table.insert(servers, "vtsls") 26 | end 27 | 28 | return servers 29 | end 30 | 31 | M.formatters = { 32 | -- "eslint_d", 33 | "prettierd", 34 | } 35 | 36 | return M 37 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lsp/utils.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | --- Takes a client name and generates utility mappings for that client 4 | M.generate_ts_mappings = function(client_name) 5 | local organize_imports = client_name == "ts_ls" 6 | and "TypescriptOrganizeImports" 7 | or "VtsExec organize_imports" 8 | 9 | local rename_file = client_name == "ts_ls" and "TypescriptRenameFile" 10 | or "VtsExec rename_file" 11 | 12 | local add_missing_imports = client_name == "ts_ls" 13 | and "TypescriptAddMissingImports" 14 | or "VtsExec add_missing_imports" 15 | 16 | local go_to_source_definition = client_name == "ts_ls" 17 | and "TypescriptGoToSourceDefinition" 18 | or "VtsExec go_to_source_definition" 19 | 20 | local remove_unused_imports = client_name == "ts_ls" 21 | and "TypescriptRemoveUnused" 22 | or "VtsExec remove_unused_imports" 23 | 24 | return { 25 | organize_imports = organize_imports, 26 | rename_file = rename_file, 27 | add_missing_imports = add_missing_imports, 28 | go_to_source_definition = go_to_source_definition, 29 | remove_unused_imports = remove_unused_imports, 30 | } 31 | end 32 | 33 | return M 34 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lualine.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-lualine/lualine.nvim", 3 | event = "VeryLazy", 4 | dependencies = { "nvim-web-devicons" }, 5 | config = function() 6 | -- For extracting colors from hlgroups 7 | local get_color = require("lualine.utils.utils").extract_highlight_colors 8 | local icons = require("core.icons") 9 | 10 | -- Conditions 11 | local conditions = { 12 | buffer_not_empty = function() 13 | return vim.fn.empty(vim.fn.expand("%:t")) ~= 1 14 | end, 15 | 16 | hide_in_width = function() 17 | return vim.fn.winwidth(0) > 60 18 | end, 19 | 20 | file_not_unix = function() 21 | return vim.bo.fileformat ~= "unix" 22 | end, 23 | 24 | tabs = function() 25 | return not vim.bo.expandtab 26 | end, 27 | } 28 | 29 | local components = { 30 | format_status = function() 31 | return icons.devicons.format 32 | end, 33 | 34 | tabs = function() 35 | return "[T:" .. vim.bo.tabstop .. "]" 36 | end, 37 | } 38 | 39 | require("lualine").setup({ 40 | options = { 41 | component_separators = "", 42 | section_separators = { left = "", right = "" }, 43 | -- disabled_filetypes = { "NvimTree" }, 44 | always_divide_middle = true, 45 | globalstatus = true, 46 | }, 47 | sections = { 48 | lualine_a = { "mode" }, 49 | lualine_b = { 50 | { "branch", icon = "󰘬" }, 51 | { 52 | "diagnostics", 53 | 54 | -- Table of diagnostic sources, available sources are: 55 | -- 'nvim_lsp', 'nvim_diagnostic', 'coc', 'ale', 'vim_lsp'. 56 | sources = { "nvim_lsp" }, 57 | 58 | -- Displays diagnostics for the defined severity types 59 | sections = { "error", "warn", "info", "hint" }, 60 | 61 | -- Highlight groups for diagnostics 62 | diagnostics_color = { 63 | error = { fg = get_color("DiagnosticError", "fg") }, 64 | warn = { fg = get_color("DiagnosticWarn", "fg") }, 65 | info = { fg = get_color("DiagnosticInfo", "fg") }, 66 | hint = { fg = get_color("DiagnosticHint", "fg") }, 67 | }, 68 | 69 | symbols = { 70 | error = string.format("%s ", icons.diagnostics.error), 71 | warn = string.format("%s ", icons.diagnostics.warning), 72 | info = string.format("%s ", icons.diagnostics.info), 73 | hint = string.format("%s ", icons.diagnostics.hint), 74 | }, 75 | 76 | -- Show diagnostics even if there are none 77 | -- always_visible = true, 78 | }, 79 | }, 80 | lualine_c = { 81 | { 82 | "filename", 83 | -- color = { gui = "italic" }, 84 | path = 4, 85 | cond = conditions.buffer_not_empty, 86 | symbols = { 87 | modified = " +", 88 | readonly = string.format(" %s", icons.devicons.lock), 89 | }, 90 | }, 91 | }, 92 | lualine_x = { 93 | "filetype", 94 | { 95 | "fileformat", 96 | 97 | -- Only show for non-unix files 98 | cond = conditions.file_not_unix, 99 | }, 100 | { 101 | components.tabs, 102 | cond = conditions.tabs, 103 | color = { 104 | fg = get_color("DiagnosticInfo", "fg"), 105 | }, 106 | }, 107 | "searchcount", 108 | }, 109 | lualine_y = { 110 | { 111 | components.format_status, 112 | color = function() 113 | return { 114 | bg = not vim.b.format_on_save 115 | and get_color("NeogitDiffDelete", "bg"), 116 | fg = not vim.b.format_on_save 117 | and get_color("NeogitDiffDelete", "fg"), 118 | } 119 | end, 120 | on_click = function() 121 | vim.cmd("UserAutoFormatToggle!") 122 | end, 123 | }, 124 | }, 125 | lualine_z = { 126 | { 127 | "location", 128 | cond = conditions.hide_in_width, 129 | padding = { right = 0 }, 130 | }, 131 | { 132 | "%L", 133 | cond = conditions.hide_in_width, 134 | padding = { left = 1, right = 1 }, 135 | }, 136 | }, 137 | }, 138 | inactive_sections = { 139 | lualine_a = {}, 140 | lualine_b = {}, 141 | lualine_c = { "filename" }, 142 | lualine_x = { "location" }, 143 | lualine_y = {}, 144 | lualine_z = {}, 145 | }, 146 | -- extensions = {}, 147 | }) 148 | end, 149 | } 150 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/luasnip.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "L3MON4D3/LuaSnip", 3 | event = "InsertEnter", 4 | config = function() 5 | local ls = require("luasnip") 6 | local ft_funs = require("luasnip.extras.filetype_functions") 7 | local map = require("core.utils").map 8 | local utils = require("core.utils").string_utils 9 | 10 | map({ "i", "s" }, "", function() 11 | if ls.choice_active() then 12 | ls.change_choice(1) 13 | end 14 | end) 15 | 16 | ls.setup({ 17 | -- TODO: disabled until this gets fixed https://github.com/L3MON4D3/LuaSnip/issues/503 18 | -- update_events = { "TextChanged", "TextChangedI" }, 19 | delete_check_events = { "TextChanged", "TextChangedI" }, 20 | store_selection_keys = "s", 21 | ext_opts = { 22 | [require("luasnip.util.types").choiceNode] = { 23 | active = { 24 | virt_text = { { "●", "DiagnosticSignInfo" } }, 25 | }, 26 | }, 27 | }, 28 | ft_func = function() 29 | if vim.bo.filetype == "markdown" then 30 | return ft_funs.from_pos_or_filetype() 31 | else 32 | return ft_funs.from_filetype() 33 | end 34 | end, 35 | load_ft_func = require("luasnip.extras.filetype_functions").extend_load_ft({ 36 | markdown = { 37 | "css", 38 | "html", 39 | "javascript", 40 | "javascriptreact", 41 | "lua", 42 | "scss", 43 | "typescript", 44 | "typescriptreact", 45 | }, 46 | }), 47 | 48 | -- globally available utility functions 49 | snip_env = { 50 | insert_selected_text = function(jump_index, default_snip) 51 | return ls.d(jump_index, function(_, snip) 52 | local selected_text = snip.env.LS_SELECT_RAW 53 | 54 | if not vim.tbl_isempty({ selected_text }) then 55 | return ls.sn(nil, { 56 | ls.t(vim.iter({ selected_text, "" }):flatten():totable()), 57 | ls.i(1), 58 | }) 59 | else 60 | return default_snip or ls.sn(nil, { ls.i(1) }) 61 | end 62 | end) 63 | end, 64 | insert_filename = function(jump_index, insert, case) 65 | return ls.d(jump_index, function(_, snip) 66 | local filename = snip.env.TM_FILENAME_BASE 67 | 68 | if case == "pascal" then 69 | filename = utils.to_pascal_case(filename) 70 | end 71 | 72 | return ls.sn(nil, { ls.i(insert and 1 or nil, filename) }) 73 | end) 74 | end, 75 | }, 76 | }) 77 | 78 | ls.filetype_extend("typescript", { "javascript" }) 79 | ls.filetype_extend("javascriptreact", { "javascript" }) 80 | ls.filetype_extend( 81 | "typescriptreact", 82 | { "javascriptreact", "javascript", "typescript" } 83 | ) 84 | 85 | require("luasnip.loaders.from_lua").lazy_load({ 86 | paths = { vim.fn.stdpath("config") .. "/snippets/luasnippets" }, 87 | }) 88 | require("luasnip.loaders.from_snipmate").lazy_load({ 89 | paths = { vim.fn.stdpath("config") .. "/snippets/snipmate" }, 90 | }) 91 | end, 92 | } 93 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/markdown-preview.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "iamcco/markdown-preview.nvim", 3 | enabled = false, 4 | build = "cd app && yarn install", 5 | ft = "markdown", 6 | cmd = "MarkdownPreview", 7 | config = function() 8 | -- Do not autoclose preview window 9 | vim.g.mkdp_auto_close = 0 10 | 11 | if not vim.env.IS_TERMUX then 12 | -- Default browser to open markdown files 13 | vim.g.mkdp_browser = "brave" 14 | end 15 | end, 16 | } 17 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/neogen.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "danymat/neogen", 3 | ft = { 4 | "javascript", 5 | "javascriptreact", 6 | "lua", 7 | "sh", 8 | "typescript", 9 | "typescriptreact", 10 | }, 11 | dependencies = { "nvim-treesitter" }, 12 | config = function() 13 | local neogen = require("neogen") 14 | local map = require("core.utils").map 15 | 16 | neogen.setup({ 17 | snippet_engine = "luasnip", 18 | }) 19 | 20 | -- Supported annotations are func, class, type, file 21 | map("n", "ngf", function() 22 | neogen.generate({ type = "func" }) 23 | end, "Annotate func") 24 | 25 | map("n", "ngc", function() 26 | neogen.generate({ type = "class" }) 27 | end, "Annotate class") 28 | 29 | map("n", "ngt", function() 30 | neogen.generate({ type = "type" }) 31 | end, "Annotate type") 32 | end, 33 | } 34 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-autopairs.lua: -------------------------------------------------------------------------------- 1 | -- Autopairs for bracket completions 2 | return { 3 | "windwp/nvim-autopairs", 4 | event = "InsertEnter", 5 | config = function() 6 | local autopairs = require("nvim-autopairs") 7 | local Rule = require("nvim-autopairs.rule") 8 | local ts_conds = require("nvim-autopairs.ts-conds") 9 | local ecma_filetypes = 10 | { "javascript", "typescript", "javascriptreact", "typescriptreact" } 11 | 12 | autopairs.setup({ 13 | check_ts = true, 14 | }) 15 | 16 | -- https://github.com/windwp/nvim-autopairs/pull/283 17 | autopairs.get_rule("(").not_filetypes = ecma_filetypes -- first remove the rule in order to override 18 | autopairs.add_rules({ 19 | -- do not autocomplete parenthesis in import statements 20 | Rule("(", ")", ecma_filetypes):with_pair( 21 | ts_conds.is_in_range(function(param) 22 | if not param then 23 | return false 24 | end 25 | return param.type ~= "named_imports" 26 | end, function() 27 | local cursor = vim.api.nvim_win_get_cursor(0) 28 | return { cursor[1] - 1, cursor[2] } 29 | end) 30 | ), 31 | }) 32 | end, 33 | } 34 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-cmp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "hrsh7th/nvim-cmp", 3 | event = "InsertEnter", 4 | dependencies = { 5 | "L3MON4D3/LuaSnip", 6 | "f3fora/cmp-spell", 7 | "hrsh7th/cmp-buffer", 8 | "hrsh7th/cmp-calc", 9 | "hrsh7th/cmp-nvim-lsp", 10 | "hrsh7th/cmp-nvim-lsp-signature-help", 11 | "hrsh7th/cmp-path", 12 | "nvim-autopairs", 13 | "saadparwaiz1/cmp_luasnip", 14 | { 15 | "petertriho/cmp-git", 16 | config = true, 17 | }, 18 | }, 19 | config = function() 20 | -- nvim-cmp setup 21 | local utils = require("core.utils") 22 | local autopairs = require("nvim-autopairs.completion.cmp") 23 | local cmp = require("cmp") 24 | local cmp_kinds = require("cmp.types").lsp.CompletionItemKind 25 | local luasnip = require("luasnip") 26 | local cmp_kind_icons = require("core.icons").lspkind 27 | 28 | local cmp_source_names = { 29 | buffer = "[Buffer]", 30 | nvim_lsp = "[LSP]", 31 | luasnip = "[LuaSnip]", 32 | git = "[Git]", 33 | calc = "[Calc]", 34 | spell = "[Spell]", 35 | } 36 | 37 | local common_sources = { 38 | { name = "buffer", max_item_count = 10 }, 39 | { name = "calc" }, 40 | { name = "path" }, 41 | { 42 | name = "spell", 43 | option = { 44 | enable_in_context = function() 45 | return require("cmp.config.context").in_treesitter_capture("spell") 46 | end, 47 | }, 48 | }, 49 | } 50 | 51 | cmp.setup({ 52 | snippet = { 53 | expand = function(args) 54 | luasnip.lsp_expand(args.body) 55 | end, 56 | }, 57 | 58 | ---@diagnostic disable-next-line: missing-fields 59 | formatting = { 60 | format = function(entry, vim_item) 61 | local source_name = cmp_source_names[entry.source.name] 62 | 63 | vim_item.kind = 64 | string.format("%s %s", cmp_kind_icons[vim_item.kind], vim_item.kind) 65 | vim_item.menu = source_name 66 | 67 | return vim_item 68 | end, 69 | }, 70 | 71 | window = { 72 | -- completion = cmp.config.window.bordered(), 73 | documentation = cmp.config.window.bordered(), 74 | }, 75 | 76 | -- https://github.com/hrsh7th/cmp-nvim-lsp-signature-help/issues/17#issuecomment-1291205911 77 | preselect = cmp.PreselectMode.None, 78 | 79 | mapping = cmp.mapping.preset.insert({ 80 | [""] = cmp.mapping.scroll_docs(-4), 81 | [""] = cmp.mapping.scroll_docs(4), 82 | [""] = cmp.mapping(function() 83 | if cmp.visible() then 84 | cmp.close() 85 | else 86 | cmp.complete() 87 | end 88 | end), 89 | [""] = cmp.mapping.confirm({ 90 | behavior = cmp.ConfirmBehavior.Replace, -- replaces currently typed text with completion entry 91 | }), 92 | [""] = cmp.mapping(function(fallback) 93 | if cmp.visible() then 94 | -- Need the `Select` behaviour due to below issue 95 | -- https://github.com/typescript-language-server/typescript-language-server/issues/917#issuecomment-2379364927 96 | cmp.select_next_item({ 97 | behavior = cmp.SelectBehavior.Select, 98 | }) 99 | elseif luasnip.expand_or_jumpable() then 100 | luasnip.expand_or_jump() 101 | else 102 | fallback() 103 | end 104 | end, { "i", "s" }), 105 | [""] = cmp.mapping(function(fallback) 106 | if cmp.visible() then 107 | cmp.select_prev_item({ 108 | behavior = cmp.SelectBehavior.Select, 109 | }) 110 | elseif luasnip.jumpable(-1) then 111 | luasnip.jump(-1) 112 | else 113 | fallback() 114 | end 115 | end, { "i", "s" }), 116 | }), 117 | 118 | sources = cmp.config.sources({ 119 | { name = "luasnip" }, 120 | { name = "nvim_lsp" }, 121 | { name = "nvim_lsp_signature_help" }, 122 | }, common_sources), 123 | }) 124 | 125 | -- Autopairs for completion items 126 | cmp.event:on("confirm_done", autopairs.on_confirm_done()) 127 | 128 | -- Enable emmet-ls snippets inside jsx only 129 | -- https://github.com/hrsh7th/nvim-cmp/issues/806#issuecomment-1207815660 130 | local is_emmet_snippet = function(entry) 131 | return entry:get_kind() == cmp_kinds.Snippet 132 | and entry.source:get_debug_name() == "nvim_lsp:emmet_language_server" 133 | end 134 | 135 | local emmet_in_jsx_only = function(entry, _) 136 | if is_emmet_snippet(entry) then 137 | local node = vim.treesitter.get_node() 138 | return node 139 | and (node:type() == "jsx_element" or node:type() == "jsx_text") 140 | or false 141 | end 142 | return true 143 | end 144 | 145 | local emmet_in_html_block_only = function(entry, _) 146 | if not is_emmet_snippet(entry) then 147 | return true 148 | end 149 | 150 | return utils.get_lang_from_cursor_pos() == "html" 151 | end 152 | 153 | -- Add filtered lsp source to jsx supported files 154 | -- TODO: https://github.com/hrsh7th/nvim-cmp/issues/632 155 | cmp.setup.filetype({ "javascriptreact", "typescriptreact" }, { 156 | sources = cmp.config.sources({ 157 | { name = "luasnip", keyword_length = 2, max_item_count = 5 }, 158 | { name = "nvim_lsp", entry_filter = emmet_in_jsx_only }, 159 | { name = "nvim_lsp_signature_help" }, 160 | }, common_sources), 161 | }) 162 | 163 | -- Make autoselect first completion item in html files 164 | cmp.setup.filetype("html", { 165 | mapping = cmp.mapping.preset.insert({ 166 | [""] = cmp.mapping.confirm({ 167 | behavior = cmp.ConfirmBehavior.Replace, 168 | select = true, 169 | }), 170 | }), 171 | }) 172 | 173 | cmp.setup.filetype("markdown", { 174 | sources = cmp.config.sources({ 175 | { name = "luasnip" }, 176 | { name = "nvim_lsp", entry_filter = emmet_in_html_block_only }, 177 | }, common_sources), 178 | }) 179 | 180 | cmp.setup.filetype("gitcommit", { 181 | sources = { 182 | { name = "git" }, 183 | { name = "buffer" }, 184 | { name = "path" }, 185 | { name = "spell" }, 186 | }, 187 | }) 188 | end, 189 | } 190 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-lint.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | "mfussenegger/nvim-lint", 4 | event = { "BufReadPost", "BufNewFile" }, 5 | dependencies = { "mason.nvim" }, 6 | config = function() 7 | local lint = require("lint") 8 | 9 | vim.api.nvim_create_user_command("LintInfo", function() 10 | local linters = lint.get_running() 11 | if #linters == 0 then 12 | return vim.notify("No linters running") 13 | end 14 | vim.notify("Linters: " .. table.concat(linters, ", ")) 15 | end, { desc = "Lint info" }) 16 | 17 | vim.api.nvim_create_autocmd( 18 | { "BufWritePost", "BufReadPost", "InsertLeave" }, 19 | { 20 | group = vim.api.nvim_create_augroup( 21 | "user.plugin.lint", 22 | { clear = true } 23 | ), 24 | callback = function() 25 | lint.try_lint() 26 | end, 27 | } 28 | ) 29 | 30 | lint.linters_by_ft = { 31 | bash = { "shellcheck" }, 32 | sh = { "shellcheck" }, 33 | zsh = { "zsh" }, 34 | -- javascript = { "eslint_d" }, 35 | -- javascriptreact = { "eslint_d" }, 36 | -- typescript = { "eslint_d" }, 37 | -- typescriptreact = { "eslint_d" }, 38 | } 39 | 40 | lint.linters.shellcheck.args = { 41 | "-s", 42 | "bash", 43 | "-e", -- Start ignoring below rules: 44 | -- "SC1090" - Can't follow non-constant source. Use a directive to specify location 45 | -- "SC1091" - Almost the same reason as above 46 | "SC1090,SC1091", 47 | "--format", 48 | "json", 49 | "-", 50 | } 51 | end, 52 | } 53 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-tree.lua: -------------------------------------------------------------------------------- 1 | local icons = require("core.icons") 2 | 3 | ---@type LazySpec 4 | return { 5 | "kyazdani42/nvim-tree.lua", 6 | dependencies = { "nvim-web-devicons" }, 7 | keys = { 8 | { "", "NvimTreeToggle", desc = "Toggle NvimTree" }, 9 | { 10 | "", 11 | "NvimTreeFindFile", 12 | desc = "Open current file tree in NvimTree", 13 | }, 14 | }, 15 | opts = { 16 | disable_netrw = false, 17 | diagnostics = { 18 | enable = true, 19 | }, 20 | 21 | actions = { 22 | open_file = { 23 | -- Auto-resize on opening file 24 | resize_window = true, 25 | }, 26 | }, 27 | 28 | -- Do not show hidden files by default (can be toggled by `H`) 29 | filters = { 30 | dotfiles = true, 31 | }, 32 | 33 | -- Show files ignored by .gitignore 34 | -- Toggle by `I` 35 | -- git = { 36 | -- ignore = false, 37 | -- }, 38 | 39 | -- Keeps cursor on the first letter of the filename when navigating tree 40 | -- hijack_cursor = true, 41 | 42 | view = { 43 | preserve_window_proportions = true, 44 | }, 45 | 46 | renderer = { 47 | -- Enable highligting for folders and both file icons and names 48 | highlight_opened_files = "all", 49 | highlight_git = false, 50 | icons = { 51 | glyphs = { 52 | git = { 53 | ignored = "", 54 | untracked = icons.git.untracked, 55 | }, 56 | }, 57 | }, 58 | indent_markers = { 59 | enable = true, 60 | }, 61 | }, 62 | }, 63 | } 64 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "nvim-treesitter/nvim-treesitter", 4 | build = ":TSUpdate", 5 | event = { "BufReadPost", "BufNewFile" }, 6 | dependencies = { 7 | -- treesitter powered textobjects 8 | "nvim-treesitter/nvim-treesitter-textobjects", 9 | }, 10 | config = function() 11 | local enabled_parsers = { 12 | "bash", 13 | "css", 14 | "html", 15 | "javascript", 16 | "jsdoc", 17 | "json", 18 | "jsonc", 19 | "lua", 20 | "markdown", 21 | "markdown_inline", 22 | "query", 23 | "scss", 24 | "sql", 25 | "tsx", 26 | "typescript", 27 | "vim", 28 | "vimdoc", 29 | "yaml", 30 | } 31 | 32 | -- Use scss parser fork for improved placeholder selector support 33 | -- TODO: remove when upstream adds support 34 | ---@see https://github.com/serenadeai/tree-sitter-scss/pull/19 35 | local scss_parser = 36 | require("nvim-treesitter.parsers").get_parser_configs().scss 37 | scss_parser.install_info.url = 38 | "https://github.com/schardev/tree-sitter-scss" 39 | scss_parser.install_info.revision = "master" 40 | 41 | ---@diagnostic disable-next-line: missing-fields 42 | require("nvim-treesitter.configs").setup({ 43 | -- One of "all", "maintained" (parsers with maintainers), or a list of languages 44 | ensure_installed = enabled_parsers, 45 | 46 | -- Install languages synchronously (only applied to `ensure_installed`) 47 | sync_install = false, 48 | 49 | -- List of parsers to ignore installing 50 | -- ignore_install = { "javascript" }, 51 | 52 | highlight = { 53 | -- `false` will disable the whole extension 54 | enable = true, 55 | 56 | -- list of language that will be disabled 57 | -- disable = {}, 58 | 59 | -- Setting this to true will run `:h syntax` and tree-sitter at the same time. 60 | -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation). 61 | -- Using this option may slow down your editor, and you may see some duplicate highlights. 62 | -- Instead of true it can also be a list of languages 63 | additional_vim_regex_highlighting = false, 64 | }, 65 | 66 | -- textobjects 67 | textobjects = { 68 | select = { 69 | enable = true, 70 | lookahead = true, 71 | 72 | keymaps = { 73 | ["af"] = { 74 | query = "@function.outer", 75 | desc = "Select around funtion", 76 | }, 77 | ["if"] = { 78 | query = "@function.inner", 79 | desc = "Select inside funtion", 80 | }, 81 | ["ac"] = { 82 | query = "@class.outer", 83 | desc = "Select outer class", 84 | }, 85 | ["ic"] = { 86 | query = "@class.inner", 87 | desc = "Select inner class", 88 | }, 89 | ["aP"] = { 90 | query = "@parameter.outer", 91 | desc = "Select around parameter", 92 | }, 93 | ["iP"] = { 94 | query = "@parameter.inner", 95 | desc = "Select inside parameter", 96 | }, 97 | ["aC"] = { 98 | query = "@conditional.outer", 99 | desc = "Select around conditional", 100 | }, 101 | ["iC"] = { 102 | query = "@conditional.inner", 103 | desc = "Select inside conditional", 104 | }, 105 | }, 106 | 107 | -- choose the select mode (default is charwise 'v') 108 | -- selection_modes = { 109 | -- ["@function.inner"] = "v", 110 | -- ["@function.outer"] = "V", 111 | -- }, 112 | }, 113 | 114 | swap = { 115 | enable = true, 116 | swap_next = { 117 | ["]p"] = "@parameter.inner", 118 | ["]t"] = "@user.ternary.inner", -- defined in after/queries/ecma/textobjects.scm 119 | }, 120 | swap_previous = { 121 | ["[p"] = "@parameter.inner", 122 | ["[t"] = "@user.ternary.inner", 123 | }, 124 | }, 125 | 126 | move = { 127 | enable = true, 128 | set_jumps = true, -- whether to set jumps in the jumplist 129 | goto_next_start = { 130 | ["]f"] = { 131 | query = "@function.outer", 132 | desc = "Next function start", 133 | }, 134 | ["]]"] = { query = "@class.outer", desc = "Next class start" }, 135 | }, 136 | goto_previous_start = { 137 | ["[f"] = "@function.outer", 138 | ["[["] = "@class.outer", 139 | }, 140 | }, 141 | }, 142 | 143 | incremental_selection = { 144 | enable = true, 145 | keymaps = { 146 | init_selection = "gnn", 147 | node_decremental = "", 148 | node_incremental = "", 149 | scope_incremental = "", 150 | }, 151 | }, 152 | 153 | playground = { 154 | enable = true, 155 | updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code 156 | }, 157 | 158 | query_linter = { 159 | enable = true, 160 | use_virtual_text = true, 161 | lint_events = { "BufWrite", "CursorHold" }, 162 | }, 163 | 164 | indent = { 165 | enable = true, 166 | }, 167 | }) 168 | end, 169 | }, 170 | } 171 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-ufo.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | "kevinhwang91/nvim-ufo", 4 | event = "BufReadPost", 5 | dependencies = "kevinhwang91/promise-async", 6 | config = function() 7 | -- vim.o.foldcolumn = "1" 8 | vim.o.foldlevel = 99 9 | vim.o.foldlevelstart = 99 10 | vim.o.foldenable = true 11 | vim.opt.fillchars:append([[fold: ,foldopen:,foldsep: ,foldclose:]]) 12 | 13 | local ufo = require("ufo") 14 | local map = require("core.utils").map 15 | 16 | map("n", "zR", ufo.openAllFolds, "Open all folds") 17 | map("n", "zM", ufo.closeAllFolds, "Close all folds") 18 | 19 | require("ufo").setup({ 20 | open_fold_hl_timeout = 150, 21 | provider_selector = function() 22 | return { "treesitter", "indent" } 23 | end, 24 | fold_virt_text_handler = function( 25 | virt_text, 26 | lnum, 27 | end_lnum, 28 | width, 29 | truncate 30 | ) 31 | local new_virt_text = {} 32 | local suffix = ("  %d "):format(end_lnum - lnum) 33 | local target_width = width - vim.fn.strdisplaywidth(suffix) 34 | local cur_width = 0 35 | 36 | for _, chunk in ipairs(virt_text) do 37 | local chunk_text = chunk[1] 38 | local chunk_width = vim.fn.strdisplaywidth(chunk_text) 39 | 40 | if target_width > cur_width + chunk_width then 41 | table.insert(new_virt_text, chunk) 42 | else 43 | local hlgroup = chunk[2] 44 | chunk_text = truncate(chunk_text, target_width - cur_width) 45 | table.insert(new_virt_text, { chunk_text, hlgroup }) 46 | chunk_width = vim.fn.strdisplaywidth(chunk_text) 47 | -- str width returned from truncate() may less than 2nd argument, need padding 48 | if cur_width + chunk_width < target_width then 49 | suffix = suffix 50 | .. (" "):rep(target_width - cur_width - chunk_width) 51 | end 52 | break 53 | end 54 | 55 | cur_width = cur_width + chunk_width 56 | end 57 | 58 | table.insert(new_virt_text, { suffix, "MoreMsg" }) 59 | return new_virt_text 60 | end, 61 | }) 62 | end, 63 | } 64 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/telescope.lua: -------------------------------------------------------------------------------- 1 | ---@type LazySpec 2 | return { 3 | "nvim-telescope/telescope.nvim", 4 | event = { "VeryLazy" }, 5 | dependencies = { 6 | "plenary.nvim", 7 | { "nvim-telescope/telescope-ui-select.nvim" }, 8 | { 9 | "nvim-telescope/telescope-fzf-native.nvim", 10 | build = "make", 11 | cond = function() 12 | return vim.fn.executable("make") == 1 13 | end, 14 | }, 15 | }, 16 | config = function() 17 | local map = require("core.utils").map 18 | local builtin = require("telescope.builtin") 19 | 20 | -- Mappings 21 | map("n", "fv", builtin.find_files, "Find Files") 22 | map("n", "fV", function() 23 | builtin.find_files({ hidden = true, no_ignore = true }) 24 | end, "Find Files (incl. hidden and ignored)") 25 | map("n", "fr", builtin.live_grep, "Live Grep") 26 | map( 27 | "v", 28 | "fr", 29 | '"zy:Telescope live_grep default_text=z', 30 | "Live Grep visually selected text" 31 | ) 32 | map("n", "/", function() 33 | builtin.current_buffer_fuzzy_find( 34 | require("telescope.themes").get_dropdown({ 35 | winblend = 10, 36 | previewer = false, 37 | }) 38 | ) 39 | end, "Fuzzy search current buffer") 40 | map("n", "fe", builtin.resume, "Resume previous picker") 41 | map("n", "fh", builtin.help_tags, "Helptags") 42 | map("n", "ff", builtin.builtin, "Telescope Builtins") 43 | map("n", "fo", builtin.oldfiles, "Oldfiles") 44 | map("n", "fb", builtin.buffers, "Buffers List") 45 | map("n", "fd", function() 46 | builtin.find_files({ cwd = "$DOTS_DIR" }) 47 | end, "Find Files in $DOTS_DIR") 48 | map("n", "fR", function() 49 | builtin.find_files({ cwd = "~/dev/http-requests", default_text = "http " }) 50 | end, "Find request files in ~/dev/http-requests") 51 | 52 | -- Telescope base config 53 | require("telescope").setup({ 54 | extensions = { 55 | ["ui-select"] = { 56 | require("telescope.themes").get_dropdown(), 57 | }, 58 | }, 59 | }) 60 | 61 | -- Load extensions if installed 62 | pcall(require("telescope").load_extension, "fzf") 63 | pcall(require("telescope").load_extension, "ui-select") 64 | end, 65 | } 66 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/which-key.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "folke/which-key.nvim", 3 | event = "BufEnter", 4 | opts = { 5 | delay = 400, 6 | icons = { rules = false }, 7 | spec = { 8 | { "e", desc = "+edit" }, 9 | { "g", desc = "+git" }, 10 | { "ng", desc = "+neogen" }, 11 | { "r", desc = "+replace" }, 12 | { "f", desc = "+telescope" }, 13 | }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /config/nvim/snippets/luasnippets/all.lua: -------------------------------------------------------------------------------- 1 | -- Luasnip will bring it's globals into scope automatically 2 | ---@see https://github.com/L3MON4D3/LuaSnip/blob/master/lua/luasnip/config.lua 3 | ---@diagnostic disable: undefined-global 4 | 5 | return {} 6 | -------------------------------------------------------------------------------- /config/nvim/snippets/luasnippets/javascript.lua: -------------------------------------------------------------------------------- 1 | ---@diagnostic disable: undefined-global 2 | local utils = require("core.utils").string_utils 3 | 4 | return { 5 | -- c-style for loop 6 | s( 7 | { trig = "forc", name = "For Loop" }, 8 | fmt( 9 | [[ 10 | for (let {} = 0; {} < {}; {}++) {{ 11 | {} 12 | }} 13 | ]], 14 | { 15 | i(1, "i"), 16 | rep(1), 17 | c(2, { 18 | i(1, "j"), 19 | sn(1, { i(1, "array"), t(".length") }), 20 | }), 21 | rep(1), 22 | insert_selected_text(3), 23 | } 24 | ) 25 | ), 26 | 27 | -- import statement 28 | s( 29 | { trig = "import", name = "Import Name" }, 30 | fmt('import {} from "{}";', { 31 | c(2, { 32 | d(nil, function(args) 33 | local specifier = args[1][1] 34 | local import = utils.to_pascal_case(utils.basename(specifier)) 35 | return sn(nil, { i(1, import) }) 36 | end, { 1 }), 37 | sn(nil, { t("{ "), i(1, "named import"), t(" }") }), 38 | sn(nil, { t("* as "), i(1, "namespace import") }), 39 | }), 40 | i(1, "specifier"), 41 | }) 42 | ), 43 | 44 | -- useeffect 45 | s( 46 | { trig = "rue", name = "React useEffect" }, 47 | fmt( 48 | [[ 49 | useEffect(() => {{ 50 | {} 51 | {} 52 | }}{}) 53 | ]], 54 | { 55 | i(1), 56 | c(2, { 57 | i(1), 58 | sn(nil, { 59 | t({ "return () => {", "" }), 60 | i(1), 61 | t({ "", "\t}" }), 62 | }), 63 | }), 64 | c(3, { 65 | i(1), 66 | sn(nil, { t(", ["), i(1), t("]") }), 67 | }), 68 | } 69 | ) 70 | ), 71 | 72 | -- usestate 73 | s( 74 | { trig = "rus", name = "React useState" }, 75 | fmt("const [{}, set{}] = useState({});", { 76 | i(1, "state"), 77 | l(l._1:gsub("^%l", string.upper), 1), 78 | i(2), 79 | }) 80 | ), 81 | } 82 | -------------------------------------------------------------------------------- /config/nvim/snippets/luasnippets/javascriptreact.lua: -------------------------------------------------------------------------------- 1 | ---@diagnostic disable: undefined-global 2 | return { 3 | -- react component 4 | s( 5 | { trig = "rfc", name = "React Component" }, 6 | fmt( 7 | [[ 8 | const {} = ({}) => {{ 9 | return ( 10 | <> 11 | {} 12 | 13 | ) 14 | }}; 15 | 16 | export default {}; 17 | ]], 18 | { 19 | insert_filename(1, 1, "pascal"), 20 | c(2, { 21 | i(1, "props"), 22 | i(1, "{ children }"), 23 | }), 24 | insert_selected_text(3), 25 | rep(1), 26 | } 27 | ) 28 | ), 29 | } 30 | -------------------------------------------------------------------------------- /config/nvim/snippets/luasnippets/lua.lua: -------------------------------------------------------------------------------- 1 | ---@diagnostic disable: undefined-global 2 | 3 | return { 4 | -- comment header 5 | s("header 1", { 6 | t("----------"), 7 | l(l._1:gsub(".", "-"), 1), 8 | t({ "----------", "" }), 9 | t("--- "), 10 | i(1, "header title"), 11 | t({ " ---", "" }), 12 | t("----------"), 13 | l(l._1:gsub(".", "-"), 1), 14 | t({ "----------", "" }), 15 | }), 16 | } 17 | -------------------------------------------------------------------------------- /config/nvim/snippets/luasnippets/markdown.lua: -------------------------------------------------------------------------------- 1 | ---@diagnostic disable: undefined-global 2 | 3 | local template = [[ 4 | ```{} 5 | {} 6 | ``` 7 | ]] 8 | 9 | local function fenced_code_block(lang, placeholder) 10 | return s( 11 | { trig = lang, name = lang:upper() .. " fenced code block" }, 12 | fmt(template, { t(lang), insert_selected_text(1, placeholder) }) 13 | ) 14 | end 15 | 16 | return { 17 | s( 18 | { trig = "code", name = "code block" }, 19 | fmt(template, { i(1), insert_selected_text(2) }) 20 | ), 21 | fenced_code_block("html"), 22 | fenced_code_block("css"), 23 | fenced_code_block("bash"), 24 | fenced_code_block("js"), 25 | fenced_code_block("ts"), 26 | fenced_code_block("tsx"), 27 | } 28 | -------------------------------------------------------------------------------- /config/nvim/snippets/snipmate/javascript.snippets: -------------------------------------------------------------------------------- 1 | snippet fore "For-Each loop" 2 | ${1:array}.forEach(element => { 3 | ${TM_SELECTED_TEXT}$0 4 | }) 5 | 6 | snippet forin "For-In loop" 7 | for (const ${1:key} in ${2:object}) { 8 | if (Object.hasOwn(${2:object}, ${1:key})) { 9 | const ${3:value} = ${2:object}[${1:key}]; 10 | ${TM_SELECTED_TEXT}$0 11 | } 12 | } 13 | 14 | snippet forof "For-Of loop" 15 | for (const ${1:iterator} of ${2:array-like}) { 16 | ${TM_SELECTED_TEXT}$0 17 | } 18 | 19 | snippet func "Function Statement" 20 | function ${1:name}(${2:params}) { 21 | ${TM_SELECTED_TEXT}$0 22 | } 23 | 24 | snippet if "If Statement" 25 | if (${1:condition}) { 26 | ${TM_SELECTED_TEXT}$0 27 | } 28 | 29 | snippet ifelse "If-Else Statement" 30 | if (${1:condition}) { 31 | ${TM_SELECTED_TEXT}$2 32 | } else { 33 | $0 34 | } 35 | 36 | snippet arrow "Arrow Function" 37 | const ${1:name} = (${2:params}) => { 38 | $0 39 | } 40 | 41 | snippet new "Constructor" 42 | const ${1:name} = new ${2:type}(${3:arguments});$0 43 | 44 | snippet switch "Switch Statement" 45 | switch (${1:key}) { 46 | case ${2:value}: 47 | $3 48 | break; 49 | 50 | default: 51 | $0 52 | break; 53 | } 54 | 55 | snippet while "While Statement" 56 | while (${1:condition}) { 57 | ${TM_SELECTED_TEXT}$0 58 | } 59 | 60 | snippet dowhile "Do-While Statement" 61 | do { 62 | ${TM_SELECTED_TEXT}$0 63 | } while (${1:condition}) 64 | 65 | snippet trycatch "Try-Catch Statement" 66 | try { 67 | ${TM_SELECTED_TEXT}$1 68 | } catch (${2:error}) { 69 | $0 70 | } 71 | 72 | snippet settimeout 73 | setTimeout(() => { 74 | ${TM_SELECTED_TEXT}$0 75 | }, ${1:timeout}); 76 | 77 | snippet setinterval 78 | setInterval(() => { 79 | ${TM_SELECTED_TEXT}$0 80 | }, ${1:interval}) 81 | 82 | snippet cl "Console log" 83 | console.log(${TM_SELECTED_TEXT}$1); 84 | 85 | snippet cw "Console warn" 86 | console.warn(${TM_SELECTED_TEXT}$1); 87 | 88 | snippet ce "Console error" 89 | console.error(${TM_SELECTED_TEXT}$1); 90 | 91 | snippet ed "export default" 92 | export default $0 93 | 94 | snippet edf "export default function" 95 | export default function ${1:name}(${2:params}) { 96 | ${TM_SELECTED_TEXT}$0 97 | } 98 | 99 | snippet sleep "sleep" 100 | await new Promise((res) => setTimeout(res, ${1:2000})); 101 | 102 | snippet it "it" 103 | it("${1:desc}", () => { 104 | ${2} 105 | }) 106 | 107 | snippet etb "expect" 108 | expect(${1}).toBe(${2}) 109 | 110 | snippet ete "expect" 111 | expect(${1}).toEqual(${2}) 112 | 113 | snippet desc "describe" 114 | describe("${1}", () => { 115 | ${2} 116 | }) 117 | 118 | snippet rucon "useContext" 119 | const ${1:contextValue} = useContext(${2:contextProvider}) 120 | 121 | snippet ruimp "useImperativeHandle" 122 | useImperativeHandle(${1:ref}, () => { 123 | ${2:handle} 124 | }, [${3:deps}]) 125 | 126 | snippet rule "useLayoutEffect" 127 | useLayoutEffect(() => { 128 | ${TM_SELECTED_TEXT}$1 129 | 130 | return () => { 131 | $2 132 | }; 133 | }, [${3:deps}]) 134 | 135 | 136 | snippet rum "useMemo" 137 | useMemo(() => ${TM_SELECTED_TEXT}$1, [${2:deps}]) 138 | 139 | snippet rur "useReducer" 140 | const [${1:state}, ${2:dispatch}] = useReducer(${3:reducerFn}, ${4:initialState}) 141 | 142 | snippet ruref "useRef" 143 | const ${1:ref} = useRef(${2:initialValue}) 144 | 145 | snippet pstyled "Panda Styled Component" 146 | const Styled$1 = styled('${2:div}', { 147 | base: { 148 | ${TM_SELECTED_TEXT}$3 149 | } 150 | }) 151 | -------------------------------------------------------------------------------- /config/nvim/spell/en.utf-8.add: -------------------------------------------------------------------------------- 1 | config 2 | systemd 3 | nvim 4 | sudo 5 | neovim 6 | LSP 7 | cli 8 | stackoverflow 9 | TODO 10 | github 11 | DOM 12 | viewport 13 | params 14 | eslint 15 | fallthrough 16 | const 17 | mixin 18 | npm 19 | scss 20 | JSON 21 | backend 22 | frontend 23 | refetch 24 | util 25 | hashmap 26 | perf 27 | -------------------------------------------------------------------------------- /config/polybar/bin/bluetooth: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | powered=$(bluetoothctl show | awk '/Powered/ {print $2}') 3 | 4 | if [[ $powered == "yes" ]]; then 5 | if bluetoothctl info >>/tmp/sbltlog; then 6 | status=$(bluetoothctl info | awk '/Connected/ {print $2}') 7 | device_name=$(bluetoothctl info | grep 'Name' | sed 's/\sName: \(.*\)/\1/') 8 | if [[ "$status" == "yes" ]]; then 9 | echo " ${device_name}" 10 | fi 11 | else 12 | echo "" 13 | fi 14 | else 15 | echo "" 16 | fi 17 | -------------------------------------------------------------------------------- /config/polybar/bin/powermenu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Original author: Aditya Shakya 3 | shopt -s nocasematch # disable case-sensitive matching 4 | 5 | uptime=$(uptime -p | sed -e 's/up //g') 6 | rofi_dir="$HOME"/.config/rofi 7 | rofi_command=(rofi -theme "$rofi_dir"/styles/powermenu.rasi) 8 | 9 | # Options icons (requires nerd font) 10 | shutdown="" 11 | reboot="累" 12 | lock="" 13 | suspend="鈴" 14 | logout="" 15 | 16 | # Confirmation 17 | confirm_exit() { 18 | rofi -dmenu -i -no-fixed-num-lines -p "Are You Sure? : " \ 19 | -theme "$rofi_dir"/styles/powermenu_confirm.rasi 20 | } 21 | 22 | # Message 23 | msg() { 24 | rofi -theme "$rofi_dir/styles/powermenu_confirm.rasi" -e "Available Options - y / n" 25 | } 26 | 27 | # Variable passed to rofi 28 | options="$shutdown\n$reboot\n$lock\n$suspend\n$logout" 29 | 30 | selected_option="$(echo -e "$options" | "${rofi_command[@]}" -p "Uptime: $uptime" -dmenu -selected-row 2)" 31 | case "$selected_option" in 32 | "$shutdown") 33 | ans=$(confirm_exit) 34 | if [[ "$ans" == "y" ]]; then 35 | systemctl poweroff 36 | elif [[ "$ans" == "n" ]]; then 37 | exit 0 38 | else 39 | msg 40 | fi 41 | ;; 42 | "$reboot") 43 | ans=$(confirm_exit) 44 | if [[ "$ans" == "y" ]]; then 45 | systemctl reboot 46 | elif [[ "$ans" == "n" ]]; then 47 | exit 0 48 | else 49 | msg 50 | fi 51 | ;; 52 | "$lock") 53 | # TODO: Properly configure session locking 54 | if command -v i3lock >/dev/null; then 55 | i3lock 56 | fi 57 | ;; 58 | "$suspend") 59 | ans=$(confirm_exit) 60 | if [[ $ans == "y" ]]; then 61 | amixer set Master mute 62 | systemctl suspend 63 | elif [[ $ans == "n" ]]; then 64 | exit 0 65 | else 66 | msg 67 | fi 68 | ;; 69 | "$logout") 70 | ans=$(confirm_exit) 71 | if [[ $ans == "y" ]]; then 72 | bspc quit 73 | elif [[ $ans == "n" ]]; then 74 | exit 0 75 | else 76 | msg 77 | fi 78 | ;; 79 | esac 80 | -------------------------------------------------------------------------------- /config/polybar/colors.ini: -------------------------------------------------------------------------------- 1 | ; Catppuccin colorscheme (https://github.com/catppuccin/catppuccin) 2 | ; mocha flavour 3 | [catppuccin] 4 | bg = #11111b 5 | bg-alt = #1e1e2e 6 | fg = #D9E0EE 7 | fg-alt = #6E6C7E 8 | white = #FFFFFF 9 | blue = #89B4FA 10 | blue-alt = #62B4F9 11 | red = #F38BA8 12 | green = #A6E3A1 13 | yellow = #F9E2AF 14 | cyan = #89DCEB 15 | cyan-alt = #94E2D5 16 | pink = #F5C2E7 17 | violet = #CBA6F7 18 | -------------------------------------------------------------------------------- /config/polybar/config.ini: -------------------------------------------------------------------------------- 1 | [global/wm] 2 | margin-top = 0 3 | margin-bottom = 0 4 | include-file = $HOME/.config/polybar/colors.ini 5 | include-file = $HOME/.config/polybar/modules.ini 6 | 7 | [bar/main] 8 | ; to center align the bar use this formula -> width = X% and offset-x = Y%, 9 | ; so that X + 2 * Y = 100 10 | width = 99% 11 | height = 40 12 | offset-x = 0.5% 13 | offset-y = 5 14 | radius = 10 15 | padding = 2 16 | module-margin = 1 17 | fixed-center = true 18 | monitor = eDP 19 | line-size = 5 20 | background = ${catppuccin.bg} 21 | foreground = ${catppuccin.fg} 22 | 23 | font-0 = JetbrainsMono Nerd Font:style=Regular:size=11;2 24 | 25 | modules-left = menu bspwm 26 | modules-center = time 27 | modules-right = bluetooth audio memory filesystem wireless-network battery powermenu 28 | 29 | ; systray 30 | tray-position = right 31 | tray-maxsize = 20 32 | tray-scale = 1.0 33 | tray-offset-x = 5 34 | tray-offset-y = 0 35 | 36 | wm-restack = bspwm 37 | cursor-click = pointer 38 | 39 | [settings] 40 | screenchange-reload = true 41 | ; pseudo-transparency is needed for rounded radius to work 42 | pseudo-transparency = true 43 | -------------------------------------------------------------------------------- /config/polybar/launch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$HOME/.config/polybar" 4 | 5 | # Terminate already running bar instances 6 | killall -q polybar 7 | 8 | # Wait until the processes have been shut down 9 | while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done 10 | 11 | # Launch the bar 12 | polybar -q main -c "$DIR"/config.ini & 13 | -------------------------------------------------------------------------------- /config/polybar/modules.ini: -------------------------------------------------------------------------------- 1 | [module/menu] 2 | ;{{{ 3 | type = custom/text 4 | content =  5 | content-foreground = #1793D1 6 | content-padding = 1 7 | click-left = rofi -show drun 8 | click-right = rofi -show window 9 | ;}}} 10 | 11 | [module/bspwm] 12 | ;{{{ 13 | ; (https://github.com/polybar/polybar/wiki/Module:-bspwm) 14 | type = internal/bspwm 15 | 16 | ; Only show workspaces defined on the same output as the bar 17 | pin-workspaces = true 18 | 19 | ws-icon-0 = 1; 20 | ws-icon-1 = 2; 21 | ws-icon-2 = 3; 22 | ws-icon-3 = 4; 23 | ws-icon-4 = 5; 24 | ws-icon-default = 25 | 26 | format = 27 | 28 | label-focused = %icon% 29 | label-focused-foreground = ${catppuccin.blue} 30 | ; label-focused-background = ${catppuccin.blue} 31 | label-focused-underline = ${self.label-focused-foreground} 32 | label-focused-padding = 2 33 | 34 | label-occupied = %icon% 35 | label-occupied-foreground = ${catppuccin.fg} 36 | label-occupied-padding = 2 37 | 38 | label-urgent = %icon% 39 | label-urgent-background = ${catppuccin.red} 40 | label-urgent-foreground = ${catppuccin.white} 41 | label-urgent-overline = ${catppuccin.bg} 42 | label-urgent-underline = ${catppuccin.bg} 43 | label-urgent-padding = 2 44 | 45 | label-empty = %icon% 46 | label-empty-foreground = ${catppuccin.fg-alt} 47 | label-empty-padding = 2 48 | 49 | ; Only scroll through occupied workspaces 50 | ; Default: false 51 | occupied-scroll = true 52 | ;}}} 53 | 54 | [module/time] 55 | ;{{{ 56 | ; (https://github.com/polybar/polybar/wiki/Module:-date) 57 | type = internal/date 58 | interval = 5 59 | label-foreground = ${catppuccin.white} 60 | time = %I:%M %p 61 | time-alt =" %A, %d %B %Y " 62 | label = %time% 63 | 64 | [module/date] 65 | type = internal/date 66 | interval = 5 67 | label-foreground = ${catppuccin.white} 68 | time = " %A, %d %B %Y " 69 | time-alt = %I:%M %p 70 | label = %time% 71 | ;}}} 72 | 73 | [module/bluetooth] 74 | ;{{{ 75 | type = custom/script 76 | exec = ~/.config/polybar/bin/bluetooth 77 | format-foreground = ${catppuccin.blue} 78 | click-left = blueman-manager 79 | click-right = rfkill block bluetooth 80 | interval = 1 81 | ;}}} 82 | 83 | [module/audio] 84 | ;{{{ 85 | ; (https://github.com/polybar/polybar/wiki/Module:-pulseaudio) 86 | type = internal/pulseaudio 87 | 88 | ; Sink to be used, if it exists (find using `pacmd list-sinks`, name field) 89 | ; If not, uses default sink 90 | ; sink = alsa_output.pci-0000_06_00.6.HiFi__hw_Generic__sink 91 | 92 | ; Use PA_VOLUME_UI_MAX (~153%) if true, or PA_VOLUME_NORM (100%) if false 93 | ; Default: true 94 | use-ui-max = false 95 | 96 | ; Interval for volume increase/decrease (in percent points) 97 | ; Default: 5 98 | interval = 5 99 | 100 | format-volume = 101 | format-volume-foreground = ${catppuccin.cyan} 102 | label-volume = %{A2:pavucontrol:}%percentage%%%{A} 103 | ; label-volume-padding = 1 104 | 105 | format-muted-foreground = ${catppuccin.red} 106 | format-muted-prefix = ﱝ 107 | format-muted-prefix-padding = ${self.ramp-volume-padding} 108 | label-muted = Muted 109 | ; label-muted-padding = ${self.label-volume-padding} 110 | 111 | ramp-volume-0 = 奄 112 | ramp-volume-1 = 奄 113 | ramp-volume-2 = 奔 114 | ramp-volume-3 = 奔 115 | ramp-volume-4 = 墳 116 | ramp-volume-5 = 墳 117 | ramp-volume-6 = 墳 118 | ramp-volume-padding = 1 119 | ;}}} 120 | 121 | [module/filesystem] 122 | ;{{{ 123 | ; (https://github.com/polybar/polybar/wiki/Module:-filesystem) 124 | type = internal/fs 125 | interval = 120 126 | 127 | mount-0 = / 128 | fixed-values = true 129 | 130 | format-mounted-prefix =  131 | format-mounted-prefix-foreground = ${catppuccin.blue} 132 | format-mounted-prefix-padding = 1 133 | label-mounted = %used% 134 | ; label-mounted-padding = ${self.format-mounted-prefix-padding} 135 | 136 | format-unmounted-prefix = 137 | label-unmounted = %mountpoint%: not mounted 138 | label-mounted-foreground = ${self.format-mounted-prefix-foreground} 139 | ; label-unmounted-padding = ${self.label-mounted-padding} 140 | ;}}} 141 | 142 | [module/memory] 143 | ;{{{ 144 | type = internal/memory 145 | format-foreground = ${catppuccin.pink} 146 | interval = 1 147 | format =