Skip to content

Request handling is problematic with two servers #5854

@rchl

Description

@rchl

Vue - Official extension or vue-tsc version

3.1.8

VSCode version

1.106.3

Vue version

3

TypeScript version

5.9.3

System Info

package.json dependencies

Steps to reproduce

  1. Open https://github.com/vuejs/language-tools/blob/4fbd08748f70feb3c4a41fb908c66c88d277fc4e/test-workspace/tsc/%232588/main.vue
  2. Place cursor somewhere within the v-track:[trackName] text
  3. Invoke "Expand Selection" from command palette in Vscode

What is expected?

That the whole v-track:[trackName] is selected

What is actually happening?

VSCode selects word under the cursor (could vary depending on where the cursor is).

Link to minimal reproduction

No response

Any additional comments?

This is a very specific example that shows just one problem stemming from the fact that given editor request could go to the wrong server (vue or typescript) or go to both which can also give unexpected behavior.

In this specific example the vue server gives the correct answer. Editor makes a request:

textDocument/selectionRange
{
  "positions": [
    {
      "character": 23,
      "line": 1
    }
  ],
  "textDocument": {
    "uri": "file:///usr/local/workspace/github/volarjs/vue/test-workspace/tsc/%232588/main.vue"
  }
}

and server responds correctly with:

[
  {
    "parent": {
      "parent": {
        "parent": {
          "range": {
            "end": {
              "character": 0,
              "line": 2
            },
            "start": {
              "character": 10,
              "line": 0
            }
          }
        },
        "range": {
          "end": {
            "character": 38,
            "line": 1
          },
          "start": {
            "character": 1,
            "line": 1
          }
        }
      },
      "range": {
        "end": {
          "character": 28,
          "line": 1
        },
        "start": {
          "character": 2,
          "line": 1
        }
      }
    },
    "range": {
      "end": {
        "character": 28,
        "line": 1
      },
      "start": {
        "character": 9,
        "line": 1
      }
    }
  }
]

That said, VSCode seems to also also ask typescript language features for answer which returns incorrect result (selecting whole file). So then I think VSCode decides to just expand selection to current word which is unexpected in this case.

As I said, it's not specific to expanding selection. Another example (where things happen to work correctly in VSCode but might not in other editors) is using "rename symbol". For rename symbol to work, the editor has to use result from the Vue server when triggering it in the template block (except inside bindings) but in bindings and script blocks the editor has to use result from the typescript language features.

Whether it works correctly or not depends on editor implementation. VSCode tends to ask all servers for response and then either uses first non-empty response or uses some other heuristics. Other editors might handle things differently - perhaps always asking only the first server.

My point is that relying on editor choosing which server to ask or which to prioritize in a specific place in the file is not reliable.

I'm not sure what vue-language-tools can do about the textDocument/selectionRange requests since VSCode seems to ask all contributors but for textDocument/prepareRename could vue-language-tools decide itself whether to handle it itself or forward to typescript server using tsserver/request (though that would mean that it would have to handle the tsserver response itself instead of relying on typescript-language-features handling)?

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions