My personal configuration files. Click on each section to expand and view the full configuration.
Neovim Configuration
~/.config/nvim/
Neovim Configuration
~/.config/nvim/
init.lua
-- Leader earlyvim.g.mapleader = " "
-- lazy.nvim bootstraplocal lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"if not vim.loop.fs_stat(lazypath) then vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath, })endvim.opt.rtp:prepend(lazypath)
-- Core configrequire("config.options")require("config.keymaps")require("config.autocmds")
-- Pluginsrequire("lazy").setup("plugins", { ui = { border = "rounded" } })lua/config/options.lua
vim.cmd("let g:netrw_liststyle = 3")vim.g.deprecation_warnings = falsevim.g.bigfile_size = 1024 * 1024 * 1.5vim.opt.relativenumber = truevim.opt.number = truevim.opt.tabstop = 2vim.opt.shiftwidth = 2vim.opt.expandtab = truevim.opt.autoindent = truevim.opt.smartindent = truevim.opt.wrap = falsevim.opt.ignorecase = truevim.opt.smartcase = truevim.opt.cursorline = truevim.opt.termguicolors = truevim.opt.background = "dark"vim.opt.signcolumn = "yes"vim.opt.backspace = "indent,eol,start"vim.g.loaded_netrwPlugin = 1vim.g.loaded_netrw = 1vim.opt.splitright = truevim.opt.splitbelow = truevim.opt.laststatus = 3vim.opt.splitkeep = "screen"vim.opt.clipboard = "unnamedplus"
-- diagnosticsvim.diagnostic.config({ signs = { text = { [vim.diagnostic.severity.ERROR] = "✘", [vim.diagnostic.severity.WARN] = "▲", [vim.diagnostic.severity.HINT] = "⚑", [vim.diagnostic.severity.INFO] = "»", }, },})lua/config/keymaps.lua
-- basicsvim.keymap.set("n", "<leader>qq", "<cmd>qall<CR>", { desc = "Quit all" })vim.keymap.set("i", "jk", "<ESC>", { desc = "Exit insert mode with jk" })vim.keymap.set("n", "<leader>cc", ":nohl<CR>", { desc = "Clear search highlights" })
-- remove s/Svim.api.nvim_set_keymap("n", "s", "<Nop>", { noremap = true, silent = true })vim.api.nvim_set_keymap("v", "s", "<Nop>", { noremap = true, silent = true })
-- buffer navigationlocal function GoToNthBuffer(n) local buffers = vim.tbl_filter(function(b) return vim.fn.buflisted(b) == 1 end, vim.api.nvim_list_bufs()) if buffers[n] then vim.api.nvim_set_current_buf(buffers[n]) endendvim.keymap.set("n", "<leader>bn", "<cmd>bn<CR>", { desc = "Next buffer" })vim.keymap.set("n", "<leader>bv", "<cmd>bp<CR>", { desc = "Previous buffer" })vim.keymap.set("n", "<leader>bd", "<cmd>bd<CR>", { desc = "Close buffer" })for i = 1, 9 do vim.keymap.set("n", "<leader>b" .. i, function() GoToNthBuffer(i) end, { desc = "Go to buffer " .. i })end
-- Select allvim.keymap.set("n", "<leader>sa", "ggVG", { desc = "Select all" })
-- Keep visual selection after indent/outdentvim.keymap.set("v", ">", ">gv", { desc = "Indent and reselect" })vim.keymap.set("v", "<", "<gv", { desc = "Outdent and reselect" })
-- yazivim.keymap.set("n", "<leader>yy", "<cmd>Yazi<CR>", { desc = "Open yazi" })
-- codecompanion (optional)vim.keymap.set("n", "<leader>ax", "<cmd>CodeCompanionChat Toggle<CR>", { desc = "CodeCompanion Toggle Chat" })vim.keymap.set("v", "<leader>ax", "<cmd>CodeCompanionChat Add<CR>", { desc = "CodeCompanion Add Chat" })lua/config/autocmds.lua
-- Track the start and end of macro recording for statuslinevim.api.nvim_create_autocmd("RecordingEnter", { pattern = "*", callback = function() vim.g.macro_recording = "Recording @" .. vim.fn.reg_recording() vim.cmd("redrawstatus") end,})
vim.api.nvim_create_autocmd("RecordingLeave", { pattern = "*", callback = function() vim.g.macro_recording = "" vim.cmd("redrawstatus") end,})lua/plugins/colorscheme.lua
return { { "rose-pine/neovim", name = "rose-pine", lazy = false, priority = 1000, config = function() vim.cmd("colorscheme rose-pine-main") end, },}lua/plugins/formatting.lua
return { { "stevearc/conform.nvim", event = { "BufReadPre", "BufNewFile" }, config = function() local conform = require("conform") conform.setup({ formatters_by_ft = { javascript = { "prettier" }, typescript = { "prettier" }, javascriptreact = { "prettier" }, typescriptreact = { "prettier" }, css = { "prettier" }, html = { "prettier" }, json = { "prettier" }, yaml = { "prettier" }, markdown = { "prettier" }, lua = { "stylua" }, python = { "ruff_organize_imports", "ruff_fix", "ruff_format" }, }, format_on_save = function(bufnr) if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then return end return { timeout_ms = 500, lsp_fallback = true } end, formatters = { taplo = { args = { "format", "--option", "column_width=180", "-" } } }, }) local function show_notification(message, level) vim.notify(message, level, { title = "conform.nvim" }) end vim.api.nvim_create_user_command("FormatToggle", function(args) local is_global = not args.bang if is_global then vim.g.disable_autoformat = not vim.g.disable_autoformat if vim.g.disable_autoformat then show_notification("Autoformat-on-save disabled globally", "info") else show_notification("Autoformat-on-save enabled globally", "info") end else vim.b.disable_autoformat = not vim.b.disable_autoformat if vim.b.disable_autoformat then show_notification("Autoformat-on-save disabled for this buffer", "info") else show_notification("Autoformat-on-save enabled for this buffer", "info") end end end, { desc = "Toggle autoformat-on-save", bang = true }) end, },}lua/plugins/git.lua
return { { "kdheepak/lazygit.nvim", dependencies = { "nvim-lua/plenary.nvim" }, cmd = { "LazyGit", "LazyGitConfig", "LazyGitCurrentFile", "LazyGitFilter", "LazyGitFilterCurrentFile" }, keys = { { "<leader>gg", "<cmd>LazyGit<CR>", desc = "LazyGit" }, }, }, { "lewis6991/gitsigns.nvim", config = function() require("gitsigns").setup() end },}lua/plugins/mini.lua
return { { "nvim-mini/mini.nvim", lazy = false, keys = { { "<leader>ee", function() MiniFiles.open(vim.uv.cwd(), true) end, desc = "Open mini-files" }, { "<leader>ef", function() MiniFiles.open(vim.api.nvim_buf_get_name(0), true) end, desc = "Open mini-files at current file" }, { "<leader>mmm", function() MiniMap.open() end, desc = "MiniMap open" }, { "<leader>mmc", function() MiniMap.close() end, desc = "MiniMap close" }, -- Pickers { "<leader>ff", "<cmd>Pick files<CR>", desc = "Find files" }, { "<leader>fg", function() MiniPick.builtin.grep_live() end, desc = "Find grep" }, { "<leader>fv", "<cmd>Pick visit_paths<CR>", desc = "Find visit_paths" }, { "<leader>fd", function() MiniExtra.pickers.diagnostic() end, desc = "Find diagnostic" }, { "<leader>fl", function() MiniExtra.pickers.lsp() end, desc = "Find location" }, { "<leader>fh", "<cmd>Pick help<CR>", desc = "Find help" }, { "<leader>fk", "<cmd>Pick keymaps<CR>", desc = "Find keymaps" }, { "<leader>fb", "<cmd>Pick buffers<CR>", desc = "Find buffers" }, -- Sessions { "<leader>ws", function() MiniSessions.select() end, desc = "Select session" }, { "<leader>wr", function() MiniSessions.get_latest() end, desc = "Load session" }, }, config = function() -- basics require("mini.basics").setup({ options = { basic = true }, mappings = { basic = true, move_with_alt = true }, autocommands = { basic = true }, })
-- icons require("mini.icons").setup()
-- navigation/UI require("mini.files").setup({ mappings = { synchronize = "<C-s>" }, options = { use_as_default_explorer = false } }) require("mini.tabline").setup() require("mini.bracketed").setup() require("mini.fuzzy").setup() require("mini.pick").setup()
-- editor require("mini.extra").setup() local gen_ai_spec = require("mini.extra").gen_ai_spec local ai = require("mini.ai") require("mini.ai").setup({ n_lines = 500, custom_textobjects = { B = gen_ai_spec.buffer(), D = gen_ai_spec.diagnostic(), I = gen_ai_spec.indent(), L = gen_ai_spec.line(), N = gen_ai_spec.number(), o = ai.gen_spec.treesitter({ a = { "@block.outer", "@conditional.outer", "@loop.outer" }, i = { "@block.inner", "@conditional.inner", "@loop.inner" }, }), f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }), c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }), }, }) require("mini.indentscope").setup() require("mini.surround").setup({ mappings = { add = "gsa", delete = "gsd", find = "gsf", find_left = "gsF", highlight = "gsh", replace = "gsr", update_n_lines = "gsn", }, }) require("mini.statusline").setup({ use_icons = vim.g.have_nerd_font, content = { active = function() local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) local git = MiniStatusline.section_git({ trunc_width = 40 }) local diff = MiniStatusline.section_diff({ trunc_width = 75 }) local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75 }) local lsp = MiniStatusline.section_lsp({ trunc_width = 75 }) local filename = MiniStatusline.section_filename({ trunc_width = 140 }) local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 }) local location = MiniStatusline.section_location({ trunc_width = 200 }) local search = MiniStatusline.section_searchcount({ trunc_width = 75 }) local macro = vim.g.macro_recording return MiniStatusline.combine_groups({ { hl = mode_hl, strings = { mode } }, { hl = "MiniStatuslineDevinfo", strings = { git, diff, diagnostics } }, "%<", { hl = "MiniStatuslineFilename", strings = { filename } }, "%=", { hl = "MiniStatuslineFilename", strings = { macro } }, { hl = "MiniStatuslineFileinfo", strings = { fileinfo } }, { hl = mode_hl, strings = { search, location } }, }) end, }, }) require("mini.comment").setup() require("mini.pairs").setup({ mappings = { ["("] = { action = "open", pair = "()", neigh_pattern = ".[^%w]" }, ["["] = { action = "open", pair = "[]", neigh_pattern = ".[^%w]" }, ["{"] = { action = "open", pair = "{}", neigh_pattern = ".[^%w]" }, [")"] = { action = "close", pair = "()", neigh_pattern = "[^\\]." }, ["]"] = { action = "close", pair = "[]", neigh_pattern = "[^\\]." }, ["}"] = { action = "close", pair = "{}", neigh_pattern = "[^\\]." }, ['"'] = { action = "closeopen", pair = '""', neigh_pattern = ".[^%w]", register = { cr = false } }, ["'"] = { action = "closeopen", pair = "''", neigh_pattern = ".[^%w]", register = { cr = false } }, ["`"] = { action = "closeopen", pair = "``", neigh_pattern = ".[^%w]", register = { cr = false } }, }, }) local notify = require("mini.notify") notify.setup() vim.notify = notify.make_notify({ ERROR = { duration = 5000 }, WARN = { duration = 4000 }, INFO = { duration = 3000 }, }) require("mini.cursorword").setup() require("mini.starter").setup() require("mini.git").setup() require("mini.sessions").setup({ file = ".session.vim" }) require("mini.visits").setup() require("mini.map").setup()
-- animate (with mouse scroll guard) local mouse_scrolled = false for _, scroll in ipairs({ "Up", "Down" }) do local key = "<ScrollWheel" .. scroll .. ">" vim.keymap.set({ "", "i" }, key, function() mouse_scrolled = true return key end, { expr = true }) end local animate = require("mini.animate") animate.setup({ cursor = { enable = false, timing = animate.gen_timing.linear({ duration = 50, unit = "total" }) }, scroll = { timing = animate.gen_timing.linear({ duration = 50, unit = "total" }), subscroll = animate.gen_subscroll.equal({ predicate = function(total_scroll) if mouse_scrolled then mouse_scrolled = false return false end return total_scroll > 1 end, }), }, })
-- miniclue local miniclue = require("mini.clue") miniclue.setup({ triggers = { { mode = "n", keys = "<Leader>" }, { mode = "x", keys = "<Leader>" }, { mode = "i", keys = "<C-x>" }, { mode = "n", keys = "g" }, { mode = "x", keys = "g" }, { mode = "n", keys = "'" }, { mode = "n", keys = "`" }, { mode = "x", keys = "'" }, { mode = "x", keys = "`" }, { mode = "n", keys = '"' }, { mode = "x", keys = '"' }, { mode = "i", keys = "<C-r>" }, { mode = "c", keys = "<C-r>" }, { mode = "n", keys = "<C-w>" }, { mode = "n", keys = "z" }, { mode = "x", keys = "z" }, }, clues = { miniclue.gen_clues.builtin_completion(), miniclue.gen_clues.g(), miniclue.gen_clues.marks(), miniclue.gen_clues.registers(), miniclue.gen_clues.windows(), miniclue.gen_clues.z(), }, }) end, },}lua/plugins/misc.lua
return { { "gbprod/yanky.nvim", opts = { system_clipboard = { sync_with_ring = false } }, keys = { { "y", "<Plug>(YankyYank)", mode = { "n", "x" }, desc = "Yank", remap = true }, { "p", "<Plug>(YankyPutAfter)", mode = { "n", "x" }, desc = "Put after", remap = true }, { "P", "<Plug>(YankyPutBefore)", mode = { "n", "x" }, desc = "Put before", remap = true }, { "gp", "<Plug>(YankyGPutAfter)", mode = { "n", "x" }, desc = "GPut after", remap = true }, { "gP", "<Plug>(YankyGPutBefore)", mode = { "n", "x" }, desc = "GPut before", remap = true }, { "<c-p>", "<Plug>(YankyPreviousEntry)", mode = "n", desc = "Yanky previous", remap = true }, { "<c-n>", "<Plug>(YankyNextEntry)", mode = "n", desc = "Yanky next", remap = true }, }, }, { "nmac427/guess-indent.nvim", config = function() require("guess-indent").setup({}) end, },}lua/plugins/navigation.lua
return { -- Flash { "folke/flash.nvim", keys = { { "s", function() require("flash").jump() end, mode = { "n", "x", "o" }, desc = "Flash" }, { "S", function() require("flash").treesitter() end, mode = { "n", "x", "o" }, desc = "Flash TS" }, { "r", function() require("flash").remote() end, mode = "o", desc = "Remote Flash" }, { "R", function() require("flash").treesitter_search() end, mode = { "o", "x" }, desc = "TS Search" }, { "<c-s>", function() require("flash").toggle() end, mode = "c", desc = "Toggle Flash Search" }, }, config = function() require("flash").setup() end, },
-- Multicursor { "jake-stewart/multicursor.nvim", keys = { { "<leader><up>", function() require("multicursor-nvim").lineAddCursor(-1) end, mode = {"n","v"}, desc = "MC add up" }, { "<leader><down>", function() require("multicursor-nvim").lineAddCursor(1) end, mode = {"n","v"}, desc = "MC add down" }, { "<localleader><up>", function() require("multicursor-nvim").lineSkipCursor(-1) end, mode = {"n","v"}, desc = "MC skip up" }, { "<localleader><down>", function() require("multicursor-nvim").lineSkipCursor(1) end, mode = {"n","v"}, desc = "MC skip down" }, { "<leader>n", function() require("multicursor-nvim").matchAddCursor(1) end, mode = {"n","v"}, desc = "MC add next" }, { "<leader>v", function() require("multicursor-nvim").matchSkipCursor(1) end, mode = {"n","v"}, desc = "MC skip next" }, { "<leader>N", function() require("multicursor-nvim").matchAddCursor(-1) end, mode = {"n","v"}, desc = "MC add prev" }, { "<leader>V", function() require("multicursor-nvim").matchSkipCursor(-1) end, mode = {"n","v"}, desc = "MC skip prev" }, { "<leader>A", function() require("multicursor-nvim").matchAllAddCursors() end, mode = {"n","v"}, desc = "MC add all" }, { "<leader><left>", function() require("multicursor-nvim").nextCursor() end, mode = {"n","v"}, desc = "MC next" }, { "<leader>x", function() require("multicursor-nvim").deleteCursor() end, mode = {"n","v"}, desc = "MC delete" }, { "<c-leftmouse>", function() require("multicursor-nvim").handleMouse() end, mode = "n", desc = "MC mouse" }, { "<c-q>", function() require("multicursor-nvim").toggleCursor() end, mode = {"n","v"}, desc = "MC toggle" }, { "<leader><c-q>", function() require("multicursor-nvim").duplicateCursors() end, mode = {"n","v"}, desc = "MC duplicate" }, { "<esc>", function() local mc = require("multicursor-nvim") if not mc.cursorsEnabled() then mc.enableCursors() elseif mc.hasCursors() then mc.clearCursors() end end, mode = "n", desc = "MC clear/enable" }, { "<leader>rc", function() require("multicursor-nvim").restoreCursors() end, mode = "n", desc = "MC restore" }, { "I", function() require("multicursor-nvim").insertVisual() end, mode = "v", desc = "MC insert visual" }, { "A", function() require("multicursor-nvim").appendVisual() end, mode = "v", desc = "MC append visual" }, { "<c-i>", function() require("multicursor-nvim").jumpForward() end, mode = {"n","v"}, desc = "MC jump fwd" }, { "<c-o>", function() require("multicursor-nvim").jumpBackward() end, mode = {"n","v"}, desc = "MC jump back" }, }, config = function() require("multicursor-nvim").setup() end, },
-- precognition { "tris203/precognition.nvim", keys = { {"<leader>ll", function() require("precognition").toggle() end, desc = "Precognition" } } },
-- tmux navigator { "christoomey/vim-tmux-navigator", cmd = { "TmuxNavigateLeft", "TmuxNavigateDown", "TmuxNavigateUp", "TmuxNavigateRight", "TmuxNavigatePrevious" }, keys = { { "<c-h>", "<cmd><C-U>TmuxNavigateLeft<cr>", desc = "Navigate left" }, { "<c-j>", "<cmd><C-U>TmuxNavigateDown<cr>", desc = "Navigate down" }, { "<c-k>", "<cmd><C-U>TmuxNavigateUp<cr>", desc = "Navigate up" }, { "<c-l>", "<cmd><C-U>TmuxNavigateRight<cr>", desc = "Navigate right" }, { "<c-\\>", "<cmd><C-U>TmuxNavigatePrevious<cr>", desc = "Navigate previous" }, }, },}lua/plugins/treesitter.lua
return { { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", dependencies = { "windwp/nvim-ts-autotag", "nvim-treesitter/nvim-treesitter-textobjects" }, config = function() local treesitter = require("nvim-treesitter.configs") treesitter.setup({ highlight = { enable = true }, indent = { enable = true, disable = { "yaml", "python" } }, autotag = { enable = true }, ensure_installed = { "bash", "c", "diff", "html", "javascript", "jsdoc", "json", "jsonc", "lua", "luadoc", "luap", "markdown", "markdown_inline", "printf", "python", "query", "regex", "toml", "tsx", "typescript", "vim", "vimdoc", "xml", "yaml", "ninja", "rst", }, incremental_selection = { enable = true, keymaps = { init_selection = "<C-space>", node_incremental = "<C-space>", scope_incremental = false, node_decremental = "<bs>" }, }, }) end, },}lua/plugins/ui.lua
return { { "folke/noice.nvim", dependencies = { "MunifTanjim/nui.nvim" }, config = function() require("noice").setup({ lsp = { override = { ["vim.lsp.util.convert_input_to_markdown_lines"] = true, ["vim.lsp.util.stylize_markdown"] = true } }, presets = { command_palette = true, long_message_to_split = true, inc_rename = false, lsp_doc_border = false }, }) end, }, { "folke/trouble.nvim", config = function() require("trouble").setup() end }, { "OXY2DEV/helpview.nvim" }, { "sphamba/smear-cursor.nvim", config = function() require("smear_cursor").setup({ stiffness = 0.8, trailing_stiffness = 0.5, distance_stop_animating = 0.5, hide_target_hack = true }) end },} Tmux Configuration
~/.config/tmux/tmux.conf
Tmux Configuration
~/.config/tmux/tmux.conf
# Set proper colorsset-option -sa terminal-overrides ",xterm*:Tc"set -g mouse onset -g default-terminal "screen-256color"
set-option -g status-position top
# Set prefixunbind C-bset -g prefix C-Spacebind C-Space send-prefix
# Shift Alt vim keys to switch windowsbind -n M-H previous-windowbind -n M-L next-window
set -g @plugin 'tmux-plugins/tpm'set -g @plugin 'tmux-plugins/tmux-sensible'set -g @plugin 'christoomey/vim-tmux-navigator'set -g @plugin 'catppuccin/tmux'set -g @plugin 'tmux-plugins/tmux-yank'
run '~/.tmux/plugins/tpm/tpm'
# set vi-modeset-window-option -g mode-keys vi# keybindingsbind-key -T copy-mode-vi v send-keys -X begin-selectionbind-key -T copy-mode-vi C-v send-keys -X rectangle-togglebind-key -T copy-mode-vi y send-keys -X copy-selection-closing
bind -r k select-pane -Ubind -r j select-pane -Dbind -r h select-pane -Lbind -r l select-pane -R
bind '"' split-window -v -c "#{pane_current_path}"bind % split-window -h -c "#{pane_current_path}"
# Start windows and panes at 1, not 0set -g base-index 1set -g pane-base-index 1set-window-option -g pane-base-index 1set-option -g renumber-windows on
set -g @catppuccin_window_left_separator ""set -g @catppuccin_window_right_separator " "set -g @catppuccin_window_middle_separator " █"set -g @catppuccin_window_number_position "right"set -g @catppuccin_window_default_fill "number"set -g @catppuccin_window_default_text "#W"set -g @catppuccin_window_current_fill "number"set -g @catppuccin_window_current_text "#W#{?window_zoomed_flag,(),}"set -g @catppuccin_status_modules_right "directory meetings date_time"set -g @catppuccin_status_modules_left "session"set -g @catppuccin_status_left_separator " "set -g @catppuccin_status_right_separator " "set -g @catppuccin_status_right_separator_inverse "no"set -g @catppuccin_status_fill "icon"set -g @catppuccin_status_connect_separator "no"set -g @catppuccin_directory_text "#{b:pane_current_path}"set -g @catppuccin_date_time_text "%H:%M"