vtsls Documentation

repository·main·Indexed 22 days ago

https://github.com/yioneko/vtsls

vtsls is an LSP wrapper for the TypeScript extension bundled with VSCode, designed to provide the same features and performance with minimal patches. It includes the @vtsls/language-server for server execution and @vtsls/language-service for programmatic interaction with TypeScript features. Supported capabilities include navigation, code intelligence, refactoring, and completion. The server allows configuration of TypeScript SDK paths, implicit project settings, CodeLens visibility, and import preferences.

Tokens
8.8K
Snippets
17
Records
38
Agent score
76%

What's inside vtsls

  1. Use @vtsls/language-service to interact with TypeScript

    main

    The @vtsls/language-service package provides a programmatic interface to TypeScript language features. To use it, you must create a service instance, initialize it with configuration, and open text documents before requesting features like documentSymbol. The service follows the Language Server Protocol (LSP) patterns for parameters and responses.

    import { createTSLanguageService } from "@vtsls/language-service";
    const service = createTSLanguageService({
      clientCapabilities: {},
    });
    
    // initialize with configuration
    await service.initialize({
      typescript: { tsserver: { log: "verbose" } },
    });
    
    const uri = "file:///path/to/file.ts";
    const fileContent = "";
    
    // file needs to be opened before requesting features
    service.openTextDocument({
      textDocument: {
        uri,
        languageId: "typescript",
        version: 0,
        text: fileContent,
      },
    });
    
    // see LSP document for the format of params and response
    const response = await service.documentSymbol({ textDocument: { uri } });
    console.log(response);
    
    // close the service
    service.dispose();
  2. Install and run vtsls

    main

    To use the vtsls language server, install it globally via npm and run it using the --stdio flag. This requires Node.js version 16 or higher.

    npm install -g @vtsls/language-server
    vtsls --stdio
  3. Implement Move to File refactor

    main

    The refactor.move.newFile action is disabled by default. To enable it, set vtsls.enableMoveToFileCodeAction to true. This exposes the _typescript.moveToFileRefactoring command.

    Client-side implementation steps:

    1. Prompt the user to select a target destination file.
    2. Append the target file path to the command arguments.
    3. Send the workspace/executeCommand request to the server.

    Command Argument Formats:

    • Initial command arguments: [action: any, uri: DocumentUri, range: Range]
    • Modified arguments (with target): [action: any, uri: DocumentUri, range: Range, targetFile: string]
  4. Configure the TypeScript version

    main

    By default, vtsls uses the latest TypeScript version bundled with the server. You can change this behavior using the following methods:

    1. Use Workspace Version: Use the command typescript.selectTypeScriptVersion or set the configuration option vtsls.autoUseWorkspaceTsdk to true.
    2. Use a Specific Global Path: Set vtsls.typescript.globalTsdk to the path of your preferred TypeScript installation to ignore the bundled version.
    3. Enable Local Plugins: If you need to use plugins installed in your project's node_modules, set typescript.tsserver.pluginPaths = ["./node_modules"].
  5. Manage the lifecycle of `TSLanguageService`

    main

    The TSLanguageService follows a strict lifecycle managed through its exported methods and properties.

    Lifecycle States

    • uninitialized: The state immediately after createTSLanguageService is called but before .initialize() completes.
    • initializing: The state during the .initialize() process (e.g., while the VS Code extension is being activated).
    • initialized: The state after .initialize() has successfully completed. Most LSP request handlers (like hover or definition) will wait for this state before executing.
    • disposed: The state after .dispose() has been called. Once disposed, the service cannot be reused, and the internal singleton reference is cleared.

    Lifecycle Properties

    • initialized: A boolean indicating if the service is in the initialized state.
    • disposed: A boolean indicating if the service has been disposed.

    Lifecycle Methods

    • initialize(config: TSLanguageServiceConfig): Sets up the configuration and activates the underlying TypeScript extension. If called while already initializing, it waits for the current initialization to finish.
    • dispose(): Releases all resources held by the service, including the underlying VS Code extension. This is required to allow creating a new service instance.
    • changeConfiguration(params: DidChangeConfigurationParams): Updates the service configuration. If the service is uninitialized, this triggers the initialize process.
  6. Use FuzzyScore for advanced scoring and matching

    main

    The FuzzyScore type is a specialized array used for internal scoring and tracking match positions. It follows this structure:

    • score: The calculated match score.
    • wordStart: The offset where the matching started in the word.
    • ...matches: A sequence of match positions (from most recent to oldest).

    FuzzyScore.isDefault(score) can be used to check if a score represents a failed match (defaulting to [-100, 0]).

    import { FuzzyScore } from '@vtsls/vscode-fuzzy';
    
    // A typical FuzzyScore might look like this:
    // [score, wordStart, matchPosN, ..., matchPos0]
    const score: FuzzyScore = [10, 0, 5, 2, 1];
    
    if (!FuzzyScore.isDefault(score)) {
      // Handle valid score
    }
  7. Troubleshoot server crashes on large repositories

    main

    If the server crashes or becomes stuck when working on large projects, try the following:

    1. Disable Plugins: TypeScript plugins can consume significant resources. Try disabling them (configured via tsconfig.json or vtsls.tsserver.globalPlugins) to see if stability improves.
    2. Increase Memory Limit: The tsserver process may exhaust RAM. Increase the memory limit by setting typescript.tsserver.maxTsServerMemory to a higher value (e.g., 8192). This value is passed as the --max-old-space-size flag to the underlying Node process.
  8. Optimize completion performance

    main

    If you experience delays during code completion due to a high volume of entries, use these server-side optimizations:

    • Enable Server-Side Fuzzy Matching: Set vtsls.experimental.completion.enableServerSideFuzzyMatch to true. This filters out entries that don't match the user's input before sending them to the client.
    • Limit Completion Entries: Set vtsls.experimental.completion.entriesLimit to cap the number of returned candidates.
    • Exclude Patterns: Use typescript.preferences.autoImportFileExcludePatterns or typescript.preferences.includePackageJsonAutoImports = 'off' to reduce noise.
  9. Configure global TypeScript plugins

    main

    To use a TypeScript plugin that is not installed locally in your project (e.g., for testing or global usage), use the vtsls.tsserver.globalPlugins configuration option.

    Example configuration for styled-components support:

    [
      {
        "name": "@styled/typescript-styled-plugin",
        "location": "/usr/local/lib/node_modules",
        "enableForWorkspaceTypeScriptVersions": true
      }
    ]
  10. Available vtsls Commands

    main

    The server exposes several commands to manage the TypeScript server and perform language actions. Note that some commands require specific arguments as defined below.

    Server Management

    • typescript.openTsServerLog
    • typescript.restartTsServer
    • typescript.reloadProjects
    • javascript.reloadProjects
    • typescript.selectTypeScriptVersion
    • typescript.goToSourceDefinition: [DocumentUri, Position] => Location[]
    • typescript.findAllFileReferences: [DocumentUri] => Location[]
    • typescript.goToProjectConfig: [DocumentUri] => null
    • javascript.goToProjectConfig: [DocumentUri] => null
    • _typescript.configurePlugin: [pluginName: string, config: any] => any
    • typescript.tsserverRequest: [RequestType, args: any, config: any] => any

    Import Management

    • typescript.organizeImports: [filePath: string] => any
    • typescript.sortImports: [filePath: string] => any
    • javascript.sortImports: [filePath: string] => any
    • typescript.removeUnusedImports: [filePath: string] => any
    • javascript.removeUnusedImports: [filePath: string] => any
  11. Configure fuzzy scoring with FuzzyScoreOptions

    main

    When calling low-level scoring functions like fuzzyScore, you can provide FuzzyScoreOptions to tune the matching behavior.

    Available options:

    • firstMatchCanBeWeak: (boolean) If true, allows the first character of the pattern to match a non-ideal position in the word.
    • boostFullMatch: (boolean) If true, provides a score boost if the pattern matches the word exactly.
    import { FuzzyScoreOptions } from '@vtsls/vscode-fuzzy';
    
    const options = new FuzzyScoreOptions(true, true);
    // firstMatchCanBeWeak: true, boostFullMatch: true
  12. Configure Import Organization (Advanced)

    main

    Advanced settings for the organizeImports command to control how imports are sorted.

    • caseSensitivity: auto, caseInsensitive, or caseSensitive.
    • typeOrder: Controls where type only imports are placed: auto, last, inline, or first.
    • unicodeCollation: Use ordinal or unicode sorting.
    • numericCollation: (Requires unicode) Sort numeric strings by integer value.
    • accentCollation: (Requires unicode) Compare characters with diacritics as unequal to base characters.
    • caseFirst: (Requires unicode and not caseInsensitive) Set order to default, upper, or lower.