A Lua plugin, written in TypeScript, to write TypeScript (Lua optional).

Overview

typescript.nvim

A minimal typescript-language-server integration plugin to set up the language server via nvim-lspconfig and add commands for convenience. Written in TypeScript and transpiled to Lua using TypeScriptToLua.

This plugin is in beta status. It's stable enough for daily use, but breaking changes are possible.

Requires Neovim 0.7.

Setup

Install the plugin with your favorite plugin manager, then add require("typescript").setup() to your config. This will set up the plugin and typescript-language-server with default settings.

The following example shows all available options and their defaults:

require("typescript").setup({
    disable_commands = false, -- prevent the plugin from creating Vim commands
    disable_formatting = false, -- disable tsserver's formatting capabilities
    debug = false, -- enable debug logging for commands
    server = { -- pass options to lspconfig's setup method
        on_attach = ...,
    },
})

Features

The plugin exposes its functionality via Vim commands as well as a Lua API. The following commands are async by default, but you can make them run synchronously by adding a ! to Vim commands or passing { sync = true } to Lua commands.

  • Add missing imports: :TypescriptAddMissingImports / require("typescript").addMissingImports()

  • Organize imports: :TypescriptOrganizeImports / require("typescript").organizeImports()

  • Remove unused variables: :TypescriptRemoveUnused / require("typescript").removeUnused()

  • Fix all: :TypescriptFixAll / require("typescript").fixAll()

    Despite the name, this command fixes a handful of specific issues, most notably non-async functions that use await and unreachable code.

  • Rename file: :TypescriptRenameFile / require("typescript").renameFile(source, target)

    This command is always asynchronous. The Vim command will always operate on the current buffer and prompt for a rename target, while the Lua version requires specifying the full path to a source and target.

Not yet implemented

  • Inlay hints

Will not implement

  • Anything not supported by typescript-language-server itself

Contributing

  1. Clone the repo and run npm install.
  2. Change or add TypeScript source files under the src/ directory.
  3. Test your changes locally with npm run dev.
  4. Build your changes before committing with npm run build.

Integration tests are in Lua and depend on plenary.nvim. Run make test from the root of the repo.

