diff --git a/.gitignore b/.gitignore index cc5457a..ed1d552 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ debug foo.* *.log data +lazy-lock.json diff --git a/lazyvim.json b/lazyvim.json new file mode 100644 index 0000000..7130344 --- /dev/null +++ b/lazyvim.json @@ -0,0 +1,9 @@ +{ + "extras": [ + "lazyvim.plugins.extras.formatting.prettier" + ], + "news": { + "NEWS.md": "2123" + }, + "version": 3 +} \ No newline at end of file diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index 2c134f7..e00bec3 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -1,3 +1,289 @@ -- Keymaps are automatically loaded on the VeryLazy event -- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua -- Add any additional keymaps here + +function SaveHttpResp() + -- 获取当前时间并格式化为时间戳 + local timestamp = os.date("%Y%m%d%H%M%S") + + -- 获取当前文件的目录路径 + local current_path = vim.fn.expand('%:p:h') + + -- 定位到 rest.nvim 的响应缓冲区 + for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do + if vim.bo[bufnr].filetype == 'httpResult' then + -- 设置保存文件的完整路径,包含时间戳 + local filename = current_path .. "/log/response_" .. timestamp .. ".txt" + vim.api.nvim_buf_call(bufnr, function() + vim.cmd('w ' .. filename) + end) + print("Response saved to " .. filename) + break + end + end +end + +vim.api.nvim_set_keymap('n', 'rr', + ":lua require('rest-nvim').run()", + { noremap = true, silent = true }) + +vim.api.nvim_set_keymap('n', 'rs', + ":lua SaveHttpResp()", + { noremap = true, silent = true }) + + +function GetGoplsRootDir() + local clients = vim.lsp.get_active_clients() + for _, client in ipairs(clients) do + if client.name == "gopls" and client.config.root_dir then + return client.config.root_dir + end + end + return nil -- 返回 nil 如果没有找到 gopls 或者 gopls 没有根目录 +end + +function GoToPathAndLine(input) + if input == '' then + return + end + local parts = vim.split(input, ':') + local file = parts[1] + local line = 1 + if #parts > 1 then + line = parts[2] + end + -- 如果有工作路径,选第一个,否则选当前路径 + local pwd = vim.fn.getcwd() + -- if vim.g.WorkspaceFolders and #vim.g.WorkspaceFolders > 0 then + -- pwd = vim.g.WorkspaceFolders[1] + -- end + local goplsRootDir = GetGoplsRootDir() + if goplsRootDir then + pwd = goplsRootDir + end + vim.cmd('edit +' .. line .. ' ' .. pwd .. '/' .. file) +end + +vim.api.nvim_set_keymap('n', 'gto', ':lua GoToPathAndLine(vim.fn.input("Enter path and line: "))', { noremap = true }) + +function ExportExpandToClipboard() + local pwd = vim.fn.getcwd() + local goplsRootDir = GetGoplsRootDir() + if goplsRootDir then + pwd = goplsRootDir + end + local rf = vim.fn.expand('%:p') .. ':' .. vim.fn.line('.') + local expanded = string.sub(rf, string.len(pwd .. '/') + 1) + vim.fn.setreg('+', expanded) + print('Expanded path copied to clipboard: ' .. expanded) +end + +vim.api.nvim_set_keymap('n', 'gcr', ':lua ExportExpandToClipboard()', { noremap = true }) + + +local function check_spelling() + -- 保存当前文件 + vim.cmd('write') + + -- 获取当前文件的路径 + local current_file = vim.fn.expand('%:p') + print('Spell check in: ' .. current_file) + + -- 构建CSpell命令 + local command = 'cspell --config /Users/onns/.onns/weiyun/code/config/vim/cspell.yaml -r "/Users/onns" ' .. + current_file + + -- 在新的终端窗口中执行CSpell + vim.cmd('split | terminal ' .. command) +end + +-- 将Lua函数绑定到Neovim命令 +vim.api.nvim_create_user_command('SpellCheck', check_spelling, {}) + +vim.api.nvim_set_keymap('n', 'pj', + [[:.s/\v(\w+) \= (\d+).*;/\1 = \2 [(gogoproto.jsontag) = '\1', json_name = '\1'];]], + { noremap = true, silent = true }) +vim.api.nvim_set_keymap('n', 'pf', + [[:.s/\v(\w+) \= (\d+).*;/\1 = \2 [(gogoproto.moretags) = 'form:"\1"',(gogoproto.jsontag) = '\1', json_name = '\1'];]], + { noremap = true, silent = true }) + +function TodoTelescopeWithCWD() + local pwd = vim.fn.getcwd() + local goplsRootDir = GetGoplsRootDir() + if goplsRootDir then + pwd = goplsRootDir + end + print('TodoTelescope at : ' .. pwd) + vim.cmd("TodoTelescope cwd=" .. pwd) +end + +vim.api.nvim_set_keymap('n', 'fw', ':lua TodoTelescopeWithCWD()', { noremap = true }) + +-- 待定列表 +local targets = { "cmd", "CHANGELOG.md", "go.mod", ".git" } + +-- 检查文件或目录是否存在 +local function file_exists(path) + local ok, err, code = os.rename(path, path) + if not ok then + if code == 13 then + -- Permission denied, but it exists + return true + end + end + return ok, err +end + +-- 从当前路径向上查找目标文件或目录 +local function find_upwards() + -- 获取当前文件的路径 + local path = vim.fn.expand('%:p:h') + + while path and path ~= '' do + -- 检查目标文件或目录是否在当前路径 + for _, target in pairs(targets) do + local fullpath = path .. '/' .. target + if file_exists(fullpath) then + return path + end + end + + -- 移动到上一级目录 + path = vim.fn.fnamemodify(path, ':h') + end + return nil +end + +function TodoTelescopeWithProject() + local pwd = vim.fn.getcwd() + local projectDir = find_upwards() + if projectDir then + pwd = projectDir + end + print('TodoTelescope at : ' .. pwd) + vim.cmd("TodoTelescope cwd=" .. pwd) +end + +vim.api.nvim_set_keymap('n', 'fp', ':lua TodoTelescopeWithProject()', { noremap = true }) + + +function InsertGitBranch() + local cwd = vim.fn.getcwd() + local git_branch_cmd = "git -C " .. cwd .. " branch --show-current" + local handle = io.popen(git_branch_cmd) + local git_branch = handle:read("*a") + handle:close() + git_branch = git_branch:gsub("%s+$", "") + if git_branch ~= "" then + -- vim.api.nvim_put({ git_branch }, "", false, true) + local line_num = vim.api.nvim_win_get_cursor(0)[1] + local todo_info = "// TODO: onns " .. git_branch .. " " + vim.api.nvim_buf_set_lines(0, line_num - 1, line_num - 1, false, { todo_info }) + vim.api.nvim_command('startinsert') + vim.api.nvim_win_set_cursor(0, { line_num, #todo_info }) + end +end + +vim.api.nvim_set_keymap('n', 'ig', ':lua InsertGitBranch()', { noremap = true }) + + +local ts_utils = require 'nvim-treesitter.ts_utils' + +function JumpToFunctionName() + -- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('[f', true, true, true), 'm', true) + local node = ts_utils.get_node_at_cursor() + + while node do + -- print(node:type()) + if node:type() == "function_declaration" or node:type() == "method_declaration" then + local child_count = node:child_count() + for i = 0, child_count - 1 do + local child = node:child(i) + -- print("Child " .. i .. ": " .. child:type()) + if child then + if node:type() == "function_declaration" and child:type() == "identifier" then + local start_row, start_col, _, _ = child:range() + vim.api.nvim_win_set_cursor(0, { start_row + 1, start_col }) + return + end + if node:type() == "method_declaration" and child:type() == "field_identifier" then + local start_row, start_col, _, _ = child:range() + vim.api.nvim_win_set_cursor(0, { start_row + 1, start_col }) + return + end + end + end + end + node = node:parent() + end +end + +vim.api.nvim_set_keymap('n', '[n', 'lua JumpToFunctionName()', { noremap = true, silent = true }) + +function GetGoImportPath() + local current_file = vim.api.nvim_buf_get_name(0) + local current_path = vim.fn.fnamemodify(current_file, ":h") + local go_mod_path = vim.fn.findfile("go.mod", current_path .. ";") + if go_mod_path == "" then + return + end + + local go_mod_content = vim.fn.readfile(go_mod_path) + local module_name = nil + for _, line in ipairs(go_mod_content) do + module_name = line:match("^module%s+(%S+)") + if module_name then + break + end + end + if not module_name then + return + end + + local module_root = vim.fn.fnamemodify(go_mod_path, ":h") + + local package_path = string.sub(current_path, string.len(module_root .. '/') + 1) + + local import_package_name = module_name .. "/" .. package_path + vim.fn.setreg('+', import_package_name) + print("Import path copied to clipboard: " .. import_package_name) +end + +vim.api.nvim_set_keymap('n', 'gcp', ':lua GetGoImportPath()', { noremap = true }) + +vim.api.nvim_set_keymap('n', 'fm', + ":lua require('bookmarks').toggle_bookmarks()", + { noremap = true, silent = true }) + +function LiveGrepUp(n) + -- 获取当前工作目录 + local cwd = vim.fn.getcwd() + -- 用系统的路径分隔符分割路径 + local path_sep = package.config:sub(1, 1) + local components = {} + + -- 分割路径到各个组件 + for component in string.gmatch(cwd, "[^" .. path_sep .. "]+") do + table.insert(components, component) + end + + -- 计算向上n级的路径 + local up_n = #components - n + if up_n < 1 then up_n = 1 end -- 确保不会超出根目录 + local new_cwd = path_sep + for i = 1, up_n do + new_cwd = new_cwd .. components[i] .. (i < up_n and path_sep or "") + end + + -- 使用新的目录执行Telescope live_grep + require('telescope.builtin').live_grep({ cwd = new_cwd }) +end + +vim.api.nvim_create_user_command( + 'Lg', + function(opts) + local n = tonumber(opts.args) or 0 + LiveGrepUp(n) + end, + { nargs = 1 } -- 命令接受一个参数 +) diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua index 891b190..00ccbc2 100644 --- a/lua/config/lazy.lua +++ b/lua/config/lazy.lua @@ -2,7 +2,8 @@ local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not vim.loop.fs_stat(lazypath) then -- bootstrap lazy.nvim -- stylua: ignore - vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath }) + vim.fn.system({ "git", "clone", "--filter=blob:none", "git@github.com:folke/lazy.nvim.git", "--branch=stable", + lazypath }) end vim.opt.rtp:prepend(vim.env.LAZY or lazypath) @@ -26,7 +27,7 @@ require("lazy").setup({ version = false, -- always use the latest git commit -- version = "*", -- try installing the latest stable version for plugins that support semver }, - install = { colorscheme = { "tokyonight", "habamax" } }, + install = { colorscheme = { "onedark", "tokyonight", "habamax" } }, checker = { enabled = true }, -- automatically check for plugin updates performance = { rtp = { @@ -44,3 +45,27 @@ require("lazy").setup({ }, }, }) + +require("gitsigns").setup({ + current_line_blame = true, -- Toggle with `:Gitsigns toggle_current_line_blame` + current_line_blame_opts = { + virt_text = true, + virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align' + delay = 100, + ignore_whitespace = false, + virt_text_priority = 100, + }, +}) + +require("lspconfig").gopls.setup({ + cmd = { "gopls", "-remote=unix;/tmp/gopls-daemon-socket" }, +}) + +require("lspconfig").bufls.setup({}) + +-- https://github.com/hrsh7th/nvim-cmp/issues/1809 +-- gopls 在返回提示词的时候随机选择,理论上应该默认选第一个 +local cmp = require("cmp") +cmp.setup({ + preselect = cmp.PreselectMode.None +}) diff --git a/lua/config/options.lua b/lua/config/options.lua index 3ea1454..2e9e456 100644 --- a/lua/config/options.lua +++ b/lua/config/options.lua @@ -1,3 +1,39 @@ -- Options are automatically loaded before lazy.nvim startup -- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua -- Add any additional options here + +-- 拼写检查 +-- vim.opt.spell = true +-- vim.opt.spelllang = "en_us" + +vim.g.go_fmt_command = "gofmt" +vim.g.go_fillstruct_mode = "gopls" +vim.g.go_autodetect_gopath = 1 +vim.g.go_highlight_types = 1 +vim.g.go_highlight_fields = 1 +vim.g.go_highlight_functions = 1 +vim.g.go_highlight_function_calls = 1 +vim.g.go_highlight_extra_types = 1 +vim.g.go_highlight_generate_tags = 1 +vim.g.go_gopls_enabled = 1 +vim.g.go_imports_autosave = 0 +vim.g.go_gopls_options = { "-remote=unix;/tmp/gopls-daemon-socket" } +vim.g.go_def_mode = "gopls" +vim.g.go_info_mode = "gopls" +vim.g.go_referrers_mode = "gopls" + +-- vim.api.nvim_set_keymap('n', 'gd', ':GoDef', { noremap = true, silent = true }) +-- vim.api.nvim_set_keymap('n', 'gr', ':GoReferrers', { noremap = true, silent = true }) +-- vim.api.nvim_set_keymap('n', 'gm', ':GoImplements', { noremap = true, silent = true }) +vim.api.nvim_set_keymap("n", "", ":GoDeclsDir", { silent = true }) +vim.api.nvim_set_keymap("i", " ", ":GoDeclsDir", { silent = true }) +-- vim.api.nvim_set_keymap('n', 'gd', "(coc-definition)", { noremap = true, silent = true }) +-- vim.api.nvim_set_keymap('n', 'gr', "(coc-references)", { noremap = true, silent = true }) +-- vim.api.nvim_set_keymap('n', 'gm', "(coc-implementation)", { noremap = true, silent = true }) + +-- tagbar 打开后自动聚焦 +vim.g.tagbar_autofocus = 1 + +vim.opt.wrap = true + +vim.g.startify_files_number = 20 diff --git a/lua/plugins/cocvim.lua b/lua/plugins/cocvim.lua new file mode 100644 index 0000000..f08e070 --- /dev/null +++ b/lua/plugins/cocvim.lua @@ -0,0 +1,70 @@ +return { + -- { + -- 'neoclide/coc.nvim', + -- branch = 'master', + -- build = "yarn install --frozen-lockfile", + -- }, + { + 'onns/bookmarks.nvim', + keys = {}, + branch = 'main', + dependencies = { 'nvim-web-devicons' }, + config = function() + require("bookmarks").setup() + require("telescope").load_extension("bookmarks") + end + }, + -- { + -- "scrooloose/nerdtree", + -- keys = { + -- { + -- "e", + -- "NERDTreeToggle", + -- desc = "NERDTreeToggle" + -- }, + -- { + -- "v", + -- "NERDTreeFind", + -- desc = "NERDTreeFind" + -- } + -- }, + -- config = function() + -- require("neo-tree").setup() + -- end + -- }, + { + "git@github.com:navarasu/onedark.nvim.git", + lazy = false, + config = function() + require('onedark').setup { + style = 'darker' + } + require('onedark').load() + end + }, + { + 'git@github.com:fatih/vim-go.git' + }, + { + "git@github.com:junegunn/fzf.git" + }, + { + "git@github.com:majutsushi/tagbar.git", + keys = { + { + "t", + "TagbarToggle", + desc = "TagbarToggle" + } + } + }, + { + "git@github.com:mhinz/vim-startify.git", lazy = false + }, + { + 'git@github.com:wakatime/vim-wakatime.git' + }, + { + 'buoto/gotests-vim' + }, +} diff --git a/lua/plugins/disabled.lua b/lua/plugins/disabled.lua new file mode 100644 index 0000000..cd6e95b --- /dev/null +++ b/lua/plugins/disabled.lua @@ -0,0 +1,5 @@ +return { + -- disable trouble + -- { "hrsh7th:/nvim-cmp", enabled = false }, + -- { "hrsh7th/nvim-cmp", enabled = false }, +} \ No newline at end of file diff --git a/lua/plugins/example.lua b/lua/plugins/example.lua deleted file mode 100644 index de22bc8..0000000 --- a/lua/plugins/example.lua +++ /dev/null @@ -1,245 +0,0 @@ --- since this is just an example spec, don't actually load anything here and return an empty spec --- stylua: ignore -if true then return {} end - --- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim --- --- In your plugin files, you can: --- * add extra plugins --- * disable/enabled LazyVim plugins --- * override the configuration of LazyVim plugins -return { - -- add gruvbox - { "ellisonleao/gruvbox.nvim" }, - - -- Configure LazyVim to load gruvbox - { - "LazyVim/LazyVim", - opts = { - colorscheme = "gruvbox", - }, - }, - - -- change trouble config - { - "folke/trouble.nvim", - -- opts will be merged with the parent spec - opts = { use_diagnostic_signs = true }, - }, - - -- disable trouble - { "folke/trouble.nvim", enabled = false }, - - -- override nvim-cmp and add cmp-emoji - { - "hrsh7th/nvim-cmp", - dependencies = { "hrsh7th/cmp-emoji" }, - ---@param opts cmp.ConfigSchema - opts = function(_, opts) - table.insert(opts.sources, { name = "emoji" }) - end, - }, - - -- change some telescope options and a keymap to browse plugin files - { - "nvim-telescope/telescope.nvim", - keys = { - -- add a keymap to browse plugin files - -- stylua: ignore - { - "fp", - function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end, - desc = "Find Plugin File", - }, - }, - -- change some options - opts = { - defaults = { - layout_strategy = "horizontal", - layout_config = { prompt_position = "top" }, - sorting_strategy = "ascending", - winblend = 0, - }, - }, - }, - - -- add pyright to lspconfig - { - "neovim/nvim-lspconfig", - ---@class PluginLspOpts - opts = { - ---@type lspconfig.options - servers = { - -- pyright will be automatically installed with mason and loaded with lspconfig - pyright = {}, - }, - }, - }, - - -- add tsserver and setup with typescript.nvim instead of lspconfig - { - "neovim/nvim-lspconfig", - dependencies = { - "jose-elias-alvarez/typescript.nvim", - init = function() - require("lazyvim.util").lsp.on_attach(function(_, buffer) - -- stylua: ignore - vim.keymap.set( "n", "co", "TypescriptOrganizeImports", { buffer = buffer, desc = "Organize Imports" }) - vim.keymap.set("n", "cR", "TypescriptRenameFile", { desc = "Rename File", buffer = buffer }) - end) - end, - }, - ---@class PluginLspOpts - opts = { - ---@type lspconfig.options - servers = { - -- tsserver will be automatically installed with mason and loaded with lspconfig - tsserver = {}, - }, - -- you can do any additional lsp server setup here - -- return true if you don't want this server to be setup with lspconfig - ---@type table - setup = { - -- example to setup with typescript.nvim - tsserver = function(_, opts) - require("typescript").setup({ server = opts }) - return true - end, - -- Specify * to use this function as a fallback for any server - -- ["*"] = function(server, opts) end, - }, - }, - }, - - -- for typescript, LazyVim also includes extra specs to properly setup lspconfig, - -- treesitter, mason and typescript.nvim. So instead of the above, you can use: - { import = "lazyvim.plugins.extras.lang.typescript" }, - - -- add more treesitter parsers - { - "nvim-treesitter/nvim-treesitter", - opts = { - ensure_installed = { - "bash", - "html", - "javascript", - "json", - "lua", - "markdown", - "markdown_inline", - "python", - "query", - "regex", - "tsx", - "typescript", - "vim", - "yaml", - }, - }, - }, - - -- since `vim.tbl_deep_extend`, can only merge tables and not lists, the code above - -- would overwrite `ensure_installed` with the new value. - -- If you'd rather extend the default config, use the code below instead: - { - "nvim-treesitter/nvim-treesitter", - opts = function(_, opts) - -- add tsx and treesitter - vim.list_extend(opts.ensure_installed, { - "tsx", - "typescript", - }) - end, - }, - - -- the opts function can also be used to change the default opts: - { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - opts = function(_, opts) - table.insert(opts.sections.lualine_x, "😄") - end, - }, - - -- or you can return new options to override all the defaults - { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - opts = function() - return { - --[[add your custom lualine config here]] - } - end, - }, - - -- use mini.starter instead of alpha - { import = "lazyvim.plugins.extras.ui.mini-starter" }, - - -- add jsonls and schemastore packages, and setup treesitter for json, json5 and jsonc - { import = "lazyvim.plugins.extras.lang.json" }, - - -- add any tools you want to have installed below - { - "williamboman/mason.nvim", - opts = { - ensure_installed = { - "stylua", - "shellcheck", - "shfmt", - "flake8", - }, - }, - }, - - -- Use for completion and snippets (supertab) - -- first: disable default and behavior in LuaSnip - { - "L3MON4D3/LuaSnip", - keys = function() - return {} - end, - }, - -- then: setup supertab in cmp - { - "hrsh7th/nvim-cmp", - dependencies = { - "hrsh7th/cmp-emoji", - }, - ---@param opts cmp.ConfigSchema - opts = function(_, opts) - local has_words_before = function() - unpack = unpack or table.unpack - local line, col = unpack(vim.api.nvim_win_get_cursor(0)) - return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil - end - - local luasnip = require("luasnip") - local cmp = require("cmp") - - opts.mapping = vim.tbl_extend("force", opts.mapping, { - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item() - -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() - -- this way you will only jump inside the snippet region - elseif luasnip.expand_or_jumpable() then - luasnip.expand_or_jump() - elseif has_words_before() then - cmp.complete() - 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" }), - }) - end, - }, -} diff --git a/lua/plugins/format.lua b/lua/plugins/format.lua new file mode 100644 index 0000000..a70d32b --- /dev/null +++ b/lua/plugins/format.lua @@ -0,0 +1,11 @@ +return { + { + "stevearc/conform.nvim", + optional = true, + opts = { + formatters_by_ft = { + ["sql"] = { "sql_formatter" }, + }, + }, + }, +} diff --git a/lua/plugins/rest.lua b/lua/plugins/rest.lua new file mode 100644 index 0000000..bec50dd --- /dev/null +++ b/lua/plugins/rest.lua @@ -0,0 +1,43 @@ +return { + "git@github.com:onns/rest.nvim.git", + dependencies = { { "git@github.com:nvim-lua/plenary.nvim.git" } }, + config = function() + require("rest-nvim").setup({ + -- Open request results in a horizontal split + result_split_horizontal = false, + -- Keep the http file buffer above|left when split horizontal|vertical + result_split_in_place = false, + -- Skip SSL verification, useful for unknown certificates + skip_ssl_verification = false, + -- Encode URL before making request + encode_url = true, + -- Highlight request on run + highlight = { + enabled = true, + timeout = 150, + }, + result = { + -- toggle showing URL, HTTP info, headers at top the of result window + show_url = true, + -- show the generated curl command in case you want to launch + -- the same request via the terminal (can be verbose) + show_curl_command = true, + show_http_info = true, + show_headers = true, + -- executables or functions for formatting response body [optional] + -- set them to false if you want to disable them + formatters = { + json = "jq", + html = function(body) + return vim.fn.system({ "tidy", "-i", "-q", "-" }, body) + end + }, + }, + -- Jump to request line on run + jump_to_request = false, + env_file = '.env', + custom_dynamic_variables = {}, + yank_dry_run = true, + }) + end +} diff --git a/lua/plugins/treesitter.lua b/lua/plugins/treesitter.lua new file mode 100644 index 0000000..97a415f --- /dev/null +++ b/lua/plugins/treesitter.lua @@ -0,0 +1,149 @@ +return { + -- Treesitter is a new parser generator tool that we can + -- use in Neovim to power faster and more accurate + -- syntax highlighting. + { + "nvim-treesitter/nvim-treesitter", + version = false, -- last release is way too old and doesn't work on Windows + build = ":TSUpdate", + event = { "LazyFile", "VeryLazy" }, + init = function(plugin) + -- PERF: add nvim-treesitter queries to the rtp and it's custom query predicates early + -- This is needed because a bunch of plugins no longer `require("nvim-treesitter")`, which + -- no longer trigger the **nvim-treesitter** module to be loaded in time. + -- Luckily, the only things that those plugins need are the custom queries, which we make available + -- during startup. + require("lazy.core.loader").add_to_rtp(plugin) + require("nvim-treesitter.query_predicates") + end, + dependencies = { + { + "nvim-treesitter/nvim-treesitter-textobjects", + config = function() + -- When in diff mode, we want to use the default + -- vim text objects c & C instead of the treesitter ones. + local move = require("nvim-treesitter.textobjects.move") ---@type table + local configs = require("nvim-treesitter.configs") + for name, fn in pairs(move) do + if name:find("goto") == 1 then + move[name] = function(q, ...) + if vim.wo.diff then + local config = configs.get_module("textobjects.move")[name] ---@type table + for key, query in pairs(config or {}) do + if q == query and key:find("[%]%[][cC]") then + vim.cmd("normal! " .. key) + return + end + end + end + return fn(q, ...) + end + end + end + end, + }, + }, + cmd = { "TSUpdateSync", "TSUpdate", "TSInstall" }, + keys = { + { "", desc = "Increment selection" }, + { "", desc = "Decrement selection", mode = "x" }, + }, + ---@type TSConfig + ---@diagnostic disable-next-line: missing-fields + opts = { + highlight = { enable = true }, + indent = { enable = true }, + ensure_installed = { + "bash", + "c", + "diff", + "html", + "javascript", + "jsdoc", + "json", + "jsonc", + "lua", + "luadoc", + "luap", + "markdown", + "markdown_inline", + "python", + "query", + "regex", + "toml", + "tsx", + "typescript", + "vim", + "vimdoc", + "xml", + "yaml", + "go", + "http", + "sql", + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + scope_incremental = false, + node_decremental = "", + }, + }, + textobjects = { + move = { + enable = true, + goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer" }, + goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer" }, + goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer" }, + goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer" }, + }, + }, + }, + ---@param opts TSConfig + config = function(_, opts) + if type(opts.ensure_installed) == "table" then + ---@type table + local added = {} + opts.ensure_installed = vim.tbl_filter(function(lang) + if added[lang] then + return false + end + added[lang] = true + return true + end, opts.ensure_installed) + end + require("nvim-treesitter.configs").setup(opts) + end, + }, + + -- Show context of the current function + { + "nvim-treesitter/nvim-treesitter-context", + event = "LazyFile", + enabled = true, + opts = { mode = "cursor", max_lines = 3 }, + keys = { + { + "ut", + function() + local tsc = require("treesitter-context") + tsc.toggle() + if LazyVim.inject.get_upvalue(tsc.toggle, "enabled") then + LazyVim.info("Enabled Treesitter Context", { title = "Option" }) + else + LazyVim.warn("Disabled Treesitter Context", { title = "Option" }) + end + end, + desc = "Toggle Treesitter Context", + }, + }, + }, + + -- Automatically add closing tags for HTML and JSX + { + "windwp/nvim-ts-autotag", + event = "LazyFile", + opts = {}, + }, +}