neovim / neovim

Vim-fork focused on extensibility and usability

Home Page:https://neovim.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Typescript: "Move to a new file" generates an empty file

Bhanukamax opened this issue · comments

  • nvim --version: NVIM v0.5.0-dev+1282-gfbe18d9ca
  • language server name/version: tsserver (I'm not sure how to check the version, how ever i tried with typescript@latest as well)
  • Operating system/version: Pop!_OS 20.04 LTS
nvim -c ":checkhealth nvim lspconfig"

health#nvim#check

Configuration

  • OK: no issues found

Performance

  • INFO: Build type: Debug
  • WARNING: Non-optimized (DEBUG) build. Nvim will be slower.

Remote Plugins

  • OK: Up to date

terminal

  • INFO: key_backspace (kbs) terminfo entry: key_backspace=\177
  • INFO: key_dc (kdch1) terminfo entry: key_dc=\E[3~
  • INFO: $VTE_VERSION='6003'
  • INFO: $COLORTERM='truecolor'

health#lspconfig#check

Checking language server protocol configuration

  • INFO: clangd: configuration checked.
  • INFO: tsserver: configuration checked.
lsp.log

[ DEBUG ] 2021-05-01T16:18:21+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp.lua:887 ] "LSP[tsserver]" "client.request" 1 "textDocument/codeAction" { context = { diagnostics = {} }, range = { end = <1>{ character = 11, line = 4 }, start = <table 1> }, textDocument = { uri = "file:///home/bm/code/try-lsp/ts/main.ts" }} <function 1> 3
[ DEBUG ] 2021-05-01T16:18:21+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:390 ] "rpc.send.payload" { id = 6, jsonrpc = "2.0", method = "textDocument/codeAction", params = { context = { diagnostics = {} }, range = { end = <1>{ character = 11, line = 4 }, start = <table 1> }, textDocument = { uri = "file:///home/bm/code/try-lsp/ts/main.ts" } }}
[ DEBUG ] 2021-05-01T16:18:21+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:491 ] "decoded" { id = 6, jsonrpc = "2.0", result = { { command = { arguments = { { action = "Move to a new file", endLine = 5, endOffset = 12, file = "/home/bm/code/try-lsp/ts/main.ts", refactor = "Move to a new file", startLine = 5, startOffset = 12 } }, command = "_typescript.applyRefactoring", title = "Move to a new file" }, kind = "refactor.move", title = "Move to a new file" } }}
[ DEBUG ] 2021-05-01T16:18:21+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/handlers.lua:442 ] "default_handler" "textDocument/codeAction" { bufnr = 3, client_id = 1, params = { { command = { arguments = { { action = "Move to a new file", endLine = 5, endOffset = 12, file = "/home/bm/code/try-lsp/ts/main.ts", refactor = "Move to a new file", startLine = 5, startOffset = 12 } }, command = "_typescript.applyRefactoring", title = "Move to a new file" }, kind = "refactor.move", title = "Move to a new file" } }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp.lua:887 ] "LSP[tsserver]" "client.request" 1 "workspace/executeCommand" { arguments = { { action = "Move to a new file", endLine = 5, endOffset = 12, file = "/home/bm/code/try-lsp/ts/main.ts", refactor = "Move to a new file", startLine = 5, startOffset = 12 } }, command = "_typescript.applyRefactoring", title = "Move to a new file"} <function 1> 3
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:390 ] "rpc.send.payload" { id = 7, jsonrpc = "2.0", method = "workspace/executeCommand", params = { arguments = { { action = "Move to a new file", endLine = 5, endOffset = 12, file = "/home/bm/code/try-lsp/ts/main.ts", refactor = "Move to a new file", startLine = 5, startOffset = 12 } }, command = "_typescript.applyRefactoring", title = "Move to a new file" }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:491 ] "decoded" { id = 1, jsonrpc = "2.0", method = "workspace/applyEdit", params = { edit = { changes = { ["file:///home/bm/code/try-lsp/ts/main.ts"] = { { newText = 'import { myNewFunc } from "./myNewFunc";\n', range = { end = { character = 0, line = 0 }, start = { character = 0, line = 0 } } }, { newText = "", range = { end = { character = 0, line = 8 }, start = { character = 0, line = 4 } } } }, ["file:///home/bm/code/try-lsp/ts/myNewFunc.ts"] = { { newText = 'import { testing } from "./testing";\n\nexport function myNewFunc(): void {\n testing();\n}\n', range = { end = { character = -1, line = -1 }, start = { character = -1, line = -1 } } } } } } }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp.lua:686 ] "server_request" "workspace/applyEdit" { edit = { changes = { ["file:///home/bm/code/try-lsp/ts/main.ts"] = { { newText = 'import { myNewFunc } from "./myNewFunc";\n', range = { end = { character = 0, line = 0 }, start = { character = 0, line = 0 } } }, { newText = "", range = { end = { character = 0, line = 8 }, start = { character = 0, line = 4 } } } }, ["file:///home/bm/code/try-lsp/ts/myNewFunc.ts"] = { { newText = 'import { testing } from "./testing";\n\nexport function myNewFunc(): void {\n testing();\n}\n', range = { end = { character = -1, line = -1 }, start = { character = -1, line = -1 } } } } } }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp.lua:689 ] "server_request: found handler for" "workspace/applyEdit"
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/handlers.lua:442 ] "default_handler" "workspace/applyEdit" { client_id = 1, params = { edit = { changes = { ["file:///home/bm/code/try-lsp/ts/main.ts"] = { { newText = 'import { myNewFunc } from "./myNewFunc";\n', range = { end = { character = 0, line = 0 }, start = { character = 0, line = 0 } } }, { newText = "", range = { end = { character = 0, line = 8 }, start = { character = 0, line = 4 } } } }, ["file:///home/bm/code/try-lsp/ts/myNewFunc.ts"] = { { newText = 'import { testing } from "./testing";\n\nexport function myNewFunc(): void {\n testing();\n}\n', range = { end = { character = -1, line = -1 }, start = { character = -1, line = -1 } } } } } } }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:390 ] "rpc.send.payload" { jsonrpc = "2.0", method = "textDocument/didOpen", params = { textDocument = { languageId = "typescript", text = "\n", uri = "file:///home/bm/code/try-lsp/ts/myNewFunc.ts", version = 0 } }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:502 ] "server_request: callback result" { result = { applied = false, failureReason = "/usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:77: Invalid range: { 0, { 'import { testing } from "./testing";', "", "export function myNewFunc(): void {", " testing();", "}", "" },\n A = { 0, -1 },\n B = { 0, -1 }\n}" }, status = true}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:390 ] "rpc.send.payload" { id = 1, jsonrpc = "2.0", result = { applied = false, failureReason = "/usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:77: Invalid range: { 0, { 'import { testing } from "./testing";', "", "export function myNewFunc(): void {", " testing();", "}", "" },\n A = { 0, -1 },\n B = { 0, -1 }\n}" }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/handlers.lua:442 ] "default_handler" "textDocument/publishDiagnostics" { client_id = 1, params = { diagnostics = {}, uri = "file:///home/bm/code/try-lsp/ts/myNewFunc.ts" }}
[ DEBUG ] 2021-05-01T16:18:23+0530 ] /usr/local/share/nvim/runtime/lua/vim/lsp/rpc.lua:491 ] "decoded" { id = 7, jsonrpc = "2.0", result = vim.NIL}

