diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index 6dd47d5..8fa3351 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -16,7 +16,17 @@ end, { desc = "Github browse (current line)" }) vim.keymap.set("n", "gR", function() vim.cmd("!gh repo view -w") end, { desc = "Github browse repository" }) --- Yank to clipboard +-- Reset home :cd %:p:h +vim.keymap.set("n", "rd", function() + vim.cmd("cd %:p:h") + vim.notify("Root directory set to %:p:h", vim.log.levels.INFO) +end, { desc = "Set current directory as root directory" }) +-- Yank current file name to clipboard +vim.keymap.set("n", "fy", function() + vim.cmd("let @+ = expand('%')") + vim.notify("Yanked to system clipboard " .. vim.fn.expand("%"), vim.log.levels.INFO) +end, { desc = "Yank current file path to system clipboard" }) +-- Yank selected text to clipboard vim.keymap.set("v", "y", '"*y', { desc = "Yank to system clipboard" }) -- jq vim.keymap.set("n", "jq", ":%!jq", { desc = "Stream current buffer to jq (json.parse current buffer)" }) @@ -26,3 +36,23 @@ vim.keymap.set("n", "", function() end, { desc = "Telescope resume last search" }) -- Delete mark vim.keymap.set("n", "dm", ":delmarks ", { desc = "Stream current buffer to jq (json.parse current buffer)" }) +-- Close buffler split +vim.keymap.set("n", "bx", ":quit", { desc = "Close focused split buffer" }) +-- Jump to implementation +vim.keymap.set("n", "gi", "Telescope lsp_implementations", { desc = "Telescope Go to implementation" }) +-- Set filte-type +vim.keymap.set("n", "ft", ":set filetype=", { desc = "Set file type" }) +-- Tidy code +vim.keymap.set("n", "ct", function() + vim.lsp.buf.code_action({ + context = { only = { "source.removeUnused.ts" }, diagnostics = {} }, + apply = true, + }) + vim.lsp.buf.code_action({ + context = { only = { "source.addMissingImports.ts" }, diagnostics = {} }, + apply = true, + }) + vim.defer_fn(function() + LazyVim.format({ force = true }) + end, 500) +end, { desc = "Tidy typescript code" }) diff --git a/lua/plugins/color-scheme.lua b/lua/plugins/color-scheme.lua index 509b0be..d5057bd 100644 --- a/lua/plugins/color-scheme.lua +++ b/lua/plugins/color-scheme.lua @@ -15,7 +15,7 @@ return { -- Style to be applied to different syntax groups -- Value is any valid attr-list value for `:help nvim_set_hl` comments = { italic = true }, - keywords = { italic = true }, + keywords = { italic = false, fg = "#0000b5" }, functions = {}, variables = {}, }, @@ -36,11 +36,27 @@ return { highlights.Pmenu = { bg = colors.bg_alt } highlights.PmenuSel = { bg = colors.bg_hl_line } highlights.PmenuExtra = { bg = colors.bg_alt } - highlights.FloatBorder = { bg = colors.bg_alt } + highlights.FloatBorder = { bg = colors.bg_alt, fg = colors.fg_main } + highlights.LspFloatWinBorder = { fg = colors.fg_main, bg = colors.bg_main, style = "bold" } -- border to the documentation window + highlights.LspFloatWinNormal = { bg = colors.bg_main, style = "bold" } -- Change the floating windows background to light grey + -- highlights.NoicePopupBorder = { fg = colors.red } -- highlights.NormalFloat = { bg = "#f8f9fa" } -- Change the floating windows background to light grey highlights.CursorLine = { bg = "#effaff" } highlights.Directory = { fg = "#000000" } -- highlights.LineNr = { fg = colors.fg_dim, bg = "#ffffff" } + + -- Code + highlights.String = { fg = "#0c703e" } + highlights["@keyword.import"] = { fg = "#0000b5" } + highlights["@keyword.function"] = { fg = "#0000b5" } + highlights["@lsp.typemod.function.declaration"] = { fg = "#1c2833" } + highlights["@lsp.type.function"] = { fg = "#1c2833", italic = true } + highlights["@lsp.type.method"] = { fg = colors.cyan_faint } + highlights["@function.method.call"] = { bold = true } + highlights["@function.call"] = { bold = true } + -- highlights["@lsp.typemod.function.readonly.typescript"] = { underline = true } + highlights.Operator = { fg = "#cf000f" } + highlights.Underlined = { underline = true, fg = "#444444" } end, }) diff --git a/lua/plugins/fugitive.lua b/lua/plugins/fugitive.lua new file mode 100644 index 0000000..25291b2 --- /dev/null +++ b/lua/plugins/fugitive.lua @@ -0,0 +1,10 @@ +return { + "tpope/vim-fugitive", + -- Optional: Configure lazy loading + -- cmd = { "Git", "Gedit", "Gstatus", "Gdiffsplit", "Gblame" }, + keys = { "gi" }, -- Example key mapping for lazy loading + config = function() + -- Optional: Add keymaps or settings for Vim Fugitive here + vim.keymap.set("n", "gi", ":Git ", { desc = "Git Status" }) + end, +} diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index b63f2d2..85be2d3 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -2,5 +2,181 @@ return { "neovim/nvim-lspconfig", opts = { inlay_hints = { enabled = false }, + -- make sure mason installs the server + servers = { + --- @deprecated -- tsserver renamed to ts_ls but not yet released, so keep this for now + --- the proper approach is to check the nvim-lspconfig release version when it's released to determine the server name dynamically + tsserver = { + enabled = false, + }, + ts_ls = { + enabled = false, + }, + -- schema https://github.com/yioneko/vtsls/blob/main/packages/service/configuration.schema.json + vtsls = { + -- explicitly add default filetypes, so that we can extend + -- them in related extras + filetypes = { + "javascript", + "javascriptreact", + "javascript.jsx", + "typescript", + "typescriptreact", + "typescript.tsx", + }, + settings = { + complete_function_calls = true, + vtsls = { + enableMoveToFileCodeAction = true, + autoUseWorkspaceTsdk = true, + experimental = { + maxInlayHintLength = 50, + completion = { + enableServerSideFuzzyMatch = true, + }, + }, + }, + typescript = { + preferences = { + useAliasesForRenames = false, + }, + updateImportsOnFileMove = { enabled = "always" }, + suggest = { + completeFunctionCalls = true, + }, + inlayHints = { + enumMemberValues = { enabled = true }, + functionLikeReturnTypes = { enabled = true }, + parameterNames = { enabled = "literals" }, + parameterTypes = { enabled = true }, + propertyDeclarationTypes = { enabled = true }, + variableTypes = { enabled = true }, + }, + }, + }, + keys = { + { + "gD", + function() + local params = vim.lsp.util.make_position_params() + LazyVim.lsp.execute({ + command = "typescript.goToSourceDefinition", + arguments = { params.textDocument.uri, params.position }, + open = true, + }) + end, + desc = "Goto Source Definition", + }, + { + "gR", + function() + LazyVim.lsp.execute({ + command = "typescript.findAllFileReferences", + arguments = { vim.uri_from_bufnr(0) }, + open = true, + }) + end, + desc = "File References", + }, + { + "co", + LazyVim.lsp.action["source.organizeImports"], + desc = "Organize Imports", + }, + { + "cM", + LazyVim.lsp.action["source.addMissingImports.ts"], + desc = "Add missing imports", + }, + { + "cu", + LazyVim.lsp.action["source.removeUnused.ts"], + desc = "Remove unused imports", + }, + { + "cD", + LazyVim.lsp.action["source.fixAll.ts"], + desc = "Fix all diagnostics", + }, + { + "cV", + function() + LazyVim.lsp.execute({ command = "typescript.selectTypeScriptVersion" }) + end, + desc = "Select TS workspace version", + }, + }, + }, + }, + setup = { + --- @deprecated -- tsserver renamed to ts_ls but not yet released, so keep this for now + --- the proper approach is to check the nvim-lspconfig release version when it's released to determine the server name dynamically + tsserver = function() + -- disable tsserver + return true + end, + ts_ls = function() + -- disable tsserver + return true + end, + vtsls = function(_, opts) + LazyVim.lsp.on_attach(function(client, buffer) + client.server_capabilities.renameProvider = { + prepareProvider = false, + } + client.commands["_typescript.moveToFileRefactoring"] = function(command, ctx) + ---@type string, string, lsp.Range + local action, uri, range = unpack(command.arguments) + + local function move(newf) + client.request("workspace/executeCommand", { + command = command.command, + arguments = { action, uri, range, newf }, + }) + end + + local fname = vim.uri_to_fname(uri) + client.request("workspace/executeCommand", { + command = "typescript.tsserverRequest", + arguments = { + "getMoveToRefactoringFileSuggestions", + { + file = fname, + startLine = range.start.line + 1, + startOffset = range.start.character + 1, + endLine = range["end"].line + 1, + endOffset = range["end"].character + 1, + }, + }, + }, function(_, result) + ---@type string[] + local files = result.body.files + table.insert(files, 1, "Enter new path...") + vim.ui.select(files, { + prompt = "Select move destination:", + format_item = function(f) + return vim.fn.fnamemodify(f, ":~:.") + end, + }, function(f) + if f and f:find("^Enter new path") then + vim.ui.input({ + prompt = "Enter move destination:", + default = vim.fn.fnamemodify(fname, ":h") .. "/", + completion = "file", + }, function(newf) + return newf and move(newf) + end) + elseif f then + move(f) + end + end) + end) + end + end, "vtsls") + -- copy typescript settings to javascript + opts.settings.javascript = + vim.tbl_deep_extend("force", {}, opts.settings.typescript, opts.settings.javascript or {}) + end, + }, }, } diff --git a/lua/plugins/neo-tree.lua b/lua/plugins/neo-tree.lua index 4f26ace..e04615c 100644 --- a/lua/plugins/neo-tree.lua +++ b/lua/plugins/neo-tree.lua @@ -1,48 +1,46 @@ return { "nvim-neo-tree/neo-tree.nvim", - config = function() - require("neo-tree").setup({ - default_component_configs = { - indent = { - with_expanders = true, -- if nil and file nesting is enabled, will enable expanders - expander_collapsed = "", - expander_expanded = "", - expander_highlight = "NeoTreeExpander", - }, - icon = { - folder_closed = "", - folder_open = "", - folder_empty = "󰜌", - -- The next two settings are only a fallback, if you use nvim-web-devicons and configure default icons there - -- then these will never be used. - default = "*", - highlight = "NeoTreeFileIcon", - }, - modified = { - symbol = "[+]", - highlight = "NeoTreeModified", - }, - name = { - trailing_slash = false, - use_git_status_colors = true, - highlight = "NeoTreeFileName", - }, - git_status = { - symbols = { - -- Change type - added = "", -- or "✚", but this is redundant info if you use git_status_colors on the name - modified = "", -- or "", but this is redundant info if you use git_status_colors on the name - deleted = "", -- this can only be used in the git_status source - renamed = "", -- this can only be used in the git_status source - -- Status type - untracked = "", - ignored = "", - unstaged = "", - staged = "", - conflict = "", - }, + opts = { + default_component_configs = { + indent = { + with_expanders = true, -- if nil and file nesting is enabled, will enable expanders + expander_collapsed = "", + expander_expanded = "", + expander_highlight = "NeoTreeExpander", + }, + icon = { + folder_closed = "", + folder_open = "", + folder_empty = "󰜌", + -- The next two settings are only a fallback, if you use nvim-web-devicons and configure default icons there + -- then these will never be used. + default = "*", + highlight = "NeoTreeFileIcon", + }, + modified = { + symbol = "[+]", + highlight = "NeoTreeModified", + }, + name = { + trailing_slash = false, + use_git_status_colors = true, + highlight = "NeoTreeFileName", + }, + git_status = { + symbols = { + -- Change type + added = "", -- or "✚", but this is redundant info if you use git_status_colors on the name + modified = "", -- or "", but this is redundant info if you use git_status_colors on the name + deleted = "", -- this can only be used in the git_status source + renamed = "", -- this can only be used in the git_status source + -- Status type + untracked = "", + ignored = "", + unstaged = "", + staged = "", + conflict = "", }, }, - }) - end, + }, + }, } diff --git a/lua/plugins/noice.lua b/lua/plugins/noice.lua index 6fe2b47..a9b7aef 100644 --- a/lua/plugins/noice.lua +++ b/lua/plugins/noice.lua @@ -1,3 +1,4 @@ +local text = require("noice.text") return { "folke/noice.nvim", event = "VeryLazy", @@ -164,7 +165,23 @@ return { replace = true, render = "plain", format = { "{message}" }, - win_options = { concealcursor = "n", conceallevel = 3 }, + size = { + max_width = math.floor(0.5 * vim.api.nvim_win_get_width(0)), + max_height = 15, + }, + position = { row = 2, col = 2 }, + border = { + style = "rounded", + padding = { 0, 0, 0, 0 }, + }, + win_options = { + concealcursor = "n", + conceallevel = 3, + winhighlight = { + Normal = "LspFloatWinNormal", + FloatBorder = "LspFloatWinBorder", + }, + }, }, }, }, diff --git a/lua/plugins/telescope.lua b/lua/plugins/telescope.lua index 902e979..b02bb7e 100644 --- a/lua/plugins/telescope.lua +++ b/lua/plugins/telescope.lua @@ -2,7 +2,7 @@ return { "nvim-telescope/telescope-file-browser.nvim", keys = { { - "sB", + "fB", ":Telescope file_browser path=%:p:h=%:p:h", desc = "Browse Files", }, diff --git a/lua/plugins/webdev-icons.lua b/lua/plugins/webdev-icons.lua new file mode 100644 index 0000000..728465a --- /dev/null +++ b/lua/plugins/webdev-icons.lua @@ -0,0 +1,28 @@ +-- Ensure nvim-web-devicons is loaded first otherwise the setup override does not work +require("nvim-web-devicons").setup({ + override_by_extension = { + ["ts"] = { + icon = "󰛦", -- Default TypeScript icon + color = "#1b3f7a", + cterm_color = "214", + name = "TypeScript", + }, + }, + override_by_filename = { + ["tsconfig.json"] = { + icon = "", + color = "#1b3f7a", + cterm_color = "66", + name = "tsconfig.json", + }, + }, +}) + +-- Assertion to validate the override +local devicons = require("nvim-web-devicons") +local icon, icon_color = devicons.get_icon_color("file.ts", "ts") +-- Validate the icon and color +assert(icon == "󰛦", "Icon override failed: Expected '󰛦'") +assert(icon_color == "#1b3f7a", "Color override failed: Expected '#1b3f7a'") + +return {}