diff --git a/config/nvim/lsp/ts_ls.lua b/config/nvim/lsp/ts_ls.lua new file mode 100644 index 0000000..2424a71 --- /dev/null +++ b/config/nvim/lsp/ts_ls.lua @@ -0,0 +1,81 @@ +return { + init_options = { hostInfo = 'neovim' }, + cmd = { 'typescript-language-server', '--stdio' }, + filetypes = { + 'javascript', + 'javascriptreact', + 'javascript.jsx', + 'typescript', + 'typescriptreact', + 'typescript.tsx', + }, + root_dir = function(bufnr, on_dir) + -- The project root is where the LSP can be started from + -- As stated in the documentation above, this LSP supports monorepos and simple projects. + -- We select then from the project root, which is identified by the presence of a package + -- manager lock file. + local root_markers = { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock' } + -- Give the root markers equal priority by wrapping them in a table + root_markers = vim.fn.has 'nvim-0.11.3' == 1 and { root_markers, { '.git' } } or vim.list_extend(root_markers, { '.git' }) + -- We fallback to the current working directory if no project root is found + local project_root = vim.fs.root(bufnr, root_markers) or vim.fn.getcwd() + + on_dir(project_root) + end, + handlers = { + -- handle rename request for certain code actions like extracting functions / types + ['_typescript.rename'] = function(_, result, ctx) + local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) + vim.lsp.util.show_document({ + uri = result.textDocument.uri, + range = { + start = result.position, + ['end'] = result.position, + }, + }, client.offset_encoding) + vim.lsp.buf.rename() + return vim.NIL + end, + }, + commands = { + ['editor.action.showReferences'] = function(command, ctx) + local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) + local file_uri, position, references = unpack(command.arguments) + + local quickfix_items = vim.lsp.util.locations_to_items(references, client.offset_encoding) + vim.fn.setqflist({}, ' ', { + title = command.title, + items = quickfix_items, + context = { + command = command, + bufnr = ctx.bufnr, + }, + }) + + vim.lsp.util.show_document({ + uri = file_uri, + range = { + start = position, + ['end'] = position, + }, + }, client.offset_encoding) + + vim.cmd 'botright copen' + end, + }, + on_attach = function(client, bufnr) + -- ts_ls provides `source.*` code actions that apply to the whole file. These only appear in + -- `vim.lsp.buf.code_action()` if specified in `context.only`. + vim.api.nvim_buf_create_user_command(bufnr, 'LspTypescriptSourceAction', function() + local source_actions = vim.tbl_filter(function(action) + return vim.startswith(action, 'source.') + end, client.server_capabilities.codeActionProvider.codeActionKinds) + + vim.lsp.buf.code_action { + context = { + only = source_actions, + }, + } + end, {}) + end, +} diff --git a/config/nvim/lua/config/lsp.lua b/config/nvim/lua/config/lsp.lua index dce8628..83d462a 100644 --- a/config/nvim/lua/config/lsp.lua +++ b/config/nvim/lua/config/lsp.lua @@ -1,6 +1,7 @@ -- enables LSPs and configures useful bindings -vim.lsp.enable('lua_ls') +vim.lsp.enable 'lua_ls' +vim.lsp.enable 'ts_ls' vim.api.nvim_create_autocmd('LspAttach', { callback = function(ev) @@ -12,11 +13,11 @@ vim.api.nvim_create_autocmd('LspAttach', { vim.lsp.completion.get() end) end - end + end, }) -- Diagnostics -vim.diagnostic.config({ +vim.diagnostic.config { -- Use the default configuration -- virtual_lines = true @@ -25,4 +26,4 @@ vim.diagnostic.config({ -- Only show virtual line diagnostics for the current cursor line current_line = true, }, -}) +} diff --git a/config/nvim/lua/plugins/telescope.lua b/config/nvim/lua/plugins/telescope.lua index be344dc..ef586eb 100644 --- a/config/nvim/lua/plugins/telescope.lua +++ b/config/nvim/lua/plugins/telescope.lua @@ -2,7 +2,45 @@ return { { 'nvim-telescope/telescope.nvim', tag = '0.1.8', - dependencies = { 'nvim-lua/plenary.nvim', { 'nvim-telescope/telescope-fzf-native.nvim', build = 'make' } }, - config = function() end, + dependencies = { + 'nvim-lua/plenary.nvim', + { + 'nvim-telescope/telescope-fzf-native.nvim', + build = 'make', + config = function() + require('telescope').load_extension 'fzf' + end, + }, + }, + keys = { + { + 't', + function() + require('telescope.builtin').find_files() + end, + desc = 'Find file', + }, + { + 'f', + function() + require('telescope.builtin').live_grep() + end, + desc = 'Codesearch', + }, + { + 'g', + function() + require('telescope.builtin').lsp_references() + end, + desc = 'View references', + }, + }, + opts = { + pickers = { + lsp_references = { + theme = 'ivy', + }, + }, + }, }, }