commit 91caa45acabcee29fa4ff436720bacb02e437efb Author: lenn Date: Sun Jan 4 09:14:52 2026 +0800 first commit diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..bb1d484 --- /dev/null +++ b/init.lua @@ -0,0 +1,363 @@ +-- ~/.config/nvim/init.lua +vim.g.mapleader = " " + +-- 基础体验 +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.signcolumn = "yes" +vim.opt.termguicolors = true +vim.opt.mouse = "a" +vim.opt.clipboard = "unnamedplus" +vim.opt.updatetime = 250 +vim.opt.timeoutlen = 400 + +-- 缩进(先给一个通用默认) +vim.opt.tabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.smartindent = true +vim.opt.scrolloff = 12 + +-- 搜索 +vim.opt.ignorecase = true +vim.opt.smartcase = true +vim.opt.hlsearch = true +vim.opt.incsearch = true + +-- 基本按键 +vim.keymap.set("n", "w", "w", { desc = "save" }) +vim.keymap.set("n", "q", "q", { desc = "quit" }) +vim.keymap.set("n", "", "nohlsearch") +vim.keymap.set("n", "vs", "vsplit", { desc = "Vertical split" }) +vim.keymap.set("n", "hs", "split", { desc = "Horizontal split" }) +vim.keymap.set("n", "sx", "close", { desc = "Close split" }) +vim.keymap.set("n", "so", "only", { desc = "Only this split" }) +vim.keymap.set("i", "jj", "", { noremap = true, silent = true}) +vim.keymap.set("i", "", "", { noremap = true, silent = true }) +vim.keymap.set("i", "", "", { noremap = true, silent = true }) +vim.keymap.set("i", "", "", { noremap = true, silent = true }) +vim.keymap.set("i", "", "", { noremap = true, silent = true }) +vim.keymap.set("n", "", ":m .+1==", { noremap = true, silent = true }) +vim.keymap.set("n", "", ":m .-2==", { noremap = true, silent = true }) +vim.keymap.set("v", "", ":m '>+1gv=gv", { noremap = true, silent = true }) +vim.keymap.set("v", "", ":m '<-2gv=gv", { noremap = true, silent = true }) +-- edit vim config -- +vim.keymap.set("n", "ev", function() + vim.cmd("edit " .. vim.fn.stdpath("config") .. "/init.lua") +end, { desc = "Edit init.lua" }) + +-- source vim config -- +vim.keymap.set("n", "sv", function() + vim.cmd("source" .. vim.fn.stdpath("config") .. "/init.lua") + vim.notify("init.lua reloaded") +end, { desc = "Reload init.lua" }) + +-- 当前lsp +vim.keymap.set("n", "lc", function() + print(vim.inspect(vim.lsp.get_clients({ bufnr = 0 }))) +end, { desc = "LSP: clients (current buffer)"}) +-- 超有用的排错开关:显示报错来源 +vim.opt.shortmess:remove("F") + +vim.diagnostic.config({ + virtual_text = false, + signs = true, + underline = true, + update_in_insert = false, + severity_sort = true, + float = { border = "rounded", source = "if_many"}, +}) + +-- clangd 配置 +local caps = vim.lsp.protocol.make_client_capabilities() +local ok, cmp_lsp = pcall(require, "cmp_nvim_lsp") +if ok then + caps = cmp_lsp.default_capabilities(caps) +end + +-- clangd +vim.lsp.config("clangd", { + capabilities = caps, + cmd = { + "clangd", + "--background-index", + "--clang-tidy", + "--completion-style=detailed", + "--header-insertion=never", + "--suggest-missing-includes=false", + }, + filetypes = { "c", "cpp", "objc", "objcpp", "cuda" }, + root_markers = { "compile_commands.json", "compile_flags.txt", ".git", "CMakeLists.txt" }, +}) + +-- Rust +vim.lsp.config("rust_analyzer", { + capabilities = caps, + root_markers = { "Cargo.toml", ".git" }, +}) + +-- Zig +vim.lsp.config("zls", { + capabilities = caps, + root_markers = { "build.zig", "build.zig.zon", ".git"}, +}) + +-- Json +vim.lsp.config("jsonls", { + capabilities = caps, + root_markers = { "package.json", ".git"}, +}) + +-- CMake LSP +vim.lsp.config("cmake", { + capabilities = caps, + cmd = { "cmake-language-server" }, + root_markers = { "CMakeLists.txt", ".git" }, + filetypes = { "cmake" }, + init_options = { + buildDirectory = "build", + }, +}) + +-- GLSL +vim.lsp.config("glslls", { + cmd = { vim.fn.expand("glslls"), "--stdin", "--target-env", "opengl4.5" }, + filetypes = {"glsl"}, + root_markers = { ".git", "." }, +}) +vim.filetype.add({ + extension = { + vert = "glsl", + frag = "glsl", + comp = "glsl", + geom = "glsl", + tesc = "glsl", + tese = "glsl", + glsl = "glsl", + }, +}) + +-- enable lsp -- +vim.lsp.enable({ "clangd", "rust_analyzer", "zls", "jsonls", "glslls", "build"}) + +-- ===== Auto save on leave ===== +vim.api.nvim_create_autocmd({ + "BufLeave", + "WinLeave", + "TabLeave", + "InsertLeave", +},{ + callback = function() + if vim.bo.modified + and vim.bo.buftype == "" + and vim.fn.expand("%") ~= "" + then + vim.cmd("silent write") + end + end, +}) + +vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local buf = args.buf + local map = function(mode, lhs, rhs, desc) + vim.keymap.set(mode, lhs, rhs, { buffer = buf, desc = desc }) + end + map("n", "gd", vim.lsp.buf.definition, "Go to definition") + map("n", "gr", vim.lsp.buf.references, "References") + map("n", "K", vim.lsp.buf.hover, "Hover") + map("n", "rn", vim.lsp.buf.rename, "Rename") + map("n", "ca", vim.lsp.buf.code_action, "Code Action") + map("n", "[d", vim.diagnostic.goto_prev, "Prev diagnostic") + map("n", "]d", vim.diagnostic.goto_next, "Next diagnostic") + map("n", "e", vim.diagnostic.open_float, "Line diagnostic") + end, +}) + +-- === lazy.nvim bootstrap === +local 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 + }) +end +vim.opt.rtp:prepend(lazypath) +require("lazy_bootstrap") + + +-- === plugins === +require("lazy").setup({ + { "tpope/vim-sleuth" }, + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + config = function() + vim.api.nvim_create_autocmd("FileType", { + callback = function(args) + local ft = vim.bo[args.buf].filetype + if ft == "lazy" then + return + end + + local lang = vim.treesitter.language.get_lang(ft) + if not lang then + return + end + + local ok = pcall(vim.treesitter.get_parser, args.buf, lang) + if ok then + pcall(vim.treesitter.start, args.buf, lang) + end + end, + }) + end, + }, + { + "hrsh7th/nvim-cmp", + dependencies = { + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + "L3MON4D3/LuaSnip", + "saadparwaiz1/cmp_luasnip", + "rafamadriz/friendly-snippets", + }, + config = function() + local cmp = require("cmp") + local luasnip = require("luasnip") + + require("luasnip.loaders.from_vscode").lazy_load() + + cmp.setup({ + snippet = { + expand = function(args) luasnip.lsp_expand(args.body) end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + sources = { + { name = "nvim_lsp"}, + { name = "luasnip" }, + { name = "path" }, + { name = "buffer" }, + }, + }) + end, + }, + { + "stevearc/conform.nvim", + opts = { + formatters_by_ft = { + cpp = { "clang-format" }, + c = { "clang-format" }, + }, + }, + config = function(_, opts) + require("conform").setup(opts) + vim.keymap.set({ "n", "v"}, "f", function() + require("conform").format({ lsp_fallback = true }) + end, { desc = "Format" }) + end, + }, + { + "lewis6991/gitsigns.nvim", + config = function() + require("gitsigns").setup() + end, + }, + { + "nvim-telescope/telescope.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + config = function() + local telescope = require("telescope") + telescope.setup({ + defaults = { + -- 体验相关 + prompt_prefix = "  ", + selection_caret = "❯ ", + sorting_strategy = "ascending", + layout_config = { + prompt_position = "top", + }, + }, + }) + + local builtin = require("telescope.builtin") + -- 常用快捷键 + vim.keymap.set("n", "ff", builtin.find_files, { desc = "Find files" }) + vim.keymap.set("n", "fg", builtin.live_grep, { desc = "Live grep" }) + vim.keymap.set("n", "fb", builtin.buffers, { desc = "Buffers" }) + vim.keymap.set("n", "fh", builtin.help_tags, { desc = "Help tags" }) + + vim.keymap.set("n", "fd", builtin.diagnostics,{ desc = "Diagnostics" }) + vim.keymap.set("n", "fs", builtin.lsp_document_symbols, { desc = "Symbols (buffer)" }) + vim.keymap.set("n", "fS", builtin.lsp_workspace_symbols,{ desc = "Symbols (workspace)" }) + end, + }, + { + "stevearc/oil.nvim", + config = function() + require("oil").setup() + vim.keymap.set("n", "-", "Oil", { desc = "Open parent directory (Oil)" }) + vim.api.nvim_create_autocmd("FileType", { + pattern = "oil", + callback = function() + vim.keymap.set("n", "q", "bd", { buffer = true }) + end, + }) + end + }, + { + "echasnovski/mini.pairs", + version = false, + config = function() + require("mini.pairs").setup({ + + }) + end, + }, + { + "folke/tokyonight.nvim", + priority = 1000, + config = function() + vim.cmd.colorscheme("tokyonight") + end, + }, + { + "stevearc/dressing.nvim", + event = "VeryLazy", + config = function() + require("dressing").setup({ + input = { + border = "rounded", + }, + select = { + backend = { "builtin" }, + }, + }) + end, + }, +}) + diff --git a/lazy-lock.json b/lazy-lock.json new file mode 100644 index 0000000..7416814 --- /dev/null +++ b/lazy-lock.json @@ -0,0 +1,20 @@ +{ + "LuaSnip": { "branch": "master", "commit": "3732756842a2f7e0e76a7b0487e9692072857277" }, + "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" }, + "cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" }, + "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, + "conform.nvim": { "branch": "master", "commit": "df83eeaab265dacd2eef139a78e502a3f8926618" }, + "dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" }, + "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, + "gitsigns.nvim": { "branch": "main", "commit": "130beacf8a51f00aede9c31064c749136679a321" }, + "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, + "mini.pairs": { "branch": "main", "commit": "d5a29b6254dad07757832db505ea5aeab9aad43a" }, + "nvim-cmp": { "branch": "main", "commit": "d97d85e01339f01b842e6ec1502f639b080cb0fc" }, + "nvim-treesitter": { "branch": "main", "commit": "7efc1b58a8061d29786860006c7257c90a5196dc" }, + "oil.nvim": { "branch": "master", "commit": "963c8d2c5538c4a896a31f396b8a5a2683e254dc" }, + "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, + "telescope.nvim": { "branch": "master", "commit": "3f8109cd21abe9fdb274a09da1e3c176673254b4" }, + "tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" }, + "vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" } +} diff --git a/lua/lazy_bootstrap.lua b/lua/lazy_bootstrap.lua new file mode 100644 index 0000000..db59f87 --- /dev/null +++ b/lua/lazy_bootstrap.lua @@ -0,0 +1,10 @@ +local 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 + }) +end +vim.opt.rtp:prepend(lazypath)