-
-
Save coswind/bc5498c78a178798a42b6efe3b90def9 to your computer and use it in GitHub Desktop.
neovim v0.12 config in one file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| vim.g.mapleader = "," | |
| vim.g.maplocalleader = "," | |
| -- color scheme | |
| vim.pack.add({ | |
| { src = 'https://github.com/Mofiqul/dracula.nvim' }, | |
| { src = "https://github.com/neovim/nvim-lspconfig" }, | |
| { src = "https://github.com/rachartier/tiny-inline-diagnostic.nvim" }, | |
| { src = "https://github.com/saghen/blink.cmp" }, | |
| { src = "https://github.com/stevearc/conform.nvim" }, | |
| { src = "https://github.com/sphamba/smear-cursor.nvim" }, | |
| { src = "https://github.com/gbprod/yanky.nvim" }, | |
| { src = "https://github.com/nvim-lua/plenary.nvim" }, | |
| { src = "https://github.com/nvim-telescope/telescope.nvim" }, | |
| { src = "https://github.com/akinsho/bufferline.nvim" }, | |
| { src = "https://github.com/nvim-neo-tree/neo-tree.nvim" }, | |
| { src = "https://github.com/nvim-lua/plenary.nvim" }, | |
| { src = "https://github.com/MunifTanjim/nui.nvim" }, | |
| { src = "https://github.com/nvim-tree/nvim-web-devicons" }, | |
| }) | |
| require("dracula").setup({ | |
| colors = { | |
| bg = "#29202B", -- hsl(289,14%,15%) | |
| fg = "#F7F7F1", -- hsl(60,30%,96%) | |
| red = "#FF947F", -- hsl(10,100%,75%) | |
| orange = "#FFC97F", -- hsl(35,100%,75%) | |
| yellow = "#FEFF7F", -- hsl(60,100%,75%) | |
| green = "#8AFF7F", -- hsl(115,100%,75%) | |
| cyan = "#7FFFE9", -- hsl(170,100%,75%) | |
| blue = "#7FBFFF", -- hsl(210,100%,75%) | |
| pink = "#FF7FBF", -- hsl(330,100%,75%) | |
| purple = "#947FFF", -- hsl(250,100%,75%) | |
| shadow = "#000000", -- hsl(0,0%,0%) | |
| darken = "#212121", -- hsl(0,0%,13%) | |
| selection = "#534157", -- color(bg) s(15%) l(30%) | |
| comment = "#9E6FA8", -- color(bg) s(25%) l(55%) | |
| visual = "#492F4F", -- color(bg) s(25%) l(25%) | |
| stack = "#E77FFF", -- color(comment) s(100%) l(75%) | |
| bright_red = "#FFBFB2", -- red l+10% | |
| bright_orange = "#FFDFB2", -- orange l+10% | |
| bright_yellow = "#FFFFB2", -- yellow l+10% | |
| bright_green = "#B8FFB2", -- green l+10% | |
| bright_cyan = "#B2FFF2", -- cyan l+10% | |
| bright_blue = "#B2D8FF", -- blue l+10% | |
| bright_pink = "#FFB2D8", -- pink l+10% | |
| bright_purple = "#BFB2FF", -- purple l+10% | |
| bright_white = "#FFFFFF", -- pure white | |
| white = "#F7F7F1", -- same as fg | |
| black = "#000000", -- same as shadow | |
| menu = "#241C25", -- bg.l - 2 | |
| gutter_fg = "#84568F", -- comment.l - 10 | |
| nontext = "#584D5A", -- invisibles: color(comment) s×0.3, l×0.6 | |
| }, | |
| transparent_bg = false, | |
| overrides = { | |
| NormalFloat = { bg = "#241C25" }, | |
| FloatBorder = { fg = "#BFB2FF", bg = "#241C25" }, | |
| NoiceCmdlinePopupBorder = { fg = "#BFB2FF" }, | |
| }, | |
| }) | |
| vim.cmd.colorscheme("dracula") | |
| vim.lsp.enable({ "lua_ls", "clangd", "rust_analyzer" }) | |
| -- Diagnostic | |
| require("tiny-inline-diagnostic").setup({}) | |
| vim.diagnostic.config({ virtual_text = false }) | |
| -- CMP | |
| require("blink.cmp").setup({ | |
| keymap = { preset = "enter" }, | |
| appearance = { | |
| nerd_font_variant = "mono", | |
| }, | |
| completion = { documentation = { auto_show = false } }, | |
| sources = { | |
| default = { "lsp", "path", "snippets", "buffer" }, | |
| }, | |
| fuzzy = { implementation = "prefer_rust_with_warning" }, | |
| }) | |
| -- Formatter | |
| vim.keymap.set( | |
| { "n" }, | |
| "<leader>cf", | |
| function() | |
| require("conform").format({ | |
| async = true, | |
| lsp_fallback = true, | |
| timeout_ms = 500, | |
| }) | |
| end, | |
| { desc = "Format file" } | |
| ) | |
| require("conform").setup( | |
| { | |
| format_on_save = { | |
| lsp_fallback = true, | |
| timeout_ms = 500, | |
| }, | |
| -- formatters_by_ft = language_config.FORMATTER_MAP, | |
| } | |
| ) | |
| require("smear_cursor").setup({ | |
| smear_between_buffers = true, | |
| }) | |
| -- custom paste function | |
| local function paste_from_unnamed() | |
| local lines = vim.split(vim.fn.getreg(""), "\n", { plain = true }) | |
| if #lines == 0 then | |
| lines = { "" } | |
| end | |
| local rtype = vim.fn.getregtype(""):sub(1, 1) | |
| return { lines, rtype } | |
| end | |
| vim.g.clipboard = { | |
| name = "OSC 52", | |
| copy = { | |
| ["+"] = require("vim.ui.clipboard.osc52").copy("+"), | |
| ["*"] = require("vim.ui.clipboard.osc52").copy("*"), | |
| }, | |
| paste = { | |
| ["+"] = paste_from_unnamed, | |
| ["*"] = paste_from_unnamed, | |
| }, | |
| } | |
| vim.api.nvim_create_autocmd("TextYankPost", { | |
| callback = function() | |
| local ev = vim.v.event | |
| if ev.operator == "y" and ev.regname == "" then | |
| vim.fn.setreg("+", ev.regcontents, ev.regtype) | |
| end | |
| end, | |
| }) | |
| require("yanky").setup({ | |
| system_clipboard = { | |
| sync_with_ring = false, | |
| } | |
| }) | |
| -- options | |
| -- show the absolute line number for the current line | |
| vim.opt.number = true | |
| -- show relative line numbers | |
| vim.opt.relativenumber = true | |
| -- Confirm before quitting unsaved changes | |
| vim.opt.confirm = true | |
| -- Persistent undo across sessions | |
| vim.opt.undofile = true | |
| -- Practically infinite undo (safe) | |
| vim.opt.undolevels = 1000000 | |
| -- Enable mouse in all modes | |
| vim.opt.mouse = "a" | |
| -- Use spaces instead of tabs | |
| vim.opt.expandtab = true | |
| -- Indent size | |
| vim.opt.shiftwidth = 2 | |
| -- Tab character width | |
| vim.opt.tabstop = 2 | |
| -- Round indent to nearest multiple of shiftwidth | |
| vim.opt.shiftround = true | |
| -- Auto-indent new lines intelligently | |
| vim.opt.smartindent = true | |
| -- Keep comments, wrap text, autoformat when possible | |
| vim.opt.formatoptions = "jcroqlnt" | |
| -- Case-insensitive by default | |
| vim.opt.ignorecase = true | |
| -- But smart if uppercase is used | |
| vim.opt.smartcase = true | |
| -- Live preview for :substitute | |
| vim.opt.inccommand = "nosplit" | |
| vim.opt.grepprg = "rg --vimgrep" -- Use ripgrep for :grep | |
| -- Match file:line:col:message format | |
| vim.opt.grepformat = "%f:%l:%c:%m" | |
| -- Highlight current line | |
| vim.opt.cursorline = true | |
| -- Always show sign column | |
| vim.opt.signcolumn = "yes" | |
| -- Show cursor position in statusline | |
| vim.opt.ruler = true | |
| -- Global statusline (once you add one) | |
| vim.opt.laststatus = 3 | |
| -- Enable true colors | |
| vim.opt.termguicolors = true | |
| -- Prevent tiny splits | |
| vim.opt.winminwidth = 5 | |
| -- Keep 4 lines visible around cursor | |
| vim.opt.scrolloff = 4 | |
| -- Keep 8 columns visible horizontally | |
| vim.opt.sidescrolloff = 8 | |
| -- Disable line wrapping | |
| vim.opt.wrap = false | |
| -- (If wrapping) break at words | |
| vim.opt.linebreak = true | |
| -- Show invisible characters (tabs, etc.) | |
| vim.opt.list = false | |
| vim.opt.showmode = false | |
| vim.opt.colorcolumn = "80" | |
| -- Fold by indentation level | |
| vim.opt.foldmethod = "indent" | |
| -- Start unfolded | |
| vim.opt.foldlevel = 99 | |
| -- Simple fold indicator (first line + …) | |
| vim.opt.foldtext = "v:lua.vim.fn.getline(v:foldstart) .. ' …'" | |
| -- Restore view after jump | |
| vim.opt.jumpoptions = "view" | |
| -- Allow cursor past EOL in block mode | |
| vim.opt.virtualedit = "block" | |
| -- Enhanced command completion | |
| vim.opt.wildmode = "longest:full,full" | |
| -- Horizontal splits below | |
| vim.opt.splitbelow = true | |
| -- Vertical splits to the right | |
| vim.opt.splitright = true | |
| -- Preserve layout when splitting | |
| vim.opt.splitkeep = "screen" | |
| -- keymaps | |
| local map = vim.keymap.set | |
| -- better up/down | |
| map({ "n", "x" }, "j", "v:count == 0 ? 'gj' : 'j'", { desc = "Down", expr = true, silent = true }) | |
| map({ "n", "x" }, "<Down>", "v:count == 0 ? 'gj' : 'j'", { desc = "Down", expr = true, silent = true }) | |
| map({ "n", "x" }, "k", "v:count == 0 ? 'gk' : 'k'", { desc = "Up", expr = true, silent = true }) | |
| map({ "n", "x" }, "<Up>", "v:count == 0 ? 'gk' : 'k'", { desc = "Up", expr = true, silent = true }) | |
| -- Move Lines | |
| map("n", "<A-j>", "<cmd>execute 'move .+' . v:count1<cr>==", { desc = "Move Down" }) | |
| map("n", "<A-k>", "<cmd>execute 'move .-' . (v:count1 + 1)<cr>==", { desc = "Move Up" }) | |
| map("i", "<A-j>", "<esc><cmd>m .+1<cr>==gi", { desc = "Move Down" }) | |
| map("i", "<A-k>", "<esc><cmd>m .-2<cr>==gi", { desc = "Move Up" }) | |
| map("v", "<A-j>", ":<C-u>execute \"'<,'>move '>+\" . v:count1<cr>gv=gv", { desc = "Move Down" }) | |
| map("v", "<A-k>", ":<C-u>execute \"'<,'>move '<-\" . (v:count1 + 1)<cr>gv=gv", { desc = "Move Up" }) | |
| -- buffers | |
| map("n", "<S-h>", "<cmd>bprevious<cr>", { desc = "Prev Buffer" }) | |
| map("n", "<S-l>", "<cmd>bnext<cr>", { desc = "Next Buffer" }) | |
| map("n", "<leader>bd", function() | |
| local cur = vim.api.nvim_get_current_buf() | |
| local alt = vim.fn.bufnr("#") | |
| if alt > 0 and vim.api.nvim_buf_is_loaded(alt) then | |
| vim.cmd("buffer #") | |
| else | |
| vim.cmd("bnext") | |
| end | |
| vim.cmd("bdelete " .. cur) | |
| end, { desc = "Delete Buffer" }) | |
| map("n", "<leader>bo", function() | |
| local current = vim.api.nvim_get_current_buf() | |
| for _, buf in ipairs(vim.api.nvim_list_bufs()) do | |
| if vim.api.nvim_buf_is_loaded(buf) and buf ~= current then | |
| vim.cmd("bdelete " .. buf) | |
| end | |
| end | |
| end, { desc = "Delete Other Buffers" }) | |
| map("n", "<leader>bD", "<cmd>:bd<cr>", { desc = "Delete Buffer and Window" }) | |
| -- Clear search and stop snippet on escape | |
| map({ "i", "n", "s" }, "<esc>", function() | |
| vim.cmd("noh") | |
| return "<esc>" | |
| end, { expr = true, desc = "Escape and Clear hlsearch" }) | |
| -- https://github.com/mhinz/vim-galore#saner-behavior-of-n-and-n | |
| map("n", "n", "'Nn'[v:searchforward].'zv'", { expr = true, desc = "Next Search Result" }) | |
| map("x", "n", "'Nn'[v:searchforward]", { expr = true, desc = "Next Search Result" }) | |
| map("o", "n", "'Nn'[v:searchforward]", { expr = true, desc = "Next Search Result" }) | |
| map("n", "N", "'nN'[v:searchforward].'zv'", { expr = true, desc = "Prev Search Result" }) | |
| map("x", "N", "'nN'[v:searchforward]", { expr = true, desc = "Prev Search Result" }) | |
| map("o", "N", "'nN'[v:searchforward]", { expr = true, desc = "Prev Search Result" }) | |
| -- quick save | |
| map({ "i", "x", "n", "s" }, "<C-s>", "<cmd>w<cr><esc>", { desc = "Save File" }) | |
| --keywordprg | |
| map("n", "<leader>K", "<cmd>norm! K<cr>", { desc = "Keywordprg" }) | |
| -- better indenting | |
| map("x", "<", "<gv") | |
| map("x", ">", ">gv") | |
| -- commenting | |
| map("n", "gco", "o<esc>Vcx<esc><cmd>normal gcc<cr>fxa<bs>", { desc = "Add Comment Below" }) | |
| map("n", "gcO", "O<esc>Vcx<esc><cmd>normal gcc<cr>fxa<bs>", { desc = "Add Comment Above" }) | |
| -- lazy | |
| map("n", "<leader>l", "<cmd>Lazy<cr>", { desc = "Lazy" }) | |
| -- new file | |
| map("n", "<leader>fn", "<cmd>enew<cr>", { desc = "New File" }) | |
| -- location list | |
| map("n", "<leader>xl", function() | |
| local success, err = pcall(vim.fn.getloclist(0, { winid = 0 }).winid ~= 0 and vim.cmd.lclose or vim.cmd.lopen) | |
| if not success and err then | |
| vim.notify(err, vim.log.levels.ERROR) | |
| end | |
| end, { desc = "Location List" }) | |
| -- quickfix list | |
| map("n", "<leader>xq", function() | |
| local success, err = pcall(vim.fn.getqflist({ winid = 0 }).winid ~= 0 and vim.cmd.cclose or vim.cmd.copen) | |
| if not success and err then | |
| vim.notify(err, vim.log.levels.ERROR) | |
| end | |
| end, { desc = "Quickfix List" }) | |
| map("n", "[q", vim.cmd.cprev, { desc = "Previous Quickfix" }) | |
| map("n", "]q", vim.cmd.cnext, { desc = "Next Quickfix" }) | |
| -- diagnostic | |
| local diagnostic_goto = function(next, severity) | |
| return function() | |
| vim.diagnostic.jump({ | |
| count = (next and 1 or -1) * vim.v.count1, | |
| severity = severity and vim.diagnostic.severity[severity] or nil, | |
| float = true, | |
| }) | |
| end | |
| end | |
| map("n", "<leader>cd", vim.diagnostic.open_float, { desc = "Line Diagnostics" }) | |
| map("n", "]d", diagnostic_goto(true), { desc = "Next Diagnostic" }) | |
| map("n", "[d", diagnostic_goto(false), { desc = "Prev Diagnostic" }) | |
| map("n", "]e", diagnostic_goto(true, "ERROR"), { desc = "Next Error" }) | |
| map("n", "[e", diagnostic_goto(false, "ERROR"), { desc = "Prev Error" }) | |
| map("n", "]w", diagnostic_goto(true, "WARN"), { desc = "Next Warning" }) | |
| map("n", "[w", diagnostic_goto(false, "WARN"), { desc = "Prev Warning" }) | |
| -- quit | |
| map("n", "<leader>qq", "<cmd>qa<cr>", { desc = "Quit All" }) | |
| -- windows | |
| map("n", "<C-h>", "<C-w>h", { desc = "Move to left window" }) | |
| map("n", "<C-j>", "<C-w>j", { desc = "Move to below window" }) | |
| map("n", "<C-k>", "<C-w>k", { desc = "Move to above window" }) | |
| map("n", "<C-l>", "<C-w>l", { desc = "Move to right window" }) | |
| map("n", "<leader>-", "<C-W>s", { desc = "Split Window Below", remap = true }) | |
| map("n", "<leader>|", "<C-W>v", { desc = "Split Window Right", remap = true }) | |
| map("n", "<leader>wd", "<C-W>c", { desc = "Delete Window", remap = true }) | |
| -- tabs | |
| -- map("n", "<leader><tab>l", "<cmd>tablast<cr>", { desc = "Last Tab" }) | |
| -- map("n", "<leader><tab>o", "<cmd>tabonly<cr>", { desc = "Close Other Tabs" }) | |
| -- map("n", "<leader><tab>f", "<cmd>tabfirst<cr>", { desc = "First Tab" }) | |
| -- map("n", "<leader><tab><tab>", "<cmd>tabnew<cr>", { desc = "New Tab" }) | |
| -- map("n", "<leader><tab>]", "<cmd>tabnext<cr>", { desc = "Next Tab" }) | |
| -- map("n", "<leader><tab>d", "<cmd>tabclose<cr>", { desc = "Close Tab" }) | |
| -- map("n", "<leader><tab>[", "<cmd>tabprevious<cr>", { desc = "Previous Tab" }) | |
| -- LSP (when attached) | |
| vim.api.nvim_create_autocmd("LspAttach", { | |
| group = vim.api.nvim_create_augroup("LspKepmap", {}), | |
| callback = function(ev) | |
| -- Use buffer-local keymaps | |
| local opts = function(desc) | |
| return { buffer = ev.buf, desc = desc } | |
| end | |
| -- LSP keymaps | |
| map("n", "K", vim.lsp.buf.hover, opts("LSP Hover")) | |
| map("n", "gd", vim.lsp.buf.definition, opts("Goto Definition")) | |
| map("n", "gD", vim.lsp.buf.declaration, opts("Goto Declaration")) | |
| map("n", "gr", vim.lsp.buf.references, opts("List References")) | |
| map("n", "gi", vim.lsp.buf.implementation, opts("Goto Implementation")) | |
| map("n", "gt", vim.lsp.buf.type_definition, opts("Type Definition")) | |
| map("n", "<leader>cr", vim.lsp.buf.rename, opts("Rename Symbol")) | |
| map({ "n", "x" }, "<leader>ca", vim.lsp.buf.code_action, opts("Code Action")) | |
| map("i", "<C-k>", vim.lsp.buf.signature_help, opts("Signature Help")) | |
| end, | |
| }) | |
| map("n", "<leader><space>", "<cmd>Telescope find_files<cr>", { desc = "Find files" }) | |
| map("n", "<leader>/", "<cmd>Telescope live_grep<cr>", { desc = "Grep in files" }) | |
| map("n", "<leader>,", "<cmd>Telescope buffers sort_mru=true sort_lastused=true ignore_current_buffer=true<cr>", | |
| { desc = "Switch buffers" }) | |
| map("n", "<leader>:", "<cmd>Telescope command_history<cr>", { desc = "Command History" }) | |
| require("bufferline").setup({ | |
| options = { | |
| close_command = function(bufnr) | |
| vim.cmd("bdelete " .. bufnr) | |
| end, | |
| right_mouse_command = function(bufnr) | |
| vim.cmd("bdelete " .. bufnr) | |
| end, | |
| diagnostics = "nvim_lsp", | |
| always_show_bufferline = true, | |
| diagnostics_indicator = function(_, _, diag) | |
| local icons = { | |
| Error = " ", | |
| Warn = " ", | |
| Hint = " ", | |
| Info = " ", | |
| } | |
| local ret = (diag.error and icons.Error .. diag.error .. " " or "") | |
| .. (diag.warning and icons.Warn .. diag.warning or "") | |
| return vim.trim(ret) | |
| end, | |
| offsets = { | |
| { | |
| filetype = "neo-tree", | |
| text = "Neo-tree", | |
| highlight = "Directory", | |
| text_align = "left", | |
| }, | |
| }, | |
| get_element_icon = function(opts) | |
| -- fallback to nvim-web-devicons if available | |
| local ok, devicons = pcall(require, "nvim-web-devicons") | |
| if ok then | |
| local icon, _ = devicons.get_icon_by_filetype(opts.filetype) | |
| return icon | |
| end | |
| return "" | |
| end, | |
| } | |
| } | |
| ) | |
| map("n", "<leader>bp", "<Cmd>BufferLineTogglePin<CR>", { desc = "Toggle Pin" }) | |
| map("n", "<leader>bP", "<Cmd>BufferLineGroupClose ungrouped<CR>", { desc = "Delete Non-Pinned Buffers" }) | |
| map("n", "<S-h>", "<cmd>BufferLineCyclePrev<cr>", { desc = "Prev Buffer" }) | |
| map("n", "<S-l>", "<cmd>BufferLineCycleNext<cr>", { desc = "Next Buffer" }) | |
| map("n", "<leader>e", function() | |
| require("neo-tree.command").execute({ toggle = true, dir = vim.uv.cwd() }) | |
| end, { desc = "Explorer NeoTree (cwd)" }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment