diff --git a/plugin/editor.lua b/plugin/editor.lua index 11068e8..fad36ff 100644 --- a/plugin/editor.lua +++ b/plugin/editor.lua @@ -12,6 +12,7 @@ add({ 'm4xshen/hardtime.nvim', -- workflow 'mg979/vim-visual-multi', -- multiple cursors { src = 'iamcco/markdown-preview.nvim', build = 'cd app && npm install' }, + 'kevinhwang91/nvim-hlslens', -- 'nvim-flutter/flutter-tools.nvim', -- flutter tools }) @@ -59,6 +60,8 @@ require('nvim-treesitter').setup({ }, }) +require('hlslens').setup() + -- windsurf vim.keymap.set('i', '', function() return vim.fn['codeium#Accept']() @@ -66,4 +69,3 @@ end, { expr = true, silent = true }) vim.keymap.set('i', '', function() return vim.fn['codeium#Clear']() end, { expr = true, silent = true }) - diff --git a/plugin/lsp.lua b/plugin/lsp.lua new file mode 100644 index 0000000..e563506 --- /dev/null +++ b/plugin/lsp.lua @@ -0,0 +1,135 @@ +add({ + 'mason-org/mason.nvim', -- lsp installer manager + 'mason-org/mason-lspconfig.nvim', -- lsp installer + 'neovim/nvim-lspconfig', -- lsp config + 'rachartier/tiny-inline-diagnostic.nvim', -- inline diagnostic + 'rachartier/tiny-code-action.nvim', -- code action + 'saghen/blink.lib', + { src = 'saghen/blink.cmp', build = 'cargo build --release' }, + 'rafamadriz/friendly-snippets', +}) + +require('blink.cmp').setup({ + fuzzy = { implementation = 'prefer_rust' }, + snippets = { preset = 'default' }, + sources = { + default = function() + local type = vim.fn.getcmdtype() + if type == '/' or type == '?' then + return { 'buffer' } + end + if type == ':' then + return { 'cmdline' } + end + return { 'lsp', 'path', 'snippets', 'buffer' } + end, + providers = { + snippets = { + opts = { + search_paths = { vim.fn.stdpath('config') .. '/snippets' }, + extended_filetypes = { mdx = { 'markdown' } }, + }, + }, + }, + }, + + completion = { + ghost_text = { enabled = true }, + + list = { + selection = { + preselect = false, + auto_insert = true, + }, + }, + documentation = { + window = { border = 'rounded' }, + auto_show = true, + auto_show_delay_ms = 50, + }, + menu = { + border = 'rounded', + draw = { + components = { + kind_icon = { + text = function(ctx) + local kind_icon, _, _ = require('mini.icons').get('lsp', ctx.kind) + return kind_icon + end, + highlight = function(ctx) + local _, hl, _ = require('mini.icons').get('lsp', ctx.kind) + return hl + end, + }, + kind = { + highlight = function(ctx) + local _, hl, _ = require('mini.icons').get('lsp', ctx.kind) + return hl + end, + }, + }, + }, + }, + }, + signature = { + window = { border = 'rounded' }, + }, + keymap = { + preset = 'none', + [''] = { 'select_prev', 'snippet_backward', 'fallback' }, + [''] = { 'select_next', 'snippet_forward', 'fallback' }, + [''] = { 'accept', 'fallback' }, + [''] = { 'hide', 'show' }, + [''] = { 'show', 'show_documentation', 'hide_documentation' }, + [''] = { 'scroll_documentation_up', 'fallback' }, + [''] = { 'scroll_documentation_down', 'fallback' }, + }, +}) + +-- lsp installer +require('mason').setup({ + ui = { + icons = { + package_installed = '✓', + package_pending = '➜', + package_uninstalled = '✗', + }, + border = 'rounded', + backdrop = 100, + }, +}) + +require('mason-lspconfig').setup({ + ensure_installed = require('extensions').lsp_server, + automatic_installation = false, -- Don't auto-install or auto-configure +}) + +-- improve neovim lsp experience +vim.api.nvim_create_autocmd('LspAttach', { + callback = function() + --inline diagnostic + require('tiny-inline-diagnostic').setup({ + options = { + show_source = true, + multiple_diag_under_cursor = true, + }, + }) + + --code action + require('tiny-code-action').setup({ + picker = { + 'buffer', + opts = { + auto_preview = true, + hotkeys = true, + hotkeys_mode = 'sequential', + }, + }, + }) + end, +}) + +vim.diagnostic.config({ virtual_text = false }) -- Disable default virtual text +vim.keymap.set('n', '.', function() + require('tiny-code-action').code_action() +end, { desc = 'Code action' }) diff --git a/plugin/quality.lua b/plugin/quality.lua new file mode 100644 index 0000000..66ec0df --- /dev/null +++ b/plugin/quality.lua @@ -0,0 +1,75 @@ +add({ + 'mfussenegger/nvim-lint', -- linter + 'rshkarin/mason-nvim-lint', -- linter installer + 'stevearc/conform.nvim', -- autoformater + 'szw/vim-maximizer', + 'zapling/mason-conform.nvim', -- formatter installer +}) + +-- linter +require('lint').linters_by_ft = { + ['*'] = { 'codespell' }, + ['javascript'] = { 'eslint_d', 'cspell' }, + ['typescript'] = { 'eslint_d', 'cspell' }, + ['javascriptreact'] = { 'eslint_d', 'cspell' }, + ['typescriptreact'] = { 'eslint_d', 'cspell' }, + ['dockerfile'] = { 'hadolint' }, + ['markdown'] = { 'write_good', 'markdownlint' }, + ['text'] = { 'write_good' }, + ['sh'] = { 'shellcheck' }, + ['yaml'] = { 'actionlint' }, + ['python'] = { 'ruff' }, +} +require('mason-nvim-lint').setup({ + ensure_installed = require('extensions').linter, + automatic_installation = false, +}) + +-- formatter +require('conform').setup({ + formatters = { + ['markdown-toc'] = { + condition = function(_, ctx) + for _, line in ipairs(vim.api.nvim_buf_get_lines(ctx.buf, 0, -1, false)) do + if line:find('') then + return true + end + end + end, + }, + }, + formatters_by_ft = { + ['lua'] = { 'stylua' }, + ['c'] = { 'clang_format' }, + ['cpp'] = { 'clang_format' }, + ['h'] = { 'clang_format' }, + ['python'] = { 'ruff_fix', 'ruff_format', 'ruff_organize_imports' }, + ['javascript'] = { 'biome' }, + ['typescript'] = { 'biome' }, + ['typescriptreact'] = { 'biome' }, + ['markdown'] = { 'prettier', 'markdownlint-cli2' }, + ['markdown.mdx'] = { 'prettier', 'markdownlint-cli2' }, + ['mdx'] = { 'prettier' }, + ['_'] = { 'trim_whitespace' }, + }, + options = { + stop_after_first = true, + }, + format_after_save = function(bufnr) + if not vim.b[bufnr].conform_disable then + return { + lsp_format = 'fallback', + } + end + end, +}) + +vim.keymap.set('n', 'tf', function() + vim.b.conform_disable = not vim.b.conform_disable + local status = vim.b.conform_disable and 'disabled' or 'enabled' + vim.notify('Autoformat ' .. status, vim.log.levels.INFO) +end, { desc = 'Toggle autoformat' }) +require('mason-conform').setup({ + ensure_installed = require('extensions').formatter, + automatic_installation = true, +})