diff --git a/.stylua.toml b/.stylua.toml index 35de157..9deac85 100644 --- a/.stylua.toml +++ b/.stylua.toml @@ -2,8 +2,8 @@ column_width = 120 line_endings = "Unix" indent_type = "Spaces" indent_width = 2 -quote_style = "AutoPreferDouble" -call_parentheses = "Always" +quote_style = "AutoPreferSingle" +call_parentheses = "None" collapse_simple_statement = "Always" [sort_requires] diff --git a/config/nvim/.editorconfig b/config/nvim/.editorconfig index 6b3fcae..d775947 100644 --- a/config/nvim/.editorconfig +++ b/config/nvim/.editorconfig @@ -9,7 +9,7 @@ insert_final_newline = true charset = utf-8 indent_style = space indent_size = 2 -max_line_length = 100 +max_line_length = 120 trim_trailing_whitespace = true [*.md] diff --git a/config/nvim/.stylua.toml b/config/nvim/.stylua.toml index e96067f..edd9761 100644 --- a/config/nvim/.stylua.toml +++ b/config/nvim/.stylua.toml @@ -1,7 +1,11 @@ -column_width = 160 +column_width = 120 line_endings = "Unix" indent_type = "Spaces" indent_width = 2 quote_style = "AutoPreferSingle" call_parentheses = "None" +collapse_simple_statement = "Always" + +[sort_requires] +enabled = true diff --git a/config/nvim/lua/autogroups.lua b/config/nvim/lua/autogroups.lua index dd30e95..c999f13 100644 --- a/config/nvim/lua/autogroups.lua +++ b/config/nvim/lua/autogroups.lua @@ -9,18 +9,14 @@ local autocmd = vim.api.nvim_create_autocmd -- Create autocommand -- See `:help vim.highlight.on_yank()` local highlight_group = augroup('YankHighlight', { clear = true }) autocmd('TextYankPost', { - callback = function() - vim.highlight.on_yank() - end, + callback = function() vim.highlight.on_yank() end, group = highlight_group, pattern = '*', }) -- ── Windows to close with "q" ─────────────────────────────────────── autocmd('FileType', { - callback = function() - vim.keymap.set('n', '', ':bd', { buffer = true, silent = true }) - end, + callback = function() vim.keymap.set('n', '', ':bd', { buffer = true, silent = true }) end, pattern = { 'help', 'startuptime', diff --git a/config/nvim/lua/options.lua b/config/nvim/lua/options.lua index 60e4d24..a392e3a 100644 --- a/config/nvim/lua/options.lua +++ b/config/nvim/lua/options.lua @@ -32,9 +32,7 @@ vim.opt.showmode = false -- Sync clipboard between OS and Neovim. -- Schedule the setting after `UiEnter` because it can increase startup-time. -- See `:help 'clipboard'` -vim.schedule(function() - vim.opt.clipboard = 'unnamedplus' -end) +vim.schedule(function() vim.opt.clipboard = 'unnamedplus' end) vim.opt.breakindent = true -- Enable break indent vim.opt.smartindent = true -- Insert indents automatically @@ -103,6 +101,14 @@ vim.o.winwidth = 15 vim.o.winminwidth = 10 vim.o.equalalways = false +-- folke/noice.nvim settings +vim.g.noice_ignored_filetypes = { + 'fugitiveblame', + 'fugitive', + 'gitcommit', + 'noice', +} + -- ── Deal with word wrap ─────────────────────────────────────────────────────── local m = vim.api.nvim_set_keymap m('n', 'k', "v:count == 0 ? 'gk' : 'k'", { desc = 'Move up', noremap = true, expr = true }) diff --git a/config/nvim/lua/plugins/autoformat.lua b/config/nvim/lua/plugins/autoformat.lua deleted file mode 100644 index 58a6189..0000000 --- a/config/nvim/lua/plugins/autoformat.lua +++ /dev/null @@ -1,36 +0,0 @@ --- Autoformat --- https://github.com/stevearc/conform.nvim -return { - 'stevearc/conform.nvim', - event = { 'BufWritePre' }, - cmd = { 'ConformInfo' }, - keys = { - { - 'cf', - 'lua require("conform").format({ async = true, lsp_fallback = true })', - mode = '', - desc = 'Format buffer', - }, - }, - opts = { - notify_on_error = false, - format_on_save = function(bufnr) - -- Disable "format_on_save lsp_fallback" for languages that don't - -- have a well standardized coding style. You can add additional - -- languages here or re-enable it for the disabled ones. - local disable_filetypes = { c = true, cpp = true } - return { - timeout_ms = 500, - lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype], - } - end, - formatters_by_ft = { - lua = { 'stylua' }, - -- Conform can also run multiple formatters sequentially - -- python = { "isort", "black" }, - -- - -- You can use 'stop_after_first' to run the first available formatter from the list - javascript = { 'prettierd', 'prettier', stop_after_first = true }, - }, - }, -} diff --git a/config/nvim/lua/plugins/cmp.lua b/config/nvim/lua/plugins/cmp.lua index 9c40037..5c2c51d 100644 --- a/config/nvim/lua/plugins/cmp.lua +++ b/config/nvim/lua/plugins/cmp.lua @@ -20,6 +20,7 @@ return { { 'hrsh7th/cmp-nvim-lsp' }, { 'hrsh7th/cmp-buffer' }, { 'hrsh7th/cmp-path' }, + -- cmp import and use all environment variables from .env.* and system -- https://github.com/SergioRibera/cmp-dotenv { 'SergioRibera/cmp-dotenv' }, -- ── Other deps ────────────────────────────────────────────────────── @@ -39,8 +40,8 @@ return { cmd = 'Copilot', build = ':Copilot setup', event = { 'InsertEnter', 'LspAttach' }, - fix_pairs = true, opts = { + fix_pairs = true, suggestion = { enabled = false }, panel = { enabled = false }, filetypes = { @@ -50,9 +51,7 @@ return { }, }, }, - config = function() - require('copilot_cmp').setup() - end, + config = function() require('copilot_cmp').setup() end, }, }, config = function() @@ -63,10 +62,8 @@ return { require('copilot_cmp').setup() local has_words_before = function() - if vim.api.nvim_get_option_value('buftype', {}) == 'prompt' then - return false - end - local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + if vim.api.nvim_get_option_value('buftype', {}) == 'prompt' then return false end + local line, col = table.unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and vim.api.nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1]:match '^%s*$' == nil end @@ -74,9 +71,7 @@ return { formatting = { format = lspkind.cmp_format { mode = 'symbol', - max_width = function() - return math.floor(0.45 * vim.o.columns) - end, + max_width = function() return math.floor(0.45 * vim.o.columns) end, show_labelDetails = true, symbol_map = { Copilot = '', @@ -84,18 +79,14 @@ return { }, }, view = { - width = function(_, _) - return math.min(80, vim.o.columns) - end, + width = function(_, _) return math.min(80, vim.o.columns) end, entries = { name = 'custom', selection_order = 'near_cursor', }, }, snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, + expand = function(args) luasnip.lsp_expand(args.body) end, }, mapping = cmp.mapping.preset.insert { [''] = cmp.mapping.scroll_docs(-4), diff --git a/config/nvim/lua/plugins/lazy.lua b/config/nvim/lua/plugins/lazy.lua index b5967fd..bfe0288 100644 --- a/config/nvim/lua/plugins/lazy.lua +++ b/config/nvim/lua/plugins/lazy.lua @@ -3,28 +3,57 @@ return { -- A better annotation generator. -- Supports multiple languages and annotation conventions. -- https://github.com/danymat/neogen - { 'danymat/neogen', version = '*', opts = { enabled = true, snippet_engine = 'luasnip' } }, + { + 'danymat/neogen', + version = '*', + opts = { enabled = true, snippet_engine = 'luasnip' }, + }, -- The Refactoring library based off the Refactoring book by Martin Fowler -- https://github.com/ThePrimeagen/refactoring.nvim - { 'ThePrimeagen/refactoring.nvim', dependencies = { 'nvim-lua/plenary.nvim', 'nvim-treesitter/nvim-treesitter' }, opts = {} }, + { + 'ThePrimeagen/refactoring.nvim', + version = '*', + dependencies = { 'nvim-lua/plenary.nvim', 'nvim-treesitter/nvim-treesitter' }, + opts = {}, + }, -- All the npm/yarn/pnpm commands I don't want to type -- https://github.com/vuki656/package-info.nvim - { 'vuki656/package-info.nvim', dependencies = { 'MunifTanjim/nui.nvim' } }, + { + 'vuki656/package-info.nvim', + version = '*', + dependencies = { 'MunifTanjim/nui.nvim' }, + opts = {}, + }, -- Add/change/delete surrounding delimiter pairs with ease. Written with ❤️ in Lua. -- https://github.com/kylechui/nvim-surround - { 'kylechui/nvim-surround', version = '*', event = 'VeryLazy' }, + { + 'kylechui/nvim-surround', + version = '*', + event = 'VeryLazy', + opts = {}, + }, -- Highlight, list and search todo comments in your projects -- https://github.com/folke/todo-comments.nvim - { 'folke/todo-comments.nvim', dependencies = { 'nvim-lua/plenary.nvim' }, opts = {} }, + { + 'folke/todo-comments.nvim', + version = '*', + dependencies = { 'nvim-lua/plenary.nvim' }, + opts = {}, + }, -- Commenting -- "gc" to comment visual regions/lines -- https://github.com/numToStr/Comment.nvim - { 'numToStr/Comment.nvim', event = { 'BufRead', 'BufNewFile' }, opts = {} }, + { + 'numToStr/Comment.nvim', + version = '*', + event = { 'BufRead', 'BufNewFile' }, + opts = {}, + }, -- Detect tabstop and shiftwidth automatically -- https://github.com/tpope/vim-sleuth diff --git a/config/nvim/lua/plugins/lsp.lua b/config/nvim/lua/plugins/lsp.lua index af4257c..5211228 100644 --- a/config/nvim/lua/plugins/lsp.lua +++ b/config/nvim/lua/plugins/lsp.lua @@ -1,62 +1,62 @@ --- Quickstart configs for Nvim LSP +-- Quick start configs for Nvim LSP -- https://github.com/neovim/nvim-lspconfig return { { 'neovim/nvim-lspconfig', lazy = false, dependencies = { - -- Garbage collector that stops inactive LSP clients to free RAM - -- https://github.com/Zeioth/garbage-day.nvim - { - 'zeioth/garbage-day.nvim', - dependencies = 'neovim/nvim-lspconfig', - event = 'VeryLazy', - opts = {}, - }, - - -- improve neovim lsp experience - -- https://github.com/nvimdev/lspsaga.nvim - { - 'nvimdev/lspsaga.nvim', - dependencies = { - 'nvim-treesitter/nvim-treesitter', -- optional - 'nvim-tree/nvim-web-devicons', -- optional - }, - opts = { - code_action = { - show_server_name = true, - }, - diagnostic = { - keys = { - quit = { 'q', '' }, - }, - }, - }, - }, - -- ── Mason and LSPConfig integration ───────────────────────────────── -- Automatically install LSPs to stdpath for neovim -- Portable package manager for Neovim that runs everywhere Neovim runs. - -- Easily install and manage LSP servers, DAP servers, linters, - -- and formatters. + -- Easily install and manage LSP servers, DAP servers, linters, and formatters. -- https://github.com/williamboman/mason.nvim - { 'williamboman/mason.nvim' }, + { + 'williamboman/mason.nvim', + cmd = 'Mason', + run = ':MasonUpdate', + }, + -- Extension to mason.nvim that makes it easier to use lspconfig with mason.nvim. + -- https://github.com/williamboman/mason-lspconfig.nvim { 'williamboman/mason-lspconfig.nvim' }, + -- Install and upgrade third party tools automatically + -- https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim { 'WhoIsSethDaniel/mason-tool-installer.nvim' }, - -- ── Linting ───────────────────────────────────────────────────────── - -- An asynchronous linter plugin for Neovim complementary to the - -- built-in Language Server Protocol support. - -- https://github.com/mfussenegger/nvim-lint + -- ── Formatting ────────────────────────────────────────────────────── + -- Lightweight yet powerful formatter plugin for Neovim + -- https://github.com/stevearc/conform.nvim { - 'mfussenegger/nvim-lint', - event = { 'BufReadPre', 'BufNewFile' }, + 'stevearc/conform.nvim', + event = { 'BufWritePre' }, + cmd = { 'ConformInfo' }, + opts = { + formatters_by_ft = { + lua = { 'stylua' }, + -- Conform will run multiple formatters sequentially + -- python = { 'isort', 'black', lsp_format = 'fallback' }, + -- You can customize some of the format options for the filetype (:help conform.format) + -- rust = { 'rustfmt', lsp_format = 'fallback' }, + -- Conform will run the first available formatter + javascript = { 'prettier', 'eslint', stop_after_first = true }, + }, + notify_on_error = true, + format_on_save = function(bufnr) + -- Disable "format_on_save lsp_fallback" for languages that don't + -- have a well standardized coding style. You can add additional + -- languages here or re-enable it for the disabled ones. + local disable_filetypes = { c = true, cpp = true } + return { + -- formatters = { 'injected' }, + lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype], + timeout_ms = 500, + } + end, + }, }, - -- Extension to mason.nvim that makes it - -- easier to use nvim-lint with mason.nvim - -- https://github.com/rshkarin/mason-nvim-lint - { 'rshkarin/mason-nvim-lint' }, + -- Automatically install formatters registered with conform.nvim via mason.nvim + -- https://github.com/zapling/mason-conform.nvim + { 'zapling/mason-conform.nvim' }, -- ── Misc ──────────────────────────────────────────────────────────── -- vscode-like pictograms for neovim lsp completion items @@ -83,13 +83,13 @@ return { local on_attach = function(_, bufnr) -- Create a command `:Format` local to the LSP buffer vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) - if vim.lsp.buf.format then - vim.lsp.buf.format() - elseif vim.lsp.buf.formatting then - vim.lsp.buf.formatting() - else - require('conform').format { async = true, lsp_fallback = true } - end + require('conform').format { formatters = { 'injected' }, async = true, lsp_fallback = true } + + -- if vim.lsp.buf.format then + -- vim.lsp.buf.format() + -- elseif vim.lsp.buf.formatting then + -- vim.lsp.buf.formatting() + -- end end, { desc = 'Format current buffer with LSP' }) end @@ -99,37 +99,13 @@ return { -- ── Enable the following language servers ─────────────────────────── -- :help lspconfig-all for all pre-configured LSPs local servers = { - ast_grep = {}, - - actionlint = {}, -- GitHub Actions - ansiblels = {}, -- Ansible bashls = {}, -- Bash -- csharp_ls = {}, -- C#, requires dotnet executable - css_variables = {}, -- CSS - cssls = {}, -- CSS - docker_compose_language_service = {}, -- Docker compose - dockerls = {}, -- Docker - eslint = {}, -- ESLint - gitlab_ci_ls = {}, -- GitLab CI gopls = {}, -- Go html = {}, -- HTML intelephense = {}, -- PHP - pest_ls = {}, -- Pest (PHP) - phpactor = {}, -- PHP - psalm = {}, -- PHP - pyright = {}, -- Python - semgrep = {}, -- Security - shellcheck = {}, -- Shell scripts - shfmt = {}, -- Shell scripts formatting - stylelint_lsp = {}, -- Stylelint for S/CSS - stylua = {}, -- Used to format Lua code tailwindcss = {}, -- Tailwind CSS - terraformls = {}, -- Terraform - tflint = {}, -- Terraform - ts_ls = {}, -- TypeScript/JS - typos_lsp = {}, -- Better writing - volar = {}, -- Vue - yamlls = {}, -- YAML + ts_ls = {}, -- TypeScript lua_ls = { settings = { @@ -184,31 +160,24 @@ return { -- Mason servers should be it's own variable for mason-nvim-lint -- See: https://mason-registry.dev/registry/list local mason_servers = { - 'actionlint', - 'ansible-language-server', - 'ansible-lint', 'bash-language-server', - 'blade-formatter', 'clang-format', + 'codespell', 'commitlint', 'diagnostic-languageserver', - 'docker-compose-language-service', - 'dockerfile-language-server', 'editorconfig-checker', 'fixjson', - 'flake8', - 'html-lsp', - 'jq', 'jsonlint', + 'lua-language-server', 'luacheck', - 'php-cs-fixer', + 'phpcbf', 'phpcs', 'phpmd', - 'semgrep', + 'prettier', 'shellcheck', 'shfmt', - 'stylelint', 'stylua', + 'vim-language-server', 'vue-language-server', 'yamllint', } @@ -221,43 +190,35 @@ return { auto_update = true, } - -- ── Ensure the servers above are installed ────────────────────────── - require('mason-lspconfig').setup { - automatic_installation = true, - ensure_installed = servers, - } - -- nvim-cmp supports additional completion capabilities local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + -- Tell the server the capability of foldingRange, + -- Neovim hasn't added foldingRange to default capabilities, users must add it manually + capabilities.textDocument.foldingRange = { + dynamicRegistration = true, + lineFoldingOnly = true, + } - require('mason-lspconfig').setup_handlers { + local lspconfig_handlers = { -- The first entry (without a key) will be the default handler -- and will be called for each installed server that doesn't have -- a dedicated handler. function(server_name) -- default handler (optional) - require('lspconfig')[server_name].setup {} + require('lspconfig')[server_name].setup { + on_attach = on_attach, + capabilities = capabilities, + } end, - -- Next, you can provide a dedicated handler for specific servers. - -- For example, a handler override for the `rust_analyzer`: - -- ['rust_analyzer'] = function() - -- require('rust-tools').setup {} - -- end, + -- Next, you can provide targeted overrides for specific servers. + ['lua_ls'] = function() require('lspconfig')['lua_ls'].setup { settings = servers.lua_ls } end, + ['jsonls'] = function() require('lspconfig')['jsonls'].setup { settings = servers.jsonls } end, } - for _, lsp in ipairs(servers) do - require('lspconfig')[lsp].setup { - on_attach = on_attach, - capabilities = capabilities, - } - end - - require('lspconfig').lua_ls.setup { - on_attach = on_attach, - capabilities = capabilities, - settings = { - Lua = servers.lua_ls.settings.Lua, - }, + require('mason-lspconfig').setup { + ensure_installed = vim.tbl_keys(servers or {}), + automatic_installation = true, + handlers = lspconfig_handlers, } vim.api.nvim_create_autocmd('FileType', { @@ -270,19 +231,158 @@ return { end, }) - -- ── Setup linting ─────────────────────────────────────────────────── - require('mason-nvim-lint').setup { - ensure_installed = mason_servers or {}, - quiet_mode = true, + -- ── Setup formatting ──────────────────────────────────────────────── + require('mason-conform').setup { + -- ignore_install = { 'prettier' }, -- List of formatters to ignore during install } - local lint = require 'lint' - local lint_augroup = vim.api.nvim_create_augroup('lint', { clear = true }) - vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { - group = lint_augroup, - callback = function() - lint.try_lint() + end, + }, + + -- Garbage collector that stops inactive LSP clients to free RAM + -- https://github.com/Zeioth/garbage-day.nvim + { + 'zeioth/garbage-day.nvim', + dependencies = 'neovim/nvim-lspconfig', + event = 'VeryLazy', + opts = {}, + }, + + -- improve neovim lsp experience + -- https://github.com/nvimdev/lspsaga.nvim + -- https://nvimdev.github.io/lspsaga/ + { + 'nvimdev/lspsaga.nvim', + event = 'LspAttach', + dependencies = { + 'nvim-treesitter/nvim-treesitter', -- optional + 'nvim-tree/nvim-web-devicons', -- optional + }, + opts = { + code_action = { + show_server_name = true, + }, + diagnostic = { + keys = { + quit = { 'q', '' }, + }, + }, + }, + }, + + -- Not UFO in the sky, but an ultra fold in Neovim. + -- https://github.com/kevinhwang91/nvim-ufo/ + { + 'kevinhwang91/nvim-ufo', + version = '*', + dependencies = { + { 'neovim/nvim-lspconfig' }, + { 'kevinhwang91/promise-async' }, + { 'nvim-treesitter/nvim-treesitter', run = ':TSUpdate' }, + { + -- Status column plugin that provides a configurable + -- 'statuscolumn' and click handlers. + -- https://github.com/luukvbaal/statuscol.nvim + 'luukvbaal/statuscol.nvim', + config = function() + local builtin = require 'statuscol.builtin' + require('statuscol').setup { + relculright = true, + segments = { + { + text = { builtin.foldfunc }, + click = 'v:lua.ScFa', + }, + { + sign = { + namespace = { 'diagnostic/signs' }, + maxwidth = 2, + -- auto = true, + }, + click = 'v:lua.ScSa', + }, + { + text = { builtin.lnumfunc, ' ' }, + click = 'v:lua.ScLa', + }, + }, + } end, - }) + }, + }, + config = function() + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities.textDocument.foldingRange = { + dynamicRegistration = false, + lineFoldingOnly = true, + } + local language_servers = require('lspconfig').util.available_servers() -- or list servers manually like {'gopls', 'clangd'} + for _, ls in ipairs(language_servers) do + require('lspconfig')[ls].setup { + capabilities = capabilities, + -- you can add other fields for setting up lsp server in this table + } + end + + require('ufo').setup { + open_fold_hl_timeout = 150, + close_fold_kinds_for_ft = { 'imports', 'comment' }, + preview = { + win_config = { + border = { '', '─', '', '', '', '─', '', '' }, + winhighlight = 'Normal:Folded', + winblend = 0, + }, + mappings = { + scrollU = '', + scrollD = '', + jumpTop = '[', + jumpBot = ']', + }, + }, + + provider_selector = function(_, _, _) -- bufnr, filetype, buftype + return { 'treesitter', 'indent' } + end, + + -- fold_virt_text_handler + -- + -- This handler is called when the fold text is too long to fit in the window. + -- It is expected to truncate the text and return a new list of virtual text. + -- + ---@param virtText table The current virtual text list. + ---@param lnum number The line number of the first line in the fold. + ---@param endLnum number The line number of the last line in the fold. + ---@param width number The width of the window. + ---@param truncate function Truncate function + ---@return table + fold_virt_text_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, + } end, }, } diff --git a/config/nvim/lua/plugins/lualine.lua b/config/nvim/lua/plugins/lualine.lua index 7c183ab..0256e85 100644 --- a/config/nvim/lua/plugins/lualine.lua +++ b/config/nvim/lua/plugins/lualine.lua @@ -6,33 +6,67 @@ return { 'kyazdani42/nvim-web-devicons', 'folke/noice.nvim', }, - opts = { - options = { - icons_enabled = true, - component_separators = '|', - section_separators = '', - }, - -- Sections - -- +-------------------------------------------------+ - -- | A | B | C X | Y | Z | - -- +-------------------------------------------------+ - sections = { - lualine_b = { - { - 'buffers', - }, - }, + config = function() + local function diff_source() + local gitsigns = vim.b.gitsigns_status_dict + if gitsigns then + return { + added = gitsigns.added, + modified = gitsigns.changed, + removed = gitsigns.removed, + } + end + end - lualine_x = { - { - require('noice').api.statusline.mode.get, - cond = require('noice').api.statusline.mode.has, + require('lualine').setup { + options = { + icons_enabled = true, + component_separators = '|', + section_separators = '', + }, + -- Sections + -- +-------------------------------------------------+ + -- | A | B | C X | Y | Z | + -- +-------------------------------------------------+ + sections = { + lualine_a = { + 'mode', }, - { - require('noice').api.status.command.get, - cond = require('noice').api.status.command.has, + lualine_b = { + { 'b:gitsigns_head', icon = '' }, + { 'diff', source = diff_source }, + 'diagnostics', + }, + lualine_c = { + 'buffers', + -- 'filename', + }, + lualine_x = { + -- 'fileformat', + 'filetype', + }, + lualine_y = { + -- 'progress' + }, + lualine_z = { + { + require('noice').api.statusline.mode.get, + cond = require('noice').api.statusline.mode.has, + }, + { + require('noice').api.status.command.get, + cond = require('noice').api.status.command.has, + }, }, }, - }, - }, + inactive_sections = { + lualine_a = {}, + lualine_b = {}, + lualine_c = { 'filename' }, + lualine_x = { 'location' }, + lualine_y = {}, + lualine_z = {}, + }, + } + end, } diff --git a/config/nvim/lua/plugins/noice.lua b/config/nvim/lua/plugins/noice.lua index c4fddc1..713bc9a 100644 --- a/config/nvim/lua/plugins/noice.lua +++ b/config/nvim/lua/plugins/noice.lua @@ -2,13 +2,6 @@ -- for messages, cmdline and the popupmenu. -- https://github.com/folke/noice.nvim -vim.g.noice_ignored_filetypes = { - 'fugitiveblame', - 'fugitive', - 'gitcommit', - 'noice', -} - return { 'folke/noice.nvim', lazy = false, diff --git a/config/nvim/lua/plugins/telescope.lua b/config/nvim/lua/plugins/telescope.lua index f4ff5e4..71cfa90 100644 --- a/config/nvim/lua/plugins/telescope.lua +++ b/config/nvim/lua/plugins/telescope.lua @@ -41,12 +41,18 @@ return { :find() end - vim.keymap.set('n', 'hw', function() - toggle_telescope(harpoon:list()) - end, { desc = 'Open harpoon window with telescope' }) - vim.keymap.set('n', 'ht', function() - harpoon.ui:toggle_quick_menu(harpoon:list()) - end, { desc = 'Open Harpoon Quick menu' }) + vim.keymap.set( + 'n', + 'hw', + function() toggle_telescope(harpoon:list()) end, + { desc = 'Open harpoon window with telescope' } + ) + vim.keymap.set( + 'n', + 'ht', + function() harpoon.ui:toggle_quick_menu(harpoon:list()) end, + { desc = 'Open Harpoon Quick menu' } + ) end, }, -- A Telescope picker to quickly access configurations @@ -86,6 +92,12 @@ return { }, }, }, + extensions = { + lazy_plugins = { + -- Must be a valid path to the file containing the lazy spec and setup() call. + lazy_config = vim.fn.stdpath 'config' .. '/init.lua', + }, + }, } -- Load extensions diff --git a/config/nvim/lua/plugins/treesitter.lua b/config/nvim/lua/plugins/treesitter.lua index 66d3e5d..8b74a0f 100644 --- a/config/nvim/lua/plugins/treesitter.lua +++ b/config/nvim/lua/plugins/treesitter.lua @@ -2,9 +2,7 @@ -- https://github.com/nvim-treesitter/nvim-treesitter return { 'nvim-treesitter/nvim-treesitter', - build = function() - pcall(require('nvim-treesitter.install').update { with_sync = true }) - end, + build = function() pcall(require('nvim-treesitter.install').update { with_sync = true }) end, dependencies = { 'nvim-treesitter/nvim-treesitter-textobjects', }, diff --git a/config/nvim/lua/plugins/ufo.lua b/config/nvim/lua/plugins/ufo.lua deleted file mode 100644 index 5fbfcb9..0000000 --- a/config/nvim/lua/plugins/ufo.lua +++ /dev/null @@ -1,77 +0,0 @@ --- Not UFO in the sky, but an ultra fold in Neovim. --- https://github.com/kevinhwang91/nvim-ufo/ -return { - { - 'kevinhwang91/nvim-ufo', - version = '*', - dependencies = { - { 'kevinhwang91/promise-async' }, - { 'nvim-treesitter/nvim-treesitter', run = ':TSUpdate' }, - { - -- Status column plugin that provides a configurable - -- 'statuscolumn' and click handlers. - -- https://github.com/luukvbaal/statuscol.nvim - 'luukvbaal/statuscol.nvim', - opts = {}, - }, - }, - opts = { - open_fold_hl_timeout = 150, - close_fold_kinds_for_ft = { 'imports', 'comment' }, - preview = { - win_config = { - border = { '', '─', '', '', '', '─', '', '' }, - winhighlight = 'Normal:Folded', - winblend = 0, - }, - mappings = { - scrollU = '', - scrollD = '', - jumpTop = '[', - jumpBot = ']', - }, - }, - provider_selector = function(_, _, _) -- bufnr, filetype, buftype - return { 'treesitter', 'indent' } - end, - -- fold_virt_text_handler - -- - -- This handler is called when the fold text is too long to fit in the window. - -- It is expected to truncate the text and return a new list of virtual text. - -- - ---@param virtText table The current virtual text list. - ---@param lnum number The line number of the first line in the fold. - ---@param endLnum number The line number of the last line in the fold. - ---@param width number The width of the window. - ---@param truncate function Truncate function - ---@return table - fold_virt_text_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, - }, - }, -} diff --git a/config/nvim/lua/plugins/ui.lua b/config/nvim/lua/plugins/ui.lua index ad974a8..fdbf097 100644 --- a/config/nvim/lua/plugins/ui.lua +++ b/config/nvim/lua/plugins/ui.lua @@ -4,9 +4,7 @@ return { { 'folke/tokyonight.nvim', priority = 1000, -- Make sure to load this before all the other start plugins. - init = function() - vim.cmd.colorscheme(vim.g.colors_theme) - end, + init = function() vim.cmd.colorscheme(vim.g.colors_theme) end, opts = { transparent = true, }, @@ -29,6 +27,58 @@ return { }, }, + -- vim dashboard + -- https://github.com/nvimdev/dashboard-nvim + { + 'nvimdev/dashboard-nvim', + event = 'VimEnter', + config = function() + require('dashboard').setup { + config = { + disable_move = true, + week_header = { + enable = true, + }, + shortcut = { + { + desc = '󰊳 Lazy Update', + group = '@property', + action = 'Lazy update', + key = 'u', + }, + { + icon = ' ', + icon_hl = '@variable', + desc = 'Files', + group = 'Label', + action = 'Telescope find_files', + key = 'f', + }, + { + desc = ' Marks', + group = 'DiagnosticHint', + action = 'Telescope harpoon marks', + key = 'a', + }, + { + desc = '⚑ TODO', + group = 'DiagnosticOptions', + action = 'TodoTelescope', + key = 't', + }, + { + desc = '🔍 Search', + group = 'Number', + action = 'Telescope live_grep', + key = 's', + }, + }, + }, + } + end, + dependencies = { { 'nvim-tree/nvim-web-devicons' } }, + }, + -- Remove all background colors to make nvim transparent -- https://github.com/xiyaowong/nvim-transparent { 'xiyaowong/nvim-transparent', opts = {} }, @@ -40,7 +90,21 @@ return { -- Indent guides for Neovim -- https://github.com/lukas-reineke/indent-blankline.nvim - { 'lukas-reineke/indent-blankline.nvim', main = 'ibl', opts = {} }, + { + 'lukas-reineke/indent-blankline.nvim', + main = 'ibl', + config = function() + require('ibl').setup { + indent = { + char = '│', + }, + exclude = { + filetypes = { 'terminal', 'dashboard' }, + buftypes = { 'dashboard' }, + }, + } + end, + }, -- Git integration for buffers -- https://github.com/lewis6991/gitsigns.nvim @@ -67,22 +131,14 @@ return { -- Navigation map('n', 'gn', function() - if vim.wo.diff then - return ']c' - end - vim.schedule(function() - gs.next_hunk() - end) + if vim.wo.diff then return ']c' end + vim.schedule(function() gs.next_hunk() end) return '' end, { expr = true }) map('n', 'gp', function() - if vim.wo.diff then - return '[c' - end - vim.schedule(function() - gs.prev_hunk() - end) + if vim.wo.diff then return '[c' end + vim.schedule(function() gs.prev_hunk() end) return '' end, { expr = true }) end, @@ -142,7 +198,6 @@ return { { 'bennypowers/nvim-regexplainer', event = 'BufEnter', - lazy = false, dependencies = { 'nvim-treesitter/nvim-treesitter', 'MunifTanjim/nui.nvim', diff --git a/config/nvim/lua/plugins/which-key.lua b/config/nvim/lua/plugins/which-key.lua index ab720c5..84c6fb0 100644 --- a/config/nvim/lua/plugins/which-key.lua +++ b/config/nvim/lua/plugins/which-key.lua @@ -27,12 +27,12 @@ return { return require('which-key.extras').expand.buf() end, }, - { 'bk', 'blast', desc = 'Buffer: Last', mode = 'n' }, - { 'bj', 'bfirst', desc = 'Buffer: First', mode = 'n' }, - { 'bh', 'bprev', desc = 'Buffer: Prev', mode = 'n' }, - { 'bl', 'bnext', desc = 'Buffer: Next', mode = 'n' }, - { 'bd', 'Bdelete', desc = 'Buffer: Delete', mode = 'n' }, - { 'bw', 'Bwipeout', desc = 'Buffer: Wipeout', mode = 'n' }, + { 'bk', 'blast', desc = 'Buffer: Last' }, + { 'bj', 'bfirst', desc = 'Buffer: First' }, + { 'bh', 'bprev', desc = 'Buffer: Prev' }, + { 'bl', 'bnext', desc = 'Buffer: Next' }, + { 'bd', 'Bdelete', desc = 'Buffer: Delete' }, + { 'bw', 'Bwipeout', desc = 'Buffer: Wipeout' }, -- ── Code ──────────────────────────────────────────────────────────── { 'c', group = '[c] Code' }, @@ -52,26 +52,56 @@ return { { 'cni', 'lua require("package-info").install()', desc = 'Install package' }, { 'cns', 'lua require("package-info").show({ force = true })', desc = 'Show package info' }, { 'cnu', 'lua require("package-info").change_version()', desc = 'Change version' }, + -- ── Code: Refactoring ─────────────────────────────────────────────── { 'cx', group = '[x] Refactoring' }, { mode = { 'x' }, -- Extract function supports only visual mode - { 'cxe', "lua require('refactoring').refactor('Extract Function')", desc = 'Extract Function' }, - { 'cxf', "lua require('refactoring').refactor('Extract Function To File')", desc = 'Extract Function to File' }, + { + 'cxe', + "lua require('refactoring').refactor('Extract Function')", + desc = 'Extract Function', + }, + { + 'cxf', + "lua require('refactoring').refactor('Extract Function To File')", + desc = 'Extract Function to File', + }, -- Extract variable supports only visual mode - { 'cxv', "lua require('refactoring').refactor('Extract Variable')", desc = 'Extract Variable' }, + { + 'cxv', + "lua require('refactoring').refactor('Extract Variable')", + desc = 'Extract Variable', + }, }, -- Inline func supports only normal - { 'cxi', "lua require('refactoring').refactor('Inline Function')", desc = 'Inline Function' }, + { + 'cxi', + "lua require('refactoring').refactor('Inline Function')", + desc = 'Inline Function', + }, -- Extract block supports only normal mode - { 'cxb', "lua require('refactoring').refactor('Extract Block')", desc = 'Extract Block' }, - { 'cxbf', "lua require('refactoring').refactor('Extract Block To File')", desc = 'Extract Block to File' }, + { + 'cxb', + "lua require('refactoring').refactor('Extract Block')", + desc = 'Extract Block', + }, + { + 'cxbf', + "lua require('refactoring').refactor('Extract Block To File')", + desc = 'Extract Block to File', + }, { mode = { 'n', 'x' }, -- Inline var supports both normal and visual mode - { 'cxi', "lua require('refactoring').refactor('Inline Variable')", desc = 'Inline Variable' }, + { + 'cxi', + "lua require('refactoring').refactor('Inline Variable')", + desc = 'Inline Variable', + }, }, + -- ── Code: LSPSaga ─────────────────────────────────────────────────── -- See: lua/plugins/lsp.lua { '', 'Lspsaga term_toggle', desc = 'LSPSaga: Open Floaterm' }, @@ -79,7 +109,12 @@ return { { 'cci', 'Lspsaga incoming_calls', desc = 'LSPSaga: Incoming Calls' }, { 'cco', 'Lspsaga outgoing_calls', desc = 'LSPSaga: Outgoing Calls' }, { 'cd', 'Lspsaga show_line_diagnostics', desc = 'LSPSaga: Show Line Diagnostics' }, - -- cf = Code Format, see: lua/plugins/autoformat.lua + { + 'cf', + 'lua require("conform").format({ async = true, lsp_fallback = true })', + mode = { 'n', 'v' }, + desc = 'Format buffer', + }, { 'ci', 'Lspsaga implement', desc = 'LSPSaga: Implementations' }, { 'cl', 'Lspsaga show_cursor_diagnostics', desc = 'LSPSaga: Show Cursor Diagnostics' }, { 'cp', 'Lspsaga peek_definition', desc = 'LSPSaga: Peek Definition' }, @@ -98,7 +133,11 @@ return { { 'do', 'lua vim.diagnostic.open_float()', desc = 'Diagnostic: Open float' }, { 'dq', 'lua vim.diagnostic.setloclist()', desc = 'Diagnostic: Set loc list' }, { 'dr', "lua require('dapui').open({reset = true})", desc = 'DAP: Reset' }, - { 'ds', 'lua require("telescope.builtin").lsp_document_symbols()', desc = 'LSP: Document Symbols' }, + { + 'ds', + 'lua require("telescope.builtin").lsp_document_symbols()', + desc = 'LSP: Document Symbols', + }, { 'dt', 'DapUiToggle', desc = 'DAP: Toggle UI' }, -- ── Harpoon ───────────────────────────────────────────────────────── @@ -129,7 +168,11 @@ return { { 'sm', 'Telescope harpoon marks', desc = 'Harpoon Marks' }, { 'sn', "lua require('telescope').extensions.notify.notify()", desc = 'Notify' }, { 'so', "lua require('telescope.builtin').oldfiles()", desc = 'Find recently Opened files' }, - { 'sp', "lua require('telescope').extensions.lazy_plugins.lazy_plugins()", desc = 'Find neovim/lazy configs' }, + { + 'sp', + "lua require('telescope').extensions.lazy_plugins.lazy_plugins()", + desc = 'Find neovim/lazy configs', + }, { 'st', 'TodoTelescope', desc = 'Telescope: Todo' }, { 'sw', "lua require('telescope.builtin').grep_string()", desc = 'Search current Word' }, @@ -144,9 +187,17 @@ return { -- ── Workspace ─────────────────────────────────────────────────────── { 'w', group = '[w] Workspace' }, { 'wa', 'lua vim.lsp.buf.add_workspace_folder()', desc = 'LSP: Workspace Add Folder' }, - { 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', desc = 'LSP: Workspace List Folders' }, + { + 'wl', + 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', + desc = 'LSP: Workspace List Folders', + }, { 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', desc = 'LSP: Workspace Remove Folder' }, - { 'ws', 'lua require("telescope.builtin").lsp_dynamic_workspace_symbols()', desc = 'LSP: Workspace Symbols' }, + { + 'ws', + 'lua require("telescope.builtin").lsp_dynamic_workspace_symbols()', + desc = 'LSP: Workspace Symbols', + }, -- ── Trouble ───────────────────────────────────────────────────────── { 'x', group = '[x] Trouble' }, @@ -156,14 +207,13 @@ return { { 'xl', 'Trouble loclist', desc = 'Toggle Loclist' }, { 'xq', 'Trouble quickfix', desc = 'Toggle Quickfix' }, - -- ── Help & Neoconf ────────────────────────────────────────────────── - { '?', group = '[?] Help & neoconf' }, - { '?c', 'Neoconf', desc = 'Neoconf: Open' }, - { '?g', 'Neoconf global', desc = 'Neoconf: Global' }, - { '?l', 'Neoconf local', desc = 'Neoconf: Local' }, - { '?m', 'Neoconf lsp', desc = 'Neoconf: Show merged LSP config' }, - { '?s', 'Neoconf show', desc = 'Neoconf: Show merged config' }, - { '?w', 'lua require("which-key").show({global = false})', desc = 'Buffer Local Keymaps (which-key)' }, + -- ── Help ──────────────────────────────────────────────────────────── + { '?', group = '[?] Help & Cheat sheets' }, + { + '?w', + 'lua require("which-key").show({global = false})', + desc = 'Buffer Local Keymaps (which-key)', + }, -- ── Misc ──────────────────────────────────────────────────────────── { '1', 'lua require("harpoon"):list():select(1)', desc = 'harpoon to file 1' },