diff --git a/.gitignore b/.gitignore index 6fd0a37..24b9585 100644 --- a/.gitignore +++ b/.gitignore @@ -1,41 +1,4 @@ -# Compiled Lua sources -luac.out -# luarocks build files -*.src.rock -*.zip -*.tar.gz - -# Object files -*.o -*.os -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo -*.def -*.exp - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex +lazy-lock.json +.luarc.json diff --git a/README.md b/README.md index c4d9a26..59eebe2 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# config.nvim \ No newline at end of file +# config.nvim + +我的neovim配置 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..bb843dc --- /dev/null +++ b/init.lua @@ -0,0 +1,4 @@ + +-- INFO: 加载启动配置 +require("boot") + diff --git a/lua/boot/cmds.lua b/lua/boot/cmds.lua new file mode 100644 index 0000000..5cccac6 --- /dev/null +++ b/lua/boot/cmds.lua @@ -0,0 +1,10 @@ + +-- ********** yank ********** +vim.api.nvim_create_autocmd({ "TextYankPost" }, { + pattern = { "*" }, + callback = function() + vim.highlight.on_yank({ + timeout = 300, + }) + end, +}) diff --git a/lua/boot/init.lua b/lua/boot/init.lua new file mode 100644 index 0000000..580442c --- /dev/null +++ b/lua/boot/init.lua @@ -0,0 +1,10 @@ + +require("boot.opts") + +require("boot.cmds") + +require("boot.maps") + +require("boot.util") + +require("boot.plug") diff --git a/lua/boot/maps.lua b/lua/boot/maps.lua new file mode 100644 index 0000000..fae4680 --- /dev/null +++ b/lua/boot/maps.lua @@ -0,0 +1,8 @@ +local map = vim.api.nvim_set_keymap + +-- buffers +map("n", "", ":bp", { desc = "buffer prev" }) +map("n", "", ":bn", { desc = "buffer next" }) + +map("i", "", ":bp", { desc = "buffer prev" }) +map("i", "", ":bn", { desc = "buffer next" }) diff --git a/lua/boot/opts.lua b/lua/boot/opts.lua new file mode 100644 index 0000000..c8a3e2e --- /dev/null +++ b/lua/boot/opts.lua @@ -0,0 +1,67 @@ + +-- ********** leader ********** +vim.g.mapleader = " " + +-- ********** line number ********** +vim.o.number = true +vim.o.relativenumber = true + +-- ********** tab size ********** +vim.o.tabstop = 4 +vim.o.softtabstop = 4 +vim.o.shiftwidth = 4 +vim.o.expandtab = true + +-- ********** encoding ********** +vim.o.encoding = "utf-8" +-- vim.o.termencoding = "utf-8" +vim.o.fileencodings = "utf-8,gb2312,gbk,ucs-bom,cp936,latin-1" + +-- ********** backup ********** +vim.o.backup = false +vim.o.writebackup = false +vim.o.swapfile = false + +-- ********** search ********** +vim.o.hlsearch = true +vim.o.ignorecase = true +vim.o.incsearch = false + +-- ********** display ********** +-- blank chars +vim.o.list = true +vim.o.listchars = "space:·" +-- syntax +vim.o.syntax = "on" +vim.o.termguicolors = true +vim.o.cursorline = true +-- wrap +vim.o.wrap = false +-- fold +vim.o.foldenable = true +vim.o.foldcolumn = "1" +vim.o.foldlevel = 99 +vim.o.foldmethod = "manual" +-- vim.o.foldmethod = "indent" + +-- ********** clipboard ********** +vim.o.clipboard = "unnamedplus" + +-- ********** mouse ********** +vim.o.mouse = "a" + +-- ********** gui ********** +if vim.fn.has("gui_running") then + vim.o.guifont = "FiraCode Nerd Font:h11" + + if vim.fn.exists("g:neovide") then + -- Floating Shadow + vim.g.neovide_floating_shadow = true + vim.g.neovide_floating_z_height = 10 + vim.g.neovide_light_angle_degrees = 45 + vim.g.neovide_light_radius = 5 + -- Transparency + vim.g.neovide_transparency = 0.8 + end +end + diff --git a/lua/boot/plug.lua b/lua/boot/plug.lua new file mode 100644 index 0000000..cb21809 --- /dev/null +++ b/lua/boot/plug.lua @@ -0,0 +1,15 @@ +if vim.fn.executable("git") == 1 then + if vim.fn.isdirectory(vim.fn.stdpath("data") .. "/lazy/lazy.nvim") == 0 then + vim.fn.system({ + "git", + "clone", + "--filter=blob:none", + "https://github.com/folke/lazy.nvim.git", + "--branch=stable", + vim.fn.stdpath("data") .. "/lazy/lazy.nvim", + }) + end + vim.opt.rtp:prepend(vim.fn.stdpath("data") .. "/lazy/lazy.nvim") + + require("lazy").setup({ { import = "plug" } }) +end diff --git a/lua/boot/util.lua b/lua/boot/util.lua new file mode 100644 index 0000000..c2a929b --- /dev/null +++ b/lua/boot/util.lua @@ -0,0 +1,20 @@ +local M = { + uv = vim.uv or vim.loop, + + has = function(what) + return vim.fn.has(what) == 1 + end, + + executable = function(what) + return vim.fn.executable(what) == 1 + end, +} + +setmetatable(M, { + ---@param key string + __index = function(_, key) + return require("util." .. key) + end, +}) + +_G.NeoVim = M diff --git a/lua/plug/ext_git.lua b/lua/plug/ext_git.lua new file mode 100644 index 0000000..5035775 --- /dev/null +++ b/lua/plug/ext_git.lua @@ -0,0 +1,19 @@ +return { + { + "lewis6991/gitsigns.nvim", + event = "VeryLazy", + opts = { + current_line_blame = true, + current_line_blame_opts = { + virt_text = true, + virt_text_pos = "right_align", + delay = 1000, + ignore_whitespace = false, + }, + }, + config = function(_, opts) + require("gitsigns").setup(opts) + end, + }, +} + diff --git a/lua/plug/ext_symbol-usage.lua b/lua/plug/ext_symbol-usage.lua new file mode 100644 index 0000000..09e63c7 --- /dev/null +++ b/lua/plug/ext_symbol-usage.lua @@ -0,0 +1,78 @@ +return { + { + "Wansmer/symbol-usage.nvim", + event = "BufReadPre", + config = function() + local function h(name) + return vim.api.nvim_get_hl(0, { name = name }) + end + + -- hl-groups can have any name + vim.api.nvim_set_hl(0, "SymbolUsageRounding", { fg = h("CursorLine").bg, italic = true }) + vim.api.nvim_set_hl( + 0, + "SymbolUsageContent", + { bg = h("CursorLine").bg, fg = h("Comment").fg, italic = true } + ) + vim.api.nvim_set_hl(0, "SymbolUsageRef", { fg = h("Function").fg, bg = h("CursorLine").bg, italic = true }) + vim.api.nvim_set_hl(0, "SymbolUsageDef", { fg = h("Type").fg, bg = h("CursorLine").bg, italic = true }) + vim.api.nvim_set_hl(0, "SymbolUsageImpl", { fg = h("@keyword").fg, bg = h("CursorLine").bg, italic = true }) + + local function text_format(symbol) + local res = {} + + local round_start = { "", "SymbolUsageRounding" } + local round_end = { "", "SymbolUsageRounding" } + + -- Indicator that shows if there are any other symbols in the same line + local stacked_functions_content = symbol.stacked_count > 0 and ("+%s"):format(symbol.stacked_count) + or "" + + if symbol.references then + local usage = symbol.references <= 1 and "usage" or "usages" + local num = symbol.references == 0 and "no" or symbol.references + table.insert(res, round_start) + table.insert(res, { "󰌹 ", "SymbolUsageRef" }) + table.insert(res, { ("%s %s"):format(num, usage), "SymbolUsageContent" }) + table.insert(res, round_end) + end + + if symbol.definition then + if #res > 0 then + table.insert(res, { " ", "NonText" }) + end + table.insert(res, round_start) + table.insert(res, { "󰳽 ", "SymbolUsageDef" }) + table.insert(res, { symbol.definition .. " defs", "SymbolUsageContent" }) + table.insert(res, round_end) + end + + if symbol.implementation then + if #res > 0 then + table.insert(res, { " ", "NonText" }) + end + table.insert(res, round_start) + table.insert(res, { "󰡱 ", "SymbolUsageImpl" }) + table.insert(res, { symbol.implementation .. " impls", "SymbolUsageContent" }) + table.insert(res, round_end) + end + + if stacked_functions_content ~= "" then + if #res > 0 then + table.insert(res, { " ", "NonText" }) + end + table.insert(res, round_start) + table.insert(res, { " ", "SymbolUsageImpl" }) + table.insert(res, { stacked_functions_content, "SymbolUsageContent" }) + table.insert(res, round_end) + end + + return res + end + + require("symbol-usage").setup({ + text_format = text_format, + }) + end, + }, +} diff --git a/lua/plug/ext_todo-comments.lua b/lua/plug/ext_todo-comments.lua new file mode 100644 index 0000000..e0f8c4b --- /dev/null +++ b/lua/plug/ext_todo-comments.lua @@ -0,0 +1,17 @@ +return { + { + -- FIX: Tag Test + -- TODO: Tag test + -- HACK: Tag test + -- WARN: Tag test + -- PERF: Tag test + -- NOTE: Tag test + -- TEST: Tag test + "folke/todo-comments.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + event = "VeryLazy", + config = function() + require("todo-comments").setup() + end, + }, +} diff --git a/lua/plug/gui_bufferline.lua b/lua/plug/gui_bufferline.lua new file mode 100644 index 0000000..9f06451 --- /dev/null +++ b/lua/plug/gui_bufferline.lua @@ -0,0 +1,35 @@ +return { + { + "akinsho/bufferline.nvim", + event = "VeryLazy", + version = "*", + dependencies = { + "nvim-tree/nvim-web-devicons", + }, + opts = { + options = { + numbers = "buffer_id", + right_mouse_command = false, + -- underline + indicator = { + icon = '▎', + style = 'underline', + }, + -- diagnostics + diagnostics = "nvim_lsp", + diagnostics_indicator = function(count, level) + local icons = require("nvim-web-devicons").get_icons() + local icon_error = icons.diagnostic_error.icon + local icon_warn = icons.diagnostic_warn.icon + local icon = level:match("error") and icon_error or icon_warn + return " " .. icon .. " " .. count + end, + separator_style = "slant", + always_show_bufferline = false, + }, + }, + config = function(_, opts) + require("bufferline").setup(opts) + end, + }, +} diff --git a/lua/plug/gui_colorscheme.lua b/lua/plug/gui_colorscheme.lua new file mode 100644 index 0000000..ff5d581 --- /dev/null +++ b/lua/plug/gui_colorscheme.lua @@ -0,0 +1,40 @@ +return { + { + "folke/tokyonight.nvim", + config = function(_, opts) + vim.cmd.colorscheme("tokyonight-night") + end, + }, + { + "loctvl842/monokai-pro.nvim", + event = "VeryLazy", + enabled = false, + opts = { + transparent_background = false, + terminal_colors = true, + devicons = true, + filter = "machine", + background_clear = { + "float_win", + "telescope", + "renamer", + "notify", + "neo-tree", + }, + plugins = { + bufferline = { + underline_selected = true, + underline_visible = true, + }, + indent_blankline = { + context_highlight = "pro", -- default | pro + context_start_underline = false, + }, + }, + }, + config = function(_, opts) + require("monokai-pro").setup(opts) + vim.cmd.colorscheme("monokai-pro") + end, + }, +} diff --git a/lua/plug/gui_filetree.lua b/lua/plug/gui_filetree.lua new file mode 100644 index 0000000..ea8f967 --- /dev/null +++ b/lua/plug/gui_filetree.lua @@ -0,0 +1,30 @@ +return { + { + "nvim-neo-tree/neo-tree.nvim", + branch = "v3.x", + cmd = "Neotree", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-tree/nvim-web-devicons", + "MunifTanjim/nui.nvim", + }, + opts = { + filesystem = { + follow_current_file = { enabled = true }, + }, + }, + config = function(_, opts) + local icons = require("nvim-web-devicons").get_icons() + vim.fn.sign_define("DiagnosticSignError", + { text = icons.diagnostic_error.icon, texthl = "DiagnosticSignError"}) + vim.fn.sign_define("DiagnosticSignWarn", + { text = icons.diagnostic_warn.icon, texthl = "DiagnosticSignWarn"}) + vim.fn.sign_define("DiagnosticSignInfo", + { text = icons.diagnostic_info.icon, texthl = "DiagnosticSignInfo"}) + vim.fn.sign_define("DiagnosticSignHint", + { text = icons.diagnostic_hint.icon, texthl = "DiagnosticSignHint"}) + + require("neo-tree").setup(opts) + end, + }, +} diff --git a/lua/plug/gui_indentline.lua b/lua/plug/gui_indentline.lua new file mode 100644 index 0000000..dbb1c97 --- /dev/null +++ b/lua/plug/gui_indentline.lua @@ -0,0 +1,45 @@ +return { + { + "lukas-reineke/indent-blankline.nvim", + event = "VeryLazy", + opts = { + indent = { + char = "│", + tab_char = "│", + }, + }, + main = "ibl", + config = function(_, opts) + require("ibl").setup(opts) + end, + }, + { + "echasnovski/mini.indentscope", + version = false, + event = "VeryLazy", + opts = { + symbol = "│", + options = { try_as_border = true }, + }, + init = function() + vim.api.nvim_create_autocmd("FileType", { + pattern = { + "help", + "alpha", + "dashboard", + "neo-tree", + "Trouble", + "trouble", + "lazy", + "mason", + "notify", + "toggleterm", + "lazyterm", + }, + callback = function() + vim.b.miniindentscope_disable = true + end, + }) + end, + }, +} diff --git a/lua/plug/gui_statusline.lua b/lua/plug/gui_statusline.lua new file mode 100644 index 0000000..9547d67 --- /dev/null +++ b/lua/plug/gui_statusline.lua @@ -0,0 +1,20 @@ +return { + { + "nvim-lualine/lualine.nvim", + event = "VeryLazy", + dependencies = { + "nvim-tree/nvim-web-devicons", + }, + opts = { + options = { + globalstatus = true, + theme = "molokai", + -- section_separators = { left = "", right = "" }, + -- component_separators = { left = "", right = "" }, + }, + }, + config = function(_, opts) + require("lualine").setup(opts) + end, + }, +} diff --git a/lua/plug/gui_which-key.lua b/lua/plug/gui_which-key.lua new file mode 100644 index 0000000..5d8ccf2 --- /dev/null +++ b/lua/plug/gui_which-key.lua @@ -0,0 +1,25 @@ +return { + { + "folke/which-key.nvim", + event = "VeryLazy", + init = function() + vim.o.timeout = true + vim.o.timeoutlen = 300 + end, + config = function() + local wk = require("which-key") + wk.add({ + { "f", group = "File" }, + { "fo", ":Neotree position=float", desc = "open" }, + { "fx", ":q", desc = "exit" }, + { "v", group = "View" }, + { "vf", ":Neotree position=left toggle", desc = "explorer" }, + { "vo", ":AerialToggle", desc = "outline" }, + { "b", group = "Buffer" }, + { "bn", ":bn", desc = "next" }, + { "bp", ":bp", desc = "prev" }, + { "bd", ":bd", desc = "delete" }, + }) + end, + }, +} diff --git a/lua/plug/libraries.lua b/lua/plug/libraries.lua new file mode 100644 index 0000000..3f42fa1 --- /dev/null +++ b/lua/plug/libraries.lua @@ -0,0 +1,36 @@ +return { + -- Provides Nerd Font icons (glyphs) for use by neovim plugins + { + "nvim-tree/nvim-web-devicons", + config = function() + require("nvim-web-devicons").set_icon({ + diagnostic_error = { + icon = "", + color = "#e8274b", + name = "DiagnosticError" + }, + diagnostic_warn = { + icon = "", + color = "#cbcb41", + name = "DiagnosticWarn" + }, + diagnostic_info = { + icon = "", + color = "#00c58e", + name = "DiagnosticInfo" + }, + diagnostic_hint = { + icon = "󰌵", + name = "DiagnosticHint" + }, + }) + end, + }, + -- plenary: full; complete; entire; absolute; unqualified. + -- All the lua functions I don't want to write twice. + { "nvim-lua/plenary.nvim" }, + -- UI Component Library for Neovim. + { "MunifTanjim/nui.nvim" }, + -- Promise & Async in Lua + { "kevinhwang91/promise-async" }, +} diff --git a/lua/plug/lsp_completion.lua b/lua/plug/lsp_completion.lua new file mode 100644 index 0000000..5061c66 --- /dev/null +++ b/lua/plug/lsp_completion.lua @@ -0,0 +1,93 @@ +return { + { + "hrsh7th/nvim-cmp", + event = "VeryLazy", + dependencies = { + -- sources + { "hrsh7th/cmp-nvim-lsp" }, + { "hrsh7th/cmp-nvim-lua" }, + { "hrsh7th/cmp-buffer" }, + { "hrsh7th/cmp-path" }, + { "hrsh7th/cmp-nvim-lsp-document-symbol" }, + -- snippets + { "L3MON4D3/LuaSnip" }, + { "saadparwaiz1/cmp_luasnip" }, + { "rafamadriz/friendly-snippets" }, + -- lsp diagnostics + { "hrsh7th/cmp-nvim-lsp-signature-help" }, + { "onsails/lspkind.nvim" }, + }, + config = function() + local cmp = require("cmp") + local lspkind = require("lspkind") + local luasnip = require("luasnip") + + cmp.setup({ + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) -- Luasnip expand + end, + }, + window = { + completion = { border = "rounded" }, + documentation = { border = "rounded" }, + }, + mapping = { + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + if luasnip.expandable() then + luasnip.expand() + else + cmp.confirm({ select = true }) + end + else + fallback() + end + end), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.locally_jumpable(1) then + luasnip.jump(1) + else + fallback() + end + end, { "i", "s" }), + ["S-"] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }, + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "nvim_lsp_signature_help" }, + { name = "nvim_lsp_document_symbol" }, + { name = "nvim_lua" }, + { name = "luasnip" }, + }, { + { name = "buffer" }, + { name = "path" }, + }), + formatting = { + format = lspkind.cmp_format({ + mode = "symbol_text", + maxwidth = function() return math.floor(0.5 * vim.o.columns) end, + ellipsis_char = "...", + show_labelDetails = true, + before = function(_, vim_item) + return vim_item + end, + }), + }, + }) + + -- Add snippets from Friendly Snippets + require("luasnip/loaders/from_vscode").lazy_load() + end, + }, +} diff --git a/lua/plug/lsp_lspconfig.lua b/lua/plug/lsp_lspconfig.lua new file mode 100644 index 0000000..df8a081 --- /dev/null +++ b/lua/plug/lsp_lspconfig.lua @@ -0,0 +1,80 @@ +return { + { + "mason-org/mason.nvim", + opts = { + ui = { + icons = { + package_installed = "✓", + package_pending = "➜", + package_uninstalled = "✗", + }, + }, + }, + config = function(_, opts) + require("mason").setup(opts) + end, + }, + { + "mason-org/mason-lspconfig.nvim", + event = "VeryLazy", + dependencies = { + { "mason-org/mason.nvim" }, + { "neovim/nvim-lspconfig" }, + { "folke/neodev.nvim" }, + }, + config = function() + -- setup lsps + vim.lsp.config('lua_ls', { + settings = { + Lua = { + hint = { enable = true }, + runtime = { version = "LuaJIT" }, + diagnostics = { globals = { "vim", "require" } }, + workspace = { + checkThirdParty = true, + library = { + [vim.fn.expand("$VIMRUNTIME/lua")] = true, + [vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true, + }, + }, + }, + }, + }) + + require("mason-lspconfig").setup { + ensure_installed = { "lua_ls", "vimls", "bashls" }, + automatic_enable = { 'lua_ls', 'vimls', 'bashls' } + } + require("neodev").setup() + + -- setup keymaps + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(_) + -- local fn_format = function() + -- vim.lsp.buf.format({ async = true }) + -- end + -- hover + vim.keymap.set("n", "K", vim.lsp.buf.hover, { desc = "hover (K)" }) + -- vim.keymap.set("n", "lah", vim.lsp.buf.hover, { desc = "hover (K)" }) + -- format + -- vim.keymap.set({ "n", "v" }, "laf", fn_format, { desc = "formatting" }) + -- rename + -- vim.keymap.set({ "n", "v" }, "lar", vim.lsp.buf.rename, { desc = "rename" }) + -- code_action + -- vim.keymap.set({ "n", "v" }, "laa", vim.lsp.buf.code_action, { desc = "code_action" }) + + -- definition + -- vim.keymap.set("n", "lgd", vim.lsp.buf.definition, { desc = "definition" }) + -- declaration + -- vim.keymap.set("n", "lgD", vim.lsp.buf.declaration, { desc = "declaration" }) + -- implementation + -- vim.keymap.set("n", "lgi", vim.lsp.buf.implementation, { desc = "implementation" }) + -- references + -- vim.keymap.set("n", "lgr", vim.lsp.buf.references, { desc = "references" }) + -- type_definition + -- vim.keymap.set("n", "lgt", vim.lsp.buf.type_definition, { desc = "type_definition" }) + end, + }) + end, + }, +} diff --git a/lua/plug/lsp_signature.lua b/lua/plug/lsp_signature.lua new file mode 100644 index 0000000..421fe99 --- /dev/null +++ b/lua/plug/lsp_signature.lua @@ -0,0 +1,9 @@ +return { + { + "ray-x/lsp_signature.nvim", + event = "LspAttach", + config = function() + require("lsp_signature").setup({}) + end, + }, +} diff --git a/lua/plug/ts_folding.lua b/lua/plug/ts_folding.lua new file mode 100644 index 0000000..66cfd9a --- /dev/null +++ b/lua/plug/ts_folding.lua @@ -0,0 +1,57 @@ +return { + { + "kevinhwang91/nvim-ufo", + event = "VeryLazy", + dependencies = { + "kevinhwang91/promise-async", + "nvim-treesitter/nvim-treesitter", + }, + config = function() + vim.o.foldenable = true + vim.o.foldcolumn = "1" + vim.o.foldlevel = 99 + vim.o.foldlevelstart = 99 + + -- vim.keymap.set("n", "zR", require("ufo").openAllFolds) + -- vim.keymap.set("n", "zM", require("ufo").closeAllFolds) + + local handler = function(virtText, lnum, endLnum, width, truncate) + local newVirtText = {} + local suffix = (" 󰁂 %d "):format(endLnum - lnum) + local sufWidth = vim.fn.strdisplaywidth(suffix) + local targetWidth = width - sufWidth + local curWidth = 0 + for _, chunk in ipairs(virtText) do + local chunkText = chunk[1] + local chunkWidth = vim.fn.strdisplaywidth(chunkText) + if targetWidth > curWidth + chunkWidth then + table.insert(newVirtText, chunk) + else + chunkText = truncate(chunkText, targetWidth - curWidth) + local hlGroup = chunk[2] + table.insert(newVirtText, { chunkText, hlGroup }) + chunkWidth = vim.fn.strdisplaywidth(chunkText) + -- str width returned from truncate() may less than 2nd argument, need padding + if curWidth + chunkWidth < targetWidth then + suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth) + end + break + end + curWidth = curWidth + chunkWidth + end + table.insert(newVirtText, { suffix, "MoreMsg" }) + return newVirtText + end + + -- Option 3: treesitter as a main provider instead + -- (Note: the `nvim-treesitter` plugin is *not* needed.) + require("ufo").setup({ + provider_selector = function(bufnr, filetype, buftype) + return { "treesitter", "indent" } + end, + fold_virt_text_handler = handler, + }) + end, + }, +} + diff --git a/lua/plug/ts_outline.lua b/lua/plug/ts_outline.lua new file mode 100644 index 0000000..91d1af8 --- /dev/null +++ b/lua/plug/ts_outline.lua @@ -0,0 +1,13 @@ +return { + { + "stevearc/aerial.nvim", + cmd = "AerialToggle", + dependencies = { + "nvim-treesitter/nvim-treesitter", + "nvim-tree/nvim-web-devicons", + }, + config = function() + require("aerial").setup() + end, + }, +} diff --git a/lua/plug/ts_treesitter.lua b/lua/plug/ts_treesitter.lua new file mode 100644 index 0000000..177b89a --- /dev/null +++ b/lua/plug/ts_treesitter.lua @@ -0,0 +1,19 @@ +return { + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + event = { "BufReadPost", "BufNewFile" }, + opts = { + ensure_installed = { "c", "lua", "vim", "vimdoc", "javascript", "html" }, + sync_install = false, + highlight = { + enable = true, + additional_vim_regex_highlighting = false, + }, + indent = { enable = true }, + }, + config = function(_, opts) + require("nvim-treesitter.configs").setup(opts) + end, + }, +} diff --git a/lua/util/icon.lua b/lua/util/icon.lua new file mode 100644 index 0000000..be874a9 --- /dev/null +++ b/lua/util/icon.lua @@ -0,0 +1,30 @@ +local M = { + diagnostics = { + error = "", + warn = "", + info = "", + hint = "󰌵", + }, +} + +function M.sign_defines() + local icons = M.diagnostics + -- error + local sign_diag_error = { text = icons.error, texthl = "DiagnosticSignError" } + vim.fn.sign_define("DiagnosticSignError", sign_diag_error) + -- warn + local sign_diag_warn = { text = icons.warn, texthl = "DiagnosticSignWarn" } + vim.fn.sign_define("DiagnosticSignWarn", sign_diag_warn) + -- info + local sign_diag_info = { text = icons.info, texthl = "DiagnosticSignInfo" } + vim.fn.sign_define("DiagnosticSignInfo", sign_diag_info) + -- hint + local sign_diag_hint = { text = icons.hint, texthl = "DiagnosticSignHint" } + vim.fn.sign_define("DiagnosticSignHint", sign_diag_hint) +end + +function M.setup() + M.sign_defines() +end + +return M diff --git a/lua/util/lsp.lua b/lua/util/lsp.lua new file mode 100644 index 0000000..ae672e2 --- /dev/null +++ b/lua/util/lsp.lua @@ -0,0 +1,17 @@ +local M = {} + +function M.setup_keys() + vim.api.nvim_create_autocmd("LspAttach", { + callback = function() + local map = vim.keymap.set + + map("n", "K", vim.lsp.buf.hover, { desc = "hover" }) + end + }) +end + +function M.setup() + M.setup_keys() +end + +return M diff --git a/lua/util/path.lua b/lua/util/path.lua new file mode 100644 index 0000000..8cb87cd --- /dev/null +++ b/lua/util/path.lua @@ -0,0 +1,56 @@ +local M = {} + +function M.sep() + return vim.fn.has("win32") and "\\" or "/" +end + +function M.normalize(path) + local parts = {} + for part in path:gmatch("([^/\\\\]*)") do + if part ~= "" then + table.insert(parts, part) + end + end + local path_joined = table.concat(parts, M.sep()) + + local first_char = path:sub(1, 1) + if first_char == "/" or first_char == "\\" then + path_joined = M.sep() .. path_joined + end + local last_char = path:sub(path:len()) + if last_char == "/" or last_char == "\\" then + path_joined = path_joined .. M.sep() + end + return vim.fn.expand(path_joined) +end + +function M.join(base_path, ...) + local parts = { base_path } + for _, part in ipairs({ ... }) do + table.insert(parts, part) + end + + local path_joined = table.concat(parts, M.sep()) + return M.normalize(path_joined) +end + +function M.join_stdpath(what, ...) + local base_path = vim.fn.stdpath(what) + local parts = { base_path } + for _, part in ipairs({ ... }) do + table.insert(parts, part) + end + + local path_joined = table.concat(parts, M.sep()) + return M.normalize(path_joined) +end + +function M.is_directory(path) + return vim.fn.isdirectory(M.normalize(path)) == 1 +end + +function M.is_file(path) + return vim.fn.filereadable(M.normalize(path)) == 1 +end + +return M