I noticed the following line in the logs, hope that helps to debug the issue

"server_request: callback result"	{  result = {    applied = false,    failureReason = "/usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:77: Invalid range: { 0, { 'import { testing } from \"./testing\";', \"\", \"export function myNewFunc(): void {\", \"    testing();\", \"}\", \"\" },\n  A = { 0, -1 },\n  B = { 0, -1 }\n}"  },  status = true}

Also a related fix in emacs lsp-mode :)
Issue:
emacs-lsp/lsp-mode#1582
PR:
emacs-lsp/lsp-mode@e7d1339

Steps to reproduce using nvim -u minimal_init.lua

  1. add tsserver to config
    require'lspconfig'.tsserver.setup{}

  2. create 3 files like below
    mian.ts

import {testing} from "./testing";

export const a = {name: "first", nount: 'asfd'};

function myNewFunc(): void {
	testing();
}

export function main(): void {
	testing();
    myNewFunc();
}

main();

testing.ts

import {a} from "./main";

export function testing(): void {
	console.log(a);
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": ["es2017", "es7", "es6", "dom"],
    "declaration": true,
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true
  },
  "exclude": [
    "node_modules",
    "dist"
  ]
}
  1. open nvim nvim -u minimal_init.lua

  2. Call code action to move to new file

  • move cursor on top of the myNewFunc function name and call :lua vim.lsp.buf.code_action() hit enter
  • select the Move to new file option, (probably this will be the only option present)

Actual behaviour

  1. main.ts get's updated like this
import { myNewFunc } from "./myNewFunc";
import {testing} from "./testing";

export const a = {name: "first", nount: 'asfd'};

export function main(): void {
	testing();
    myNewFunc();
}


main();
  1. it creates an empty file called myNewFunc.ts

Expected behaviour

  1. as above in actual behaviour

  2. the new file should have the following content:

import {testing} from "./testing";

export function myNewFunc(): void {
	testing();
}

I found some more info after bit of debugging,

following is a snippet of the log coming from local _ = log.debug() and log.debug("decoded", decoded) call in runtime/lua/vim/lsp/rpc.lua file.

I noticed end/start character/line all says -1 this could probably throwing the invalid range error, but not sure how to go about fixing it though. I'm happy to work on this if someone can give some pointers on how to tackle it, because I don't have any experience in neovim development or even rpc stuff.

 [
               "file:///home/bm/code/try-lsp/ts/myNewFunc.ts"
            ]"="{
               {
                  "newText =""import { testing } from \"./testing\";\n\nexport function myNewFunc(): void {\n    testing();\n}\n",
                  "range ="{
                     "end ="{
                        character = -1,
                        line = -1
                     },
                     "start ="{
                        character = -1,
                        line = -1
                     }
                  }
               }
            }
         }

closing this issue, because it looks more like tsserver is returning the ranges incorrectly.
And we have a workaround for this issue on the jose-elias-alvarez/nvim-lsp-ts-utils repo.
if anyone wants to use that, it's currently in the develop branch and can use with Plug like below

Plug 'jose-elias-alvarez/nvim-lsp-ts-utils', {'branch': 'develop'}

Can check the issue thread for updates