Comments
  • Not clear how to make it work with tsserver lspconfig

    Not clear how to make it work with tsserver lspconfig

    I have this config for lsp:

    local status_ok, mason_lspconfig = pcall(require, "mason-lspconfig")
    if not status_ok then
      return
    end
    
    local mason = require("mason")
    local lspconfig = require("lspconfig")
    
    local servers = { "jsonls", "sumneko_lua", "tsserver", "cssls" }
    
    mason.setup()
    mason_lspconfig.setup({
      ensure_installed = servers,
    })
    
    for _, server in pairs(servers) do
      local opts = {
        on_attach = require("user.lsp.handlers").on_attach,
        capabilities = require("user.lsp.handlers").capabilities,
      }
      local has_custom_opts, server_custom_opts = pcall(require, "user.lsp.settings." .. server)
      if has_custom_opts then
        opts = vim.tbl_deep_extend("force", opts, server_custom_opts)
      end
      lspconfig[server].setup(opts)
    end
    

    https://github.com/strdr4605/.dotfiles/blob/master/nvim/lua/user/lsp/configs.lua

    and I call require("typescript").setup() here: https://github.com/strdr4605/.dotfiles/blob/master/nvim/lua/user/lsp/null-ls.lua

    As I understand from the note in README, I should not call lspconfig[server].setup(opts) with tsserver. I tried:

    ```lua
    local status_ok, mason_lspconfig = pcall(require, "mason-lspconfig")
    if not status_ok then
      return
    end
    
    local mason = require("mason")
    local lspconfig = require("lspconfig")
    
    - local servers = { "jsonls", "sumneko_lua", "tsserver", "cssls" }
    + local servers = { "jsonls", "sumneko_lua", "cssls" }
    
    
    mason.setup()
    mason_lspconfig.setup({
      ensure_installed = servers,
    })
    
    for _, server in pairs(servers) do
      local opts = {
        on_attach = require("user.lsp.handlers").on_attach,
        capabilities = require("user.lsp.handlers").capabilities,
      }
      local has_custom_opts, server_custom_opts = pcall(require, "user.lsp.settings." .. server)
      if has_custom_opts then
        opts = vim.tbl_deep_extend("force", opts, server_custom_opts)
      end
      lspconfig[server].setup(opts)
    end
    
    + require("typescript").setup()
    

    But lsp for TS is not working anymore. What am I doing wrong?

    opened by strdr4605 8
  • TypescriptRenameFile is not working

    TypescriptRenameFile is not working

    Hello, thanks for this great extension, really improves typescript development. One of the main features I wanted was to rename files taking care to update the imports, something I really miss form vscode. However, I tried it and does nothing, it even asks for a new name, but then nothing happens. Other commands like remove unused and short improts work properly, so I'm not sure what could happen with rename file. Is there any debug info I can get?

    opened by danielo515 8
  • fix: onConfirm TypescriptRenameFile

    fix: onConfirm TypescriptRenameFile

    Hello !

    First thank you for this plugin, i have been using null-ls for a year now as a typescript dev with LunarVim config.

    This PR fixes #3 about TypescriptRenameFile.

    The issue was about the tests for target and renameFile that are executed immediately after the input (and not only after confirmation). So the target was always undefined.

    opened by williamgoulois 7
  • :Typescript commands are not created after install

    :Typescript commands are not created after install

    Hello,

    After installation and configuration i dont see the commands created, is it normal?

    image

    I see this problems in the source code and tried installed that npm package but still givin the error image

    Is it because this plugin is still in development? I am just searching a way to add import all functionality to nvim

    opened by jugarpeupv 7
  • TypescriptGoToSourceDefinition failing

    TypescriptGoToSourceDefinition failing

    Hello πŸ‘‹πŸΌ,

    For certain projects I'm seeing failures to use the source definition mapping. I'm seeing the following issue:

    Error executing vim.schedule lua callback: vim/shared.lua:0: Expected table, got nil                                                                                          
    stack traceback:                                                                                                                                                              
            [C]: in function 'assert'                                                                                                                                             
            vim/shared.lua: in function 'tbl_isempty'                                                                                                                             
            .../site/pack/packer/opt/typescript.nvim/lua/typescript.lua:2679: in function 'handler'                                                                               
            /usr/share/nvim/runtime/lua/vim/lsp.lua:1390: in function ''                                                                                                          
            vim/_editor.lua: in function <vim/_editor.lua:0>                                                                                                                      
    Press ENTER or type command to continue     
    
    opened by sQVe 5
  • when this plugin is loaded, some completions aren't showing

    when this plugin is loaded, some completions aren't showing

    with this config, some completions in react proyect aren't showing:

    local formatting_callback = function(client, bufnr)
      vim.keymap.set('n', '<leader>f', function()
        local params = util.make_formatting_params({})
        client.request('textDocument/formatting', params, nil, bufnr)
      end, { buffer = bufnr })
    end
    
    capabilities.textDocument.completion.completionItem.snippetSupport = true
    require('cmp_nvim_lsp').update_capabilities(capabilities)
    
    for server, config in pairs(vim.g.SERVERS) do
      if server == "tsserver" then
        require("typescript").setup({
          disable_commands = false, -- prevent the plugin from creating Vim commands
          debug = false, -- enable debug logging for commands
          server = {
            on_attach = function(client, bufnr)
              on_attach(client, bufnr)
              formatting_callback(client, bufnr)
            end,
          }
        })
      else
        require('lspconfig')[server].setup(
          vim.tbl_deep_extend("force", { capabilities = capabilities, on_attach = on_attach }, config)
        )
      end
    end
    

    where vim.g.servers are a table like:

    vim.g.SERVERS = {
      cssls = {},
      cssmodules_ls = {},
      html = {},
      tsserver = {}
    }
    

    without the plugin, the completion work normally:

    for server, config in pairs(vim.g.SERVERS) do
        require('lspconfig')[server].setup(
          vim.tbl_deep_extend("force", { capabilities = capabilities, on_attach = on_attach }, config)
        )
      end
    
    opened by jrafaaael 5
  • Duplicate logs with eslint lsp server.

    Duplicate logs with eslint lsp server.

    Good day!

    Would it be possible to adjust the log-level as well through this plugin's config? I'm using eslint and tsserver together and I'm seeing (kinda) duplicate error logs, which I assume comes from my .eslintrc.js in my project and the one being used by the tsserver? I have not really plunged into the depths of linters and so I might be wrong.

    image

    I'm interested to hear what your approach would be to this? I was thinking of reducing the log-level op the tsserver.

    opened by mattiasbonte 5
  • Add handler for `_typescript.rename`

    Add handler for `_typescript.rename`

    Type: Feature request

    We need to first understand why we need to add this.

    To reproduce:

    1. Write the following code in a TypeScript file
    setInterval(() => {
      console.log(s);
    }, 1000);
    
    1. Now visually select the anonymous function and invoke a range code action. It would be :'<,'>lua vim.lsp.buf.range_code_action()
    2. This would give you a code action "Extract to function in module scope". Invoke it.
    3. You would see the code has changed but would also notice an error echo tsserver: -32601: MethodNotFound
    4. Upon inspecting LSP log you would see server_request: no handler found for _typescript.rename

    In VS Code, the editor asks you provide a new name for the function after the code action is performed. In neovim+typescript.nvim, it could only perform the code action as the aforementioned handler is missing.

    The solution?

    I have written a handler in Lua. This makes nvim behave same as VS Code. Do note that I assume the position given by tsserver is for UTF-16 text. I do not rely on off-spec client.offset_encoding and would rather wait until tsserver starts supporting positionEncodings (if it still hasn't yet).

    Edit: You can find the updated handler here which uses Lua API finstead for setting the cursor position.

    opened by ajitid 5
  • Add customization to import sorter

    Add customization to import sorter

    It is more or less a good practice to have import React from 'react' at the top of all other imports, but this plugin sometimes does it differently.

    This can be added as a customization option that would allow users defining their own order like eslint import order.

    Or some most common framework / library imports can be set inside the plugin as the first priority.

    opened by sarmong 4
  • Can't tell what this plugin offers

    Can't tell what this plugin offers

    Hi! I landed here from https://github.com/rockerBOO/awesome-neovim.

    However, when I got to the README, I couldn't tell what this plugin offers vs. lspconfig.tsserver.setup()

    • Is it speed?
    • More features of some kind?
    • Are there things I should be excited about that this plugin provides?

    Possible to update the README with more context?

    opened by dbalatero 4
  • Odd startup error

    Odd startup error

    I'm using LunarVim, and I've set up typescript.nvim in Packer by following the instructions in the readme.

      {
        "jose-elias-alvarez/typescript.nvim",
        config = function()
          require("typescript").setup()
        end,
      },
    

    When I start my editor, I'm getting the following error.

    packer.nvim: Error running config for typescript.nvim: vim/shared.lua:0: after the second argument: expected table, got nil
    

    I'm using the latest version of Neovim (0.8.0), and the latest version of typescript.nvim.

    Any idea what could be causing this?

    opened by LandonSchropp 4
  • refactor: split transpiled code

    refactor: split transpiled code

    Thanks to guidance on the TSTL repo, I've figured out how to properly split transpiled Lua code in a Neovim-friendly way. This has a few advantages:

    1. It's now possible to load individual modules
    2. Startup speed should improve, since we don't load a single 3k line Lua file as soon as a user calls require("typescript")
    3. We can now match source files to their Lua equivalents, making it easier to debug issues

    The solution depends on a simple TSTL plugin, which I plan on publishing as a separate package. Adding a TypeScript file that won't get transpiled required other structural changes as well.

    • [x] Figure out why some tests are failing (ended up running tests sequentially, which is more reliable, and deleting a redundant test)
    • [x] Clean up code action source
    • [x] Update documentation
    opened by jose-elias-alvarez 3
  • Move a folder / Rename folder and update imports like `TypescriptRenameFile` does

    Move a folder / Rename folder and update imports like `TypescriptRenameFile` does

    TypescriptRenameFile, works beautifully, updating all the imports.
    Is there a way to move a folder/group of files at once and update all the imports?

    If not, how do you guys deal with moving folders when refactoring?

    Thanks for your awesome work!

    opened by magoz 7
  • Split types to a seperate repo/ npm package

    Split types to a seperate repo/ npm package

    Hello, thanks for this nice project!

    I think the types are useful for everyone writing nvim plugins with typescript and it would be great if you can split them so it can have its own development and contributions. ( I already started adding stuff I'm using )

    opened by sigmaSd 5
Owner
Jose Alvarez
Full-stack developer @openmindlearning, NYC / Tokyo
Jose Alvarez
ESLint plugin to disallow the optional-call operator

ESLint Plugin: no-optional-call Overview The no-optional-call ESLint plugin provides a single rule (non-configurable) that disallows any usage of the

Kyle Simpson 15 Sep 24, 2022
🎑 Generate a random number, a list of them, or a generator with optional configuration

random_number Generate a random number, a list of them, or a generator with optional configuration Usage import randomNumber from "https://deno.land/x

Eliaz Bobadilla 7 Aug 7, 2022
Create your own wrappings with optional key bindings for selected text, a set of useful defaults is also provided.

Create your own wrappings with optional key bindings for selected text, a set of useful defaults is also provided.

Seth Yuan 66 Jan 1, 2023
In this project, you can create optional rooms and people can talk in the rooms

CodeTalk In this project, you can create optional rooms and people can talk in the rooms. Login and Registration page Login page welcomes us. If you d

NazlΔ± 3 Mar 12, 2022
Check the strength of your password simply and quickly, and with optional UI indicators

Check the strength of your password simply and quickly, and with optional UI indicators. Lock Steel is lightweight, has no dependencies and is connected with the UI elements. Just pure CSS and VanillaJS.

Keenlabi 1 Sep 15, 2022
Reference for How to Write an Open Source JavaScript Library - https://egghead.io/series/how-to-write-an-open-source-javascript-library

Reference for How to Write an Open Source JavaScript Library The purpose of this document is to serve as a reference for: How to Write an Open Source

Sarbbottam Bandyopadhyay 175 Dec 24, 2022
Learn GraphQL by building a blogging engine. Create resolvers, write schemas, write queries, design the database, test and also deploy.

GraphQL Blog graphqlblog.com Learn GraphQL by building a blogging engine. Create resolvers, write schemas, write queries, design the database, test an

GraphQLApps 6 Aug 17, 2022
PodNotes is a plugin for Obsidian that helps the user write notes on podcasts.

PodNotes You can find the documentation here. The one goal for PodNotes is to make it easier to write notes on podcasts. Here are the features that wi

Christian Bager Bach Houmann 108 Dec 26, 2022
Micro.publish is an Obsidian plugin to publish notes directly to Micro.blog, written in TypeScript

Micro.publish Micro.publish is a community maintained plugin for Obsidian to publish notes to a Micro.blog blog. Installing This plugin will be availa

Otavio Cordeiro 14 Dec 9, 2022
Write Dockerfiles and CI pipelines in TypeScript.

Trellis Write Dockerfiles and CI pipelines in TypeScript. Trellis is a portable CI/CD tool. With Trellis, you can define your Dockerfiles and CI/CD pi

Charlie Marsh 12 Nov 3, 2022
Screeps Typescript Starter is a starting point for a Screeps AI written in Typescript.

Screeps Typescript Starter Screeps Typescript Starter is a starting point for a Screeps AI written in Typescript. It provides everything you need to s

null 3 Jan 27, 2022
🐬 A simplified implementation of TypeScript's type system written in TypeScript's type system

?? HypeScript Introduction This is a simplified implementation of TypeScript's type system that's written in TypeScript's type annotations. This means

Ronen Amiel 1.8k Dec 20, 2022
Accordion Plugin written in Vanilla JavaScript.

Easy Accordion Accordion plugin written purely in JavaScript. Setup So, to start using the Easy Accordion plugin in your project, you can include the

Farhan Halai 1 Dec 16, 2020
πŸ“— How to write cross-platform Node.js code

How to write cross-platform Node.js code. Why you should care: according to the 2018 Node.js user survey, 24% of Node.js developers use Windows locall

ehmicky 1.3k Jan 3, 2023
JSPro is nothing but JavaScript Prototypes! The publisher is too lazy to write full name that's why it's just JSPro.

JSPro is nothing but JavaScript Prototypes! The publisher is too lazy to write full name that's why it's just JSPro. Whatever, it's a library of hundreds of awesome JavaScript Prototypes (you may know it as dot function) for lazy programmers. Just install the package with a little effort and leave the blames for the publisher.

Jafran Hasan 2 Mar 10, 2022
Chappe - πŸ§‘β€πŸ’» Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine.

Chappe Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine. Chappe is a Developer Do

Valerian Saliou 146 Jan 1, 2023
NpxCard - Write 'npx hariom' in your console.

npx Card This is my NPX card for connecting with me in console or terminal. ❣️ Just Hit npx hariom Will see you in console in just a minute ?? Importa

Hariom gola 2 Jul 26, 2022
This is my to-do list website built with html, css and JavaScript. In this project I used Webpack to bundle JavaScript and ES6 modules to write modular JavaScript.

To-Do-List App This is my to-do list website built with html, css and JavaScript. In this project I used Webpack to bundle JavaScript and ES6 modules

Samuel Mwape 18 Sep 20, 2022
Simple NextJS Project Template to write less boilerplate code when starting a new Next JS Project

Simple NextJS Project Template to write less boilerplate code when starting a new Next JS Project

Juan David Ramirez Mendoza 1 Feb 12, 2022