diff --git a/init.lua b/init.lua index a36326a3..4592a62e 100644 --- a/init.lua +++ b/init.lua @@ -2,7 +2,6 @@ vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' require('settings') -require('plugins') -- Ensure this file uses lazy.nvim for loading plugins require('keymaps') local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' @@ -16,9 +15,538 @@ end vim.opt.rtp:prepend(lazypath) require('lazy').setup({ - root = vim.fn.stdpath('data') .. '/lazy', - defaults = { - lazy = true, + { + 'tpope/vim-sleuth', -- Automatically set the 'shiftwidth' and 'expandtab' options based on the current file + }, + { + 'lewis6991/gitsigns.nvim', -- Git signs in the sign column + opts = { + signs = { + add = { text = '+' }, + change = { text = '' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '' }, + }, + }, + }, + { + 'folke/which-key.nvim', + event = 'VimEnter', + opts = { + delay = 0, + icons = { + mappings = vim.g.have_nerd_font, + keys = vim.g.have_nerd_font and {} or { + Up = ' ', + Down = ' ', + Left = ' ', + Right = ' ', + C = ' ', + M = ' ', + D = ' ', + S = ' ', + CR = ' ', + Esc = ' ', + ScrollWheelDown = ' ', + ScrollWheelUp = ' ', + NL = ' ', + BS = ' ', + Space = ' ', + Tab = ' ', + F1 = '', + F2 = '', + F3 = '', + F4 = '', + F5 = '', + F6 = '', + F7 = '', + F8 = '', + F9 = '', + F10 = '', + F11 = '', + F12 = '', + }, + }, + spec = { + { 'c', group = '[C]ode', mode = { 'n', 'x' } }, + { 'd', group = '[D]ocument' }, + { 'r', group = '[R]ename' }, + { 's', group = '[S]earch' }, + { 'w', group = '[W]orkspace' }, + { 't', group = '[T]oggle' }, + { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, + }, + }, + }, + { + 'nvim-tree/nvim-tree.lua', + event = 'VimEnter', + config = function() + require('nvim-tree').setup { + renderer = { + icons = { + glyphs = { + default = '', + symlink = '', + folder = { + arrow_open = '', + arrow_closed = '', + default = '', + open = '', + empty = '', + empty_open = '', + symlink = '', + }, + git = { + unstaged = '✗', + staged = '✓', + unmerged = '', + renamed = '➜', + untracked = '★', + deleted = '', + ignored = '◌', + }, + }, + }, + }, + } + vim.keymap.set('n', 'e', 'NvimTreeToggle', { desc = 'Toggle File Explorer' }) + end, + }, + { + 'wakatime/vim-wakatime', + }, + { + 'github/copilot.vim', + }, + { + 'jose-elias-alvarez/null-ls.nvim', + dependencies = { 'nvim-lua/plenary.nvim' }, + config = function() + local null_ls = require 'null-ls' + null_ls.setup { + sources = { + null_ls.builtins.formatting.prettier, + null_ls.builtins.diagnostics.eslint, + null_ls.builtins.code_actions.eslint, + }, + } + end, + }, + { + 'nvim-lualine/lualine.nvim', + dependencies = { 'nvim-tree/nvim-web-devicons' }, + config = function() + require('lualine').setup { + options = { + theme = 'auto', + section_separators = '', + component_separators = '', + }, + sections = { + lualine_a = { 'mode' }, + lualine_b = { 'branch', 'diff', 'diagnostics' }, + lualine_c = { 'filename' }, + lualine_x = { 'encoding', 'fileformat', 'filetype' }, + lualine_y = { 'progress' }, + lualine_z = { 'location' }, + }, + } + end, + }, + { + 'lewis6991/gitsigns.nvim', + config = function() + require('gitsigns').setup { + current_line_blame = true, + } + end, + }, + { + 'mfussenegger/nvim-dap', + config = function() + local dap = require 'dap' + dap.adapters.node2 = { + type = 'executable', + command = 'node', + args = { os.getenv 'HOME' .. '/.local/share/nvim/mason/packages/node-debug2-adapter/out/src/nodeDebug.js' }, + } + + dap.configurations.javascript = { + { + name = 'Launch Node.js', + type = 'node2', + request = 'launch', + program = '${file}', + cwd = vim.fn.getcwd(), + sourceMaps = true, + protocol = 'inspector', + console = 'integratedTerminal', + }, + } + end, + }, + + { + 'numToStr/Comment.nvim', + config = function() + require('Comment').setup() + end, + }, + + { + 'windwp/nvim-autopairs', + event = 'InsertEnter', + config = function() + require('nvim-autopairs').setup {} + end, + }, + + { + 'nvim-pack/nvim-spectre', + dependencies = { 'nvim-lua/plenary.nvim' }, + config = function() + require('spectre').setup() + end, + }, + { + 'nvim-telescope/telescope.nvim', + event = 'VimEnter', + branch = '0.1.x', + dependencies = { + 'nvim-lua/plenary.nvim', + { -- If encountering errors, see telescope-fzf-native README for installation instructions + 'nvim-telescope/telescope-fzf-native.nvim', + build = 'make', + cond = function() + return vim.fn.executable 'make' == 1 + end, + }, + { 'nvim-telescope/telescope-ui-select.nvim' }, + { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, + }, + config = function() + require('telescope').setup { + extensions = { + ['ui-select'] = { + require('telescope.themes').get_dropdown(), + }, + }, + } + pcall(require('telescope').load_extension, 'fzf') + pcall(require('telescope').load_extension, 'ui-select') + + local builtin = require 'telescope.builtin' + vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) + vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) + vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) + vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) + vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) + vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) + vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) + vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) + vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) + vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) + + vim.keymap.set('n', '/', function() + builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { + winblend = 10, + previewer = false, + }) + end, { desc = '[/] Fuzzily search in current buffer' }) + + vim.keymap.set('n', 's/', function() + builtin.live_grep { + grep_open_files = true, + prompt_title = 'Live Grep in Open Files', + } + end, { desc = '[S]earch [/] in Open Files' }) + + vim.keymap.set('n', 'sn', function() + builtin.find_files { cwd = vim.fn.stdpath 'config' } + end, { desc = '[S]earch [N]eovim files' }) + end, + }, + + { + 'folke/lazydev.nvim', + ft = 'lua', + opts = { + library = { + { path = '${3rd}/luv/library', words = { 'vim%.uv' } }, + }, + }, + }, + { + 'neovim/nvim-lspconfig', + dependencies = { + { 'williamboman/mason.nvim', opts = {} }, + 'williamboman/mason-lspconfig.nvim', + 'WhoIsSethDaniel/mason-tool-installer.nvim', + { 'j-hui/fidget.nvim', opts = {} }, + 'hrsh7th/cmp-nvim-lsp', + }, + config = function() + require('mason').setup() + require('mason-lspconfig').setup { + ensure_installed = { 'ts_ls', 'tailwindcss', 'cssls', 'lua_ls' }, + automatic_installation = true, + } + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) + + if vim.g.have_nerd_font then + local signs = { ERROR = '', WARN = '', INFO = '', HINT = '' } + for type, icon in pairs(signs) do + local hl = 'DiagnosticSign' .. type + vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = '' }) + end + end + + local servers = { + ts_ls = { + on_attach = function(client, bufnr) + client.server_capabilities.documentFormattingProvider = false + + local map = function(keys, func, desc) + vim.keymap.set('n', keys, func, { buffer = bufnr, desc = 'LSP: ' .. desc }) + end + + vim.api.nvim_create_autocmd('BufWritePre', { + buffer = bufnr, + callback = function() + vim.lsp.buf.code_action { + context = { only = { 'source.fixAll' }, diagnostics = {} }, + apply = true, + } + end, + }) + + map('oi', function() + vim.lsp.buf.code_action { + context = { only = { 'source.organizeImports' }, diagnostics = {} }, + apply = true, + } + end, '[O]rganize [I]mports') + end, + capabilities = capabilities, + settings = { + typescript = { + inlayHints = { includeInlayParameterNameHints = 'all' }, + preferences = { importModuleSpecifierPreference = 'non-relative', quotePreference = 'single' }, + }, + javascript = { + preferences = { importModuleSpecifierPreference = 'non-relative', quotePreference = 'single' }, + }, + }, + }, + tailwindcss = { + filetypes = { 'html', 'css', 'scss', 'javascript', 'typescript', 'javascriptreact', 'typescriptreact' }, + }, + cssls = {}, + lua_ls = { + settings = { + Lua = { + completion = { callSnippet = 'Replace' }, + }, + }, + }, + } + + local ensure_installed = vim.tbl_keys(servers) + require('mason-tool-installer').setup { ensure_installed = ensure_installed } + + require('mason-lspconfig').setup { + ensure_installed = ensure_installed, + automatic_installation = true, + handlers = { + function(server_name) + local server = servers[server_name] or {} + server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) + require('lspconfig')[server_name].setup(server) + end, + }, + } + end, + }, + { + 'stevearc/conform.nvim', + event = { 'BufWritePre' }, + cmd = { 'ConformInfo' }, + keys = { + { + 'f', + function() + require('conform').format { async = true, lsp_format = 'fallback' } + end, + mode = '', + desc = '[F]ormat buffer', + }, + }, + opts = { + notify_on_error = false, + format_on_save = function(bufnr) + local disable_filetypes = { c = true, cpp = true } + return { + timeout_ms = 500, + lsp_format = disable_filetypes[vim.bo[bufnr].filetype] and 'never' or 'fallback', + } + end, + formatters_by_ft = { + lua = { 'stylua' }, + javascript = { 'prettier' }, + typescript = { 'prettier' }, + css = { 'prettier' }, + scss = { 'prettier' }, + html = { 'prettier' }, + }, + }, + }, + { + 'hrsh7th/nvim-cmp', + event = 'InsertEnter', + dependencies = { + { + 'L3MON4D3/LuaSnip', + build = (function() + if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then + return + end + return 'make install_jsregexp' + end)(), + }, + 'saadparwaiz1/cmp_luasnip', + 'hrsh7th/cmp-nvim-lsp', + 'hrsh7th/cmp-path', + 'hrsh7th/cmp-buffer', + 'hrsh7th/cmp-cmdline', + }, + config = function() + local cmp = require 'cmp' + local luasnip = require 'luasnip' + luasnip.config.setup {} + cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + completion = { completeopt = 'menu,menuone,noinsert' }, + + mapping = cmp.mapping.preset.insert { + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.confirm { select = true }, + [''] = cmp.mapping.complete {}, + [''] = cmp.mapping(function() + if luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function() + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + end + end, { 'i', 's' }), + }, + + sources = cmp.config.sources { + { name = 'lazydev', group_index = 0 }, + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + { name = 'path' }, + { name = 'buffer' }, + }, + } + end, + }, + { -- 🎨 Colorscheme + 'folke/tokyonight.nvim', + priority = 1000, + init = function() + -- Load colorscheme with specific style + vim.cmd.colorscheme 'tokyonight-night' + -- Customize Comment color (removes italic) + vim.cmd.hi 'Comment gui=none' + end, + }, + -- ✅ Highlight TODOs, FIXMEs, and other comments + { + 'folke/todo-comments.nvim', + event = 'VimEnter', + dependencies = { 'nvim-lua/plenary.nvim' }, + opts = { signs = false }, + }, + { -- 🛠️ mini.nvim utility plugins (better text objects, surround, and statusline) + 'echasnovski/mini.nvim', + config = function() + -- Setup mini.ai for better text objects + require('mini.ai').setup { + n_lines = 500, + } + -- Setup mini.surround for surrounding text objects + require('mini.surround').setup() + + -- Setup mini.statusline for a better status line + require('mini.statusline').setup { + use_icons = vim.g.have_nerd_font, + content = { + active = function() + return '%2l:%-2v' -- line:column display + end, + }, + } + end, + }, + { + 'nvim-treesitter/nvim-treesitter', + build = ':tsupdate', + main = 'nvim-treesitter.configs', + opts = { + ensure_installed = { + 'bash', + 'c', + 'diff', + 'html', + 'css', + 'javascript', + 'typescript', + 'tsx', + 'json', + 'lua', + 'luadoc', + 'markdown', + 'markdown_inline', + 'query', + 'vim', + 'vimdoc', + }, + auto_install = true, + highlight = { + enable = true, + additional_vim_regex_highlighting = { 'ruby' }, + }, + indent = { enable = true, disable = { 'ruby' } }, + }, + }, + ui = { + icons = vim.g.have_nerd_font and {} or { + cmd = '⌘', + config = '🛠', + event = '📅', + ft = '📂', + init = '⚙', + keys = '🗝', + plugin = '🔌', + runtime = '💻', + require = '🌙', + source = '📄', + start = '🚀', + task = '📌', + lazy = '💤 ', + }, }, - spec = require('plugins').spec, -- Load plugin specifications from plugins.lua }) diff --git a/lua/plugins.lua b/lua/plugins.lua index 4e045465..50530e0a 100644 --- a/lua/plugins.lua +++ b/lua/plugins.lua @@ -1,540 +1,540 @@ -local M = {} - -M.spec = { - { - 'tpope/vim-sleuth', -- Automatically set the 'shiftwidth' and 'expandtab' options based on the current file - }, - { - 'lewis6991/gitsigns.nvim', -- Git signs in the sign column - opts = { - signs = { - add = { text = '+' }, - change = { text = '' }, - delete = { text = '_' }, - topdelete = { text = '‾' }, - changedelete = { text = '' }, - }, - }, - }, - { - 'folke/which-key.nvim', - event = 'VimEnter', - opts = { - delay = 0, - icons = { - mappings = vim.g.have_nerd_font, - keys = vim.g.have_nerd_font and {} or { - Up = ' ', - Down = ' ', - Left = ' ', - Right = ' ', - C = ' ', - M = ' ', - D = ' ', - S = ' ', - CR = ' ', - Esc = ' ', - ScrollWheelDown = ' ', - ScrollWheelUp = ' ', - NL = ' ', - BS = ' ', - Space = ' ', - Tab = ' ', - F1 = '', - F2 = '', - F3 = '', - F4 = '', - F5 = '', - F6 = '', - F7 = '', - F8 = '', - F9 = '', - F10 = '', - F11 = '', - F12 = '', - }, - }, - spec = { - { 'c', group = '[C]ode', mode = { 'n', 'x' } }, - { 'd', group = '[D]ocument' }, - { 'r', group = '[R]ename' }, - { 's', group = '[S]earch' }, - { 'w', group = '[W]orkspace' }, - { 't', group = '[T]oggle' }, - { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, - }, - }, - }, - { - 'nvim-tree/nvim-tree.lua', - event = 'VimEnter', - config = function() - require('nvim-tree').setup { - renderer = { - icons = { - glyphs = { - default = '', - symlink = '', - folder = { - arrow_open = '', - arrow_closed = '', - default = '', - open = '', - empty = '', - empty_open = '', - symlink = '', - }, - git = { - unstaged = '✗', - staged = '✓', - unmerged = '', - renamed = '➜', - untracked = '★', - deleted = '', - ignored = '◌', - }, - }, - }, - }, - } - vim.keymap.set('n', 'e', 'NvimTreeToggle', { desc = 'Toggle File Explorer' }) - end, - }, - { - 'wakatime/vim-wakatime', - }, - { - 'github/copilot.vim', - }, - { - 'jose-elias-alvarez/null-ls.nvim', - dependencies = { 'nvim-lua/plenary.nvim' }, - config = function() - local null_ls = require 'null-ls' - null_ls.setup { - sources = { - null_ls.builtins.formatting.prettier, - null_ls.builtins.diagnostics.eslint, - null_ls.builtins.code_actions.eslint, - }, - } - end, - }, - { - 'nvim-lualine/lualine.nvim', - dependencies = { 'nvim-tree/nvim-web-devicons' }, - config = function() - require('lualine').setup { - options = { - theme = 'auto', - section_separators = '', - component_separators = '', - }, - sections = { - lualine_a = { 'mode' }, - lualine_b = { 'branch', 'diff', 'diagnostics' }, - lualine_c = { 'filename' }, - lualine_x = { 'encoding', 'fileformat', 'filetype' }, - lualine_y = { 'progress' }, - lualine_z = { 'location' }, - }, - } - end, - }, - { - 'lewis6991/gitsigns.nvim', - config = function() - require('gitsigns').setup { - current_line_blame = true, - } - end, - }, - { - 'mfussenegger/nvim-dap', - config = function() - local dap = require 'dap' - dap.adapters.node2 = { - type = 'executable', - command = 'node', - args = { os.getenv 'HOME' .. '/.local/share/nvim/mason/packages/node-debug2-adapter/out/src/nodeDebug.js' }, - } - - dap.configurations.javascript = { - { - name = 'Launch Node.js', - type = 'node2', - request = 'launch', - program = '${file}', - cwd = vim.fn.getcwd(), - sourceMaps = true, - protocol = 'inspector', - console = 'integratedTerminal', - }, - } - end, - }, - - { - 'numToStr/Comment.nvim', - config = function() - require('Comment').setup() - end, - }, - - { - 'windwp/nvim-autopairs', - event = 'InsertEnter', - config = function() - require('nvim-autopairs').setup {} - end, - }, - - { - 'nvim-pack/nvim-spectre', - dependencies = { 'nvim-lua/plenary.nvim' }, - config = function() - require('spectre').setup() - end, - }, - { - 'nvim-telescope/telescope.nvim', - event = 'VimEnter', - branch = '0.1.x', - dependencies = { - 'nvim-lua/plenary.nvim', - { -- If encountering errors, see telescope-fzf-native README for installation instructions - 'nvim-telescope/telescope-fzf-native.nvim', - build = 'make', - cond = function() - return vim.fn.executable 'make' == 1 - end, - }, - { 'nvim-telescope/telescope-ui-select.nvim' }, - { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, - }, - config = function() - require('telescope').setup { - extensions = { - ['ui-select'] = { - require('telescope.themes').get_dropdown(), - }, - }, - } - pcall(require('telescope').load_extension, 'fzf') - pcall(require('telescope').load_extension, 'ui-select') - - local builtin = require 'telescope.builtin' - vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) - vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) - vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) - vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) - vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) - vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) - vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) - vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) - vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) - vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) - - vim.keymap.set('n', '/', function() - builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { - winblend = 10, - previewer = false, - }) - end, { desc = '[/] Fuzzily search in current buffer' }) - - vim.keymap.set('n', 's/', function() - builtin.live_grep { - grep_open_files = true, - prompt_title = 'Live Grep in Open Files', - } - end, { desc = '[S]earch [/] in Open Files' }) - - vim.keymap.set('n', 'sn', function() - builtin.find_files { cwd = vim.fn.stdpath 'config' } - end, { desc = '[S]earch [N]eovim files' }) - end, - }, - - { - 'folke/lazydev.nvim', - ft = 'lua', - opts = { - library = { - { path = '${3rd}/luv/library', words = { 'vim%.uv' } }, - }, - }, - }, - { - 'neovim/nvim-lspconfig', - dependencies = { - { 'williamboman/mason.nvim', opts = {} }, - 'williamboman/mason-lspconfig.nvim', - 'WhoIsSethDaniel/mason-tool-installer.nvim', - { 'j-hui/fidget.nvim', opts = {} }, - 'hrsh7th/cmp-nvim-lsp', - }, - config = function() - require('mason').setup() - require('mason-lspconfig').setup { - ensure_installed = { 'ts_ls', 'tailwindcss', 'cssls', 'lua_ls' }, - automatic_installation = true, - } - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) - - if vim.g.have_nerd_font then - local signs = { ERROR = '', WARN = '', INFO = '', HINT = '' } - for type, icon in pairs(signs) do - local hl = 'DiagnosticSign' .. type - vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = '' }) - end - end - - local servers = { - ts_ls = { - on_attach = function(client, bufnr) - client.server_capabilities.documentFormattingProvider = false - - local map = function(keys, func, desc) - vim.keymap.set('n', keys, func, { buffer = bufnr, desc = 'LSP: ' .. desc }) - end - - vim.api.nvim_create_autocmd('BufWritePre', { - buffer = bufnr, - callback = function() - vim.lsp.buf.code_action { - context = { only = { 'source.fixAll' }, diagnostics = {} }, - apply = true, - } - end, - }) - - map('oi', function() - vim.lsp.buf.code_action { - context = { only = { 'source.organizeImports' }, diagnostics = {} }, - apply = true, - } - end, '[O]rganize [I]mports') - end, - capabilities = capabilities, - settings = { - typescript = { - inlayHints = { includeInlayParameterNameHints = 'all' }, - preferences = { importModuleSpecifierPreference = 'non-relative', quotePreference = 'single' }, - }, - javascript = { - preferences = { importModuleSpecifierPreference = 'non-relative', quotePreference = 'single' }, - }, - }, - }, - tailwindcss = { - filetypes = { 'html', 'css', 'scss', 'javascript', 'typescript', 'javascriptreact', 'typescriptreact' }, - }, - cssls = {}, - lua_ls = { - settings = { - Lua = { - completion = { callSnippet = 'Replace' }, - }, - }, - }, - } - - local ensure_installed = vim.tbl_keys(servers) - require('mason-tool-installer').setup { ensure_installed = ensure_installed } - - require('mason-lspconfig').setup { - ensure_installed = ensure_installed, - automatic_installation = true, - handlers = { - function(server_name) - local server = servers[server_name] or {} - server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) - require('lspconfig')[server_name].setup(server) - end, - }, - } - end, - }, - { - 'stevearc/conform.nvim', - event = { 'BufWritePre' }, - cmd = { 'ConformInfo' }, - keys = { - { - 'f', - function() - require('conform').format { async = true, lsp_format = 'fallback' } - end, - mode = '', - desc = '[F]ormat buffer', - }, - }, - opts = { - notify_on_error = false, - format_on_save = function(bufnr) - local disable_filetypes = { c = true, cpp = true } - return { - timeout_ms = 500, - lsp_format = disable_filetypes[vim.bo[bufnr].filetype] and 'never' or 'fallback', - } - end, - formatters_by_ft = { - lua = { 'stylua' }, - javascript = { 'prettier' }, - typescript = { 'prettier' }, - css = { 'prettier' }, - scss = { 'prettier' }, - html = { 'prettier' }, - }, - }, - }, - { - 'hrsh7th/nvim-cmp', - event = 'InsertEnter', - dependencies = { - { - 'L3MON4D3/LuaSnip', - build = (function() - if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then - return - end - return 'make install_jsregexp' - end)(), - }, - 'saadparwaiz1/cmp_luasnip', - 'hrsh7th/cmp-nvim-lsp', - 'hrsh7th/cmp-path', - 'hrsh7th/cmp-buffer', - 'hrsh7th/cmp-cmdline', - }, - config = function() - local cmp = require 'cmp' - local luasnip = require 'luasnip' - luasnip.config.setup {} - cmp.setup { - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - completion = { completeopt = 'menu,menuone,noinsert' }, - - mapping = cmp.mapping.preset.insert { - [''] = cmp.mapping.select_next_item(), - [''] = cmp.mapping.select_prev_item(), - [''] = cmp.mapping.scroll_docs(-4), - [''] = cmp.mapping.scroll_docs(4), - [''] = cmp.mapping.confirm { select = true }, - [''] = cmp.mapping.complete {}, - [''] = cmp.mapping(function() - if luasnip.expand_or_locally_jumpable() then - luasnip.expand_or_jump() - end - end, { 'i', 's' }), - [''] = cmp.mapping(function() - if luasnip.locally_jumpable(-1) then - luasnip.jump(-1) - end - end, { 'i', 's' }), - }, - - sources = cmp.config.sources { - { name = 'lazydev', group_index = 0 }, - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - { name = 'path' }, - { name = 'buffer' }, - }, - } - end, - }, - { -- 🎨 Colorscheme - 'folke/tokyonight.nvim', - priority = 1000, - init = function() - -- Load colorscheme with specific style - vim.cmd.colorscheme 'tokyonight-night' - -- Customize Comment color (removes italic) - vim.cmd.hi 'Comment gui=none' - end, - }, - -- ✅ Highlight TODOs, FIXMEs, and other comments - { - 'folke/todo-comments.nvim', - event = 'VimEnter', - dependencies = { 'nvim-lua/plenary.nvim' }, - opts = { signs = false }, - }, - { -- 🛠️ mini.nvim utility plugins (better text objects, surround, and statusline) - 'echasnovski/mini.nvim', - config = function() - -- Setup mini.ai for better text objects - require('mini.ai').setup { - n_lines = 500, - } - -- Setup mini.surround for surrounding text objects - require('mini.surround').setup() - - -- Setup mini.statusline for a better status line - require('mini.statusline').setup { - use_icons = vim.g.have_nerd_font, - content = { - active = function() - return '%2l:%-2v' -- line:column display - end, - }, - } - end, - }, - { - 'nvim-treesitter/nvim-treesitter', - build = ':tsupdate', - main = 'nvim-treesitter.configs', - opts = { - ensure_installed = { - 'bash', - 'c', - 'diff', - 'html', - 'css', - 'javascript', - 'typescript', - 'tsx', - 'json', - 'lua', - 'luadoc', - 'markdown', - 'markdown_inline', - 'query', - 'vim', - 'vimdoc', - }, - auto_install = true, - highlight = { - enable = true, - additional_vim_regex_highlighting = { 'ruby' }, - }, - indent = { enable = true, disable = { 'ruby' } }, - }, - }, - ui = { - icons = vim.g.have_nerd_font and {} or { - cmd = '⌘', - config = '🛠', - event = '📅', - ft = '📂', - init = '⚙', - keys = '🗝', - plugin = '🔌', - runtime = '💻', - require = '🌙', - source = '📄', - start = '🚀', - task = '📌', - lazy = '💤 ', - }, - }, -} - -return M +-- local M = {} +-- +-- M.spec = { +-- { +-- 'tpope/vim-sleuth', -- Automatically set the 'shiftwidth' and 'expandtab' options based on the current file +-- }, +-- { +-- 'lewis6991/gitsigns.nvim', -- Git signs in the sign column +-- opts = { +-- signs = { +-- add = { text = '+' }, +-- change = { text = '' }, +-- delete = { text = '_' }, +-- topdelete = { text = '‾' }, +-- changedelete = { text = '' }, +-- }, +-- }, +-- }, +-- { +-- 'folke/which-key.nvim', +-- event = 'VimEnter', +-- opts = { +-- delay = 0, +-- icons = { +-- mappings = vim.g.have_nerd_font, +-- keys = vim.g.have_nerd_font and {} or { +-- Up = ' ', +-- Down = ' ', +-- Left = ' ', +-- Right = ' ', +-- C = ' ', +-- M = ' ', +-- D = ' ', +-- S = ' ', +-- CR = ' ', +-- Esc = ' ', +-- ScrollWheelDown = ' ', +-- ScrollWheelUp = ' ', +-- NL = ' ', +-- BS = ' ', +-- Space = ' ', +-- Tab = ' ', +-- F1 = '', +-- F2 = '', +-- F3 = '', +-- F4 = '', +-- F5 = '', +-- F6 = '', +-- F7 = '', +-- F8 = '', +-- F9 = '', +-- F10 = '', +-- F11 = '', +-- F12 = '', +-- }, +-- }, +-- spec = { +-- { 'c', group = '[C]ode', mode = { 'n', 'x' } }, +-- { 'd', group = '[D]ocument' }, +-- { 'r', group = '[R]ename' }, +-- { 's', group = '[S]earch' }, +-- { 'w', group = '[W]orkspace' }, +-- { 't', group = '[T]oggle' }, +-- { 'h', group = 'Git [H]unk', mode = { 'n', 'v' } }, +-- }, +-- }, +-- }, +-- { +-- 'nvim-tree/nvim-tree.lua', +-- event = 'VimEnter', +-- config = function() +-- require('nvim-tree').setup { +-- renderer = { +-- icons = { +-- glyphs = { +-- default = '', +-- symlink = '', +-- folder = { +-- arrow_open = '', +-- arrow_closed = '', +-- default = '', +-- open = '', +-- empty = '', +-- empty_open = '', +-- symlink = '', +-- }, +-- git = { +-- unstaged = '✗', +-- staged = '✓', +-- unmerged = '', +-- renamed = '➜', +-- untracked = '★', +-- deleted = '', +-- ignored = '◌', +-- }, +-- }, +-- }, +-- }, +-- } +-- vim.keymap.set('n', 'e', 'NvimTreeToggle', { desc = 'Toggle File Explorer' }) +-- end, +-- }, +-- { +-- 'wakatime/vim-wakatime', +-- }, +-- { +-- 'github/copilot.vim', +-- }, +-- { +-- 'jose-elias-alvarez/null-ls.nvim', +-- dependencies = { 'nvim-lua/plenary.nvim' }, +-- config = function() +-- local null_ls = require 'null-ls' +-- null_ls.setup { +-- sources = { +-- null_ls.builtins.formatting.prettier, +-- null_ls.builtins.diagnostics.eslint, +-- null_ls.builtins.code_actions.eslint, +-- }, +-- } +-- end, +-- }, +-- { +-- 'nvim-lualine/lualine.nvim', +-- dependencies = { 'nvim-tree/nvim-web-devicons' }, +-- config = function() +-- require('lualine').setup { +-- options = { +-- theme = 'auto', +-- section_separators = '', +-- component_separators = '', +-- }, +-- sections = { +-- lualine_a = { 'mode' }, +-- lualine_b = { 'branch', 'diff', 'diagnostics' }, +-- lualine_c = { 'filename' }, +-- lualine_x = { 'encoding', 'fileformat', 'filetype' }, +-- lualine_y = { 'progress' }, +-- lualine_z = { 'location' }, +-- }, +-- } +-- end, +-- }, +-- { +-- 'lewis6991/gitsigns.nvim', +-- config = function() +-- require('gitsigns').setup { +-- current_line_blame = true, +-- } +-- end, +-- }, +-- { +-- 'mfussenegger/nvim-dap', +-- config = function() +-- local dap = require 'dap' +-- dap.adapters.node2 = { +-- type = 'executable', +-- command = 'node', +-- args = { os.getenv 'HOME' .. '/.local/share/nvim/mason/packages/node-debug2-adapter/out/src/nodeDebug.js' }, +-- } +-- +-- dap.configurations.javascript = { +-- { +-- name = 'Launch Node.js', +-- type = 'node2', +-- request = 'launch', +-- program = '${file}', +-- cwd = vim.fn.getcwd(), +-- sourceMaps = true, +-- protocol = 'inspector', +-- console = 'integratedTerminal', +-- }, +-- } +-- end, +-- }, +-- +-- { +-- 'numToStr/Comment.nvim', +-- config = function() +-- require('Comment').setup() +-- end, +-- }, +-- +-- { +-- 'windwp/nvim-autopairs', +-- event = 'InsertEnter', +-- config = function() +-- require('nvim-autopairs').setup {} +-- end, +-- }, +-- +-- { +-- 'nvim-pack/nvim-spectre', +-- dependencies = { 'nvim-lua/plenary.nvim' }, +-- config = function() +-- require('spectre').setup() +-- end, +-- }, +-- { +-- 'nvim-telescope/telescope.nvim', +-- event = 'VimEnter', +-- branch = '0.1.x', +-- dependencies = { +-- 'nvim-lua/plenary.nvim', +-- { -- If encountering errors, see telescope-fzf-native README for installation instructions +-- 'nvim-telescope/telescope-fzf-native.nvim', +-- build = 'make', +-- cond = function() +-- return vim.fn.executable 'make' == 1 +-- end, +-- }, +-- { 'nvim-telescope/telescope-ui-select.nvim' }, +-- { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, +-- }, +-- config = function() +-- require('telescope').setup { +-- extensions = { +-- ['ui-select'] = { +-- require('telescope.themes').get_dropdown(), +-- }, +-- }, +-- } +-- pcall(require('telescope').load_extension, 'fzf') +-- pcall(require('telescope').load_extension, 'ui-select') +-- +-- local builtin = require 'telescope.builtin' +-- vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) +-- vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) +-- vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) +-- vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) +-- vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) +-- vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) +-- vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) +-- vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) +-- vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) +-- vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) +-- +-- vim.keymap.set('n', '/', function() +-- builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { +-- winblend = 10, +-- previewer = false, +-- }) +-- end, { desc = '[/] Fuzzily search in current buffer' }) +-- +-- vim.keymap.set('n', 's/', function() +-- builtin.live_grep { +-- grep_open_files = true, +-- prompt_title = 'Live Grep in Open Files', +-- } +-- end, { desc = '[S]earch [/] in Open Files' }) +-- +-- vim.keymap.set('n', 'sn', function() +-- builtin.find_files { cwd = vim.fn.stdpath 'config' } +-- end, { desc = '[S]earch [N]eovim files' }) +-- end, +-- }, +-- +-- { +-- 'folke/lazydev.nvim', +-- ft = 'lua', +-- opts = { +-- library = { +-- { path = '${3rd}/luv/library', words = { 'vim%.uv' } }, +-- }, +-- }, +-- }, +-- { +-- 'neovim/nvim-lspconfig', +-- dependencies = { +-- { 'williamboman/mason.nvim', opts = {} }, +-- 'williamboman/mason-lspconfig.nvim', +-- 'WhoIsSethDaniel/mason-tool-installer.nvim', +-- { 'j-hui/fidget.nvim', opts = {} }, +-- 'hrsh7th/cmp-nvim-lsp', +-- }, +-- config = function() +-- require('mason').setup() +-- require('mason-lspconfig').setup { +-- ensure_installed = { 'ts_ls', 'tailwindcss', 'cssls', 'lua_ls' }, +-- automatic_installation = true, +-- } +-- local capabilities = vim.lsp.protocol.make_client_capabilities() +-- capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) +-- +-- if vim.g.have_nerd_font then +-- local signs = { ERROR = '', WARN = '', INFO = '', HINT = '' } +-- for type, icon in pairs(signs) do +-- local hl = 'DiagnosticSign' .. type +-- vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = '' }) +-- end +-- end +-- +-- local servers = { +-- ts_ls = { +-- on_attach = function(client, bufnr) +-- client.server_capabilities.documentFormattingProvider = false +-- +-- local map = function(keys, func, desc) +-- vim.keymap.set('n', keys, func, { buffer = bufnr, desc = 'LSP: ' .. desc }) +-- end +-- +-- vim.api.nvim_create_autocmd('BufWritePre', { +-- buffer = bufnr, +-- callback = function() +-- vim.lsp.buf.code_action { +-- context = { only = { 'source.fixAll' }, diagnostics = {} }, +-- apply = true, +-- } +-- end, +-- }) +-- +-- map('oi', function() +-- vim.lsp.buf.code_action { +-- context = { only = { 'source.organizeImports' }, diagnostics = {} }, +-- apply = true, +-- } +-- end, '[O]rganize [I]mports') +-- end, +-- capabilities = capabilities, +-- settings = { +-- typescript = { +-- inlayHints = { includeInlayParameterNameHints = 'all' }, +-- preferences = { importModuleSpecifierPreference = 'non-relative', quotePreference = 'single' }, +-- }, +-- javascript = { +-- preferences = { importModuleSpecifierPreference = 'non-relative', quotePreference = 'single' }, +-- }, +-- }, +-- }, +-- tailwindcss = { +-- filetypes = { 'html', 'css', 'scss', 'javascript', 'typescript', 'javascriptreact', 'typescriptreact' }, +-- }, +-- cssls = {}, +-- lua_ls = { +-- settings = { +-- Lua = { +-- completion = { callSnippet = 'Replace' }, +-- }, +-- }, +-- }, +-- } +-- +-- local ensure_installed = vim.tbl_keys(servers) +-- require('mason-tool-installer').setup { ensure_installed = ensure_installed } +-- +-- require('mason-lspconfig').setup { +-- ensure_installed = ensure_installed, +-- automatic_installation = true, +-- handlers = { +-- function(server_name) +-- local server = servers[server_name] or {} +-- server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) +-- require('lspconfig')[server_name].setup(server) +-- end, +-- }, +-- } +-- end, +-- }, +-- { +-- 'stevearc/conform.nvim', +-- event = { 'BufWritePre' }, +-- cmd = { 'ConformInfo' }, +-- keys = { +-- { +-- 'f', +-- function() +-- require('conform').format { async = true, lsp_format = 'fallback' } +-- end, +-- mode = '', +-- desc = '[F]ormat buffer', +-- }, +-- }, +-- opts = { +-- notify_on_error = false, +-- format_on_save = function(bufnr) +-- local disable_filetypes = { c = true, cpp = true } +-- return { +-- timeout_ms = 500, +-- lsp_format = disable_filetypes[vim.bo[bufnr].filetype] and 'never' or 'fallback', +-- } +-- end, +-- formatters_by_ft = { +-- lua = { 'stylua' }, +-- javascript = { 'prettier' }, +-- typescript = { 'prettier' }, +-- css = { 'prettier' }, +-- scss = { 'prettier' }, +-- html = { 'prettier' }, +-- }, +-- }, +-- }, +-- { +-- 'hrsh7th/nvim-cmp', +-- event = 'InsertEnter', +-- dependencies = { +-- { +-- 'L3MON4D3/LuaSnip', +-- build = (function() +-- if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then +-- return +-- end +-- return 'make install_jsregexp' +-- end)(), +-- }, +-- 'saadparwaiz1/cmp_luasnip', +-- 'hrsh7th/cmp-nvim-lsp', +-- 'hrsh7th/cmp-path', +-- 'hrsh7th/cmp-buffer', +-- 'hrsh7th/cmp-cmdline', +-- }, +-- config = function() +-- local cmp = require 'cmp' +-- local luasnip = require 'luasnip' +-- luasnip.config.setup {} +-- cmp.setup { +-- snippet = { +-- expand = function(args) +-- luasnip.lsp_expand(args.body) +-- end, +-- }, +-- completion = { completeopt = 'menu,menuone,noinsert' }, +-- +-- mapping = cmp.mapping.preset.insert { +-- [''] = cmp.mapping.select_next_item(), +-- [''] = cmp.mapping.select_prev_item(), +-- [''] = cmp.mapping.scroll_docs(-4), +-- [''] = cmp.mapping.scroll_docs(4), +-- [''] = cmp.mapping.confirm { select = true }, +-- [''] = cmp.mapping.complete {}, +-- [''] = cmp.mapping(function() +-- if luasnip.expand_or_locally_jumpable() then +-- luasnip.expand_or_jump() +-- end +-- end, { 'i', 's' }), +-- [''] = cmp.mapping(function() +-- if luasnip.locally_jumpable(-1) then +-- luasnip.jump(-1) +-- end +-- end, { 'i', 's' }), +-- }, +-- +-- sources = cmp.config.sources { +-- { name = 'lazydev', group_index = 0 }, +-- { name = 'nvim_lsp' }, +-- { name = 'luasnip' }, +-- { name = 'path' }, +-- { name = 'buffer' }, +-- }, +-- } +-- end, +-- }, +-- { -- 🎨 Colorscheme +-- 'folke/tokyonight.nvim', +-- priority = 1000, +-- init = function() +-- -- Load colorscheme with specific style +-- vim.cmd.colorscheme 'tokyonight-night' +-- -- Customize Comment color (removes italic) +-- vim.cmd.hi 'Comment gui=none' +-- end, +-- }, +-- -- ✅ Highlight TODOs, FIXMEs, and other comments +-- { +-- 'folke/todo-comments.nvim', +-- event = 'VimEnter', +-- dependencies = { 'nvim-lua/plenary.nvim' }, +-- opts = { signs = false }, +-- }, +-- { -- 🛠️ mini.nvim utility plugins (better text objects, surround, and statusline) +-- 'echasnovski/mini.nvim', +-- config = function() +-- -- Setup mini.ai for better text objects +-- require('mini.ai').setup { +-- n_lines = 500, +-- } +-- -- Setup mini.surround for surrounding text objects +-- require('mini.surround').setup() +-- +-- -- Setup mini.statusline for a better status line +-- require('mini.statusline').setup { +-- use_icons = vim.g.have_nerd_font, +-- content = { +-- active = function() +-- return '%2l:%-2v' -- line:column display +-- end, +-- }, +-- } +-- end, +-- }, +-- { +-- 'nvim-treesitter/nvim-treesitter', +-- build = ':tsupdate', +-- main = 'nvim-treesitter.configs', +-- opts = { +-- ensure_installed = { +-- 'bash', +-- 'c', +-- 'diff', +-- 'html', +-- 'css', +-- 'javascript', +-- 'typescript', +-- 'tsx', +-- 'json', +-- 'lua', +-- 'luadoc', +-- 'markdown', +-- 'markdown_inline', +-- 'query', +-- 'vim', +-- 'vimdoc', +-- }, +-- auto_install = true, +-- highlight = { +-- enable = true, +-- additional_vim_regex_highlighting = { 'ruby' }, +-- }, +-- indent = { enable = true, disable = { 'ruby' } }, +-- }, +-- }, +-- ui = { +-- icons = vim.g.have_nerd_font and {} or { +-- cmd = '⌘', +-- config = '🛠', +-- event = '📅', +-- ft = '📂', +-- init = '⚙', +-- keys = '🗝', +-- plugin = '🔌', +-- runtime = '💻', +-- require = '🌙', +-- source = '📄', +-- start = '🚀', +-- task = '📌', +-- lazy = '💤 ', +-- }, +-- }, +-- } +-- +-- return M