Skip to content
/ ltex-ls Public
forked from valentjn/ltex-ls

LTeX Language Server: An LSP language server for LanguageTool with LaTeX/Markdown support; core of the LTeX extension for Visual Studio Code

License

Notifications You must be signed in to change notification settings

ed359/ltex-ls

 
 

Repository files navigation

LTEX LS — LTEX Language Server

version numberrelease date

vscode-ltex  CI status  stars  open issues closed issues
ltex-ls  CI status  coverage  stars  open issues closed issues

LTEX LS (LTEX Language Server) implements a language server according to the Language Server Protocol (LSP) and provides grammar and spelling errors in markup documents (LATEX, Markdown, etc.). The documents are checked with LanguageTool.

Simply put, you start the language server (either locally or remotely), you send the language server your LATEX or Markdown document, and it will respond with a list of the grammar and spelling errors in it. To use LTEX LS, you have to use a language client (usually an editor or an extension of the editor) that communicates with LTEX LS according to the LSP.

The reference client of LTEX LS is the LTEX extension for Visual Studio Code (vscode-ltex), whose development LTEX LS follows closely and vice versa.

Find more information about LTEX at the website of vscode-ltex.

Features

  • Supported markup languages: BibTEX, LATEX, Markdown, Org, reStructuredText, R Sweave
  • Comes with everything included, no need to install Java or LanguageTool
  • Offline checking: Does not upload anything to the internet
  • Supports over 20 languages: English, French, German, Dutch, Chinese, Russian, etc.
  • Issue highlighting with hover description
  • Replacement suggestions via quick fixes
  • User dictionaries
  • Multilingual support with babel commands or magic comments
  • Possibility to use external LanguageTool servers
  • Extensive documentation of reference client

Current List of Language Clients

In order to use LTEX LS, you need a language client. For some editors, language clients are already available, see the following list. If your editor is in the list, read the installation instructions of the language client first; it might download LTEX LS automatically or tell you where to store LTEX LS. The rest of this document is only relevant if you want to implement your own language client.

Requirements

  • 64-bit operating system
  • Java 11 or later
  • Language client supporting LSP 3.15 or later

Installation

  1. Download the latest release from GitHub.
  2. Extract the archive to an arbitrary location on your computer.

Startup

It is recommended to use the startup scripts bin/ltex-ls (Linux, Mac) and bin\ltex-ls.bat (Windows) to start LTEX LS. These scripts are only part of the released versions. The startup scripts can be controlled by the following environment variables:

  • JAVA_HOME: Path to the directory of the JRE or JDK to use (contains bin, lib, and other subdirectories)
  • JAVA_OPTS: Java arguments to be fed to java (e.g., -Xmx1024m)

You can also start LTEX LS directly without the startup scripts (not recommended). In this case, make sure that when supplying all JAR files in the lib directory to Java's class path, ltexls-languagetool-patch-LTEXLSVERSION.jar is listed as the first JAR file (where LTEXLSVERSION is the version of LTEX LS; Java's class path does not support wildcards in the middle of filenames). It does not suffice to supply lib/* to the class path, as the order in which the JAR files are included in wildcards is not specified by Java, so this will fail randomly. The startup scripts take care of this peculiarity.

Command-Line Options

Any command-line arguments supplied to the startup scripts are processed by LTEX LS itself. The options are as follows:

  • --[no-]endless: Keep the server alive when the client terminates the connection to allow reuse by the next client.
  • -h, --help: Show help message and exit.
  • --host=<host>: Listen for TCP connections on host <host> (IP address or hostname; default is localhost). Only relevant if server type is tcpSocket.
  • --port=<port>: Listen for TCP connections on port <port>. Only relevant if server type is tcpSocket. A value of 0 (default) will have the system automatically determine a free port (the actual port number will be printed to the log).
  • --server-type=<serverType>: Run the server as type <serverType>. Valid values are:
    • standardStream (default): Communicate with clients over standard input and standard output.
    • tcpSocket: Communicate with clients over a TCP socket.
  • -V, --version: Print version information as JSON to the standard output and exit. The format is a JSON object with "java" and "ltex-ls" keys and string values. A key may be missing if no information about the corresponding version could be retrieved.

Instead of using the equals sign = to separate option names and values, it is also possible to use one or more spaces.

Checking Documents with the LSP

Once started, the language server may be used according to the Language Server Protocol (LSP) to check documents.

Communication with the server is by default via standard input and standard output (except when the server type is tcpSocket). Logging messages are always printed to the standard error output.

Settings

See the website of vscode-ltex for a list of all supported settings.

Note that some settings listed on the linked page are client-specific and do not affect LTEX LS.

Quick fixes

  • quickfix.ltex.acceptSuggestions: Replace the text of the diagnostic with the specified suggestion.
  • quickfix.ltex.addToDictionary: Trigger the _ltex.addToDictionary command.
  • quickfix.ltex.disableRules: Trigger the _ltex.disableRules command.
  • quickfix.ltex.hideFalsePositives: Trigger the _ltex.hideFalsePositives command.

Commands

Some commands are handled by LTEX LS, while others must be handled by the language client. This is in contrast to the LSP specification, which recommends that the server handles all commands. However, handling of some commands by the client is necessary as these commands change the client configuration, which the LSP does not allow server-side.

All commands are prefixed with _ltex. during usage. The purpose of the leading underscore is that in some clients, commands are directly exposed to the user of the client (e.g., for assigning keyboard shortcuts), which is not desirable for internal commands that require arguments. The leading underscore signals that the commands are internal.

As arguments, all commands take an array with exactly one element, whose type is specified by the respective CommandParams interface.

The result of all commands handled by the client is null.

The result of all commands handled by the server implements at least the following interface:

interface ServerCommandResult {
  /**
   * Whether the command was executed successfully.
   */
  success: boolean;

  /**
   * Optional error message if `success` is `false`.
   */
  errorMessage?: string;
}

_ltex.addToDictionary (Client)

_ltex.addToDictionary is executed by the client when it should add words to the dictionary by adding them to ltex.dictionary.

interface AddToDictionaryCommandParams {
  /**
   * URI of the document.
   */
  uri: string;

  /**
   * Words to add to the dictionary, specified as lists of strings by language.
   */
  words: {
    [language: string]: string[];
  };
}

type AddToDictionaryCommandResult = null;

_ltex.disableRules (Client)

_ltex.disableRules is executed by the client when it should disable rules by adding the rule IDs to ltex.disabledRules.

interface DisableRulesCommandParams {
  /**
   * URI of the document.
   */
  uri: string;

  /**
   * IDs of the LanguageTool rules to disable, specified as lists of strings by language.
   */
  ruleIds: {
    [language: string]: string[];
  };
}

type DisableRulesCommandResult = null;

_ltex.hideFalsePositives (Client)

_ltex.hideFalsePositives is executed by the client when it should hide false positives by adding them to ltex.hiddenFalsePositives.

interface HideFalsePositivesCommandParams {
  /**
   * URI of the document.
   */
  uri: string;

  /**
   * False positives to hide, specified as lists of JSON strings by language.
   */
  falsePositives: {
    [language: string]: string[];
  };
}

type HideFalsePositivesCommandResult = null;

_ltex.checkDocument (Server)

_ltex.checkDocument is executed by the server to trigger the check of a specific document. The result will be sent to the client with a textDocument/publishDiagnostics notification.

interface CheckDocumentCommandParams {
  /**
   * URI of the document.
   */
  uri: string;

  /**
   * Code language ID of the document (e.g., `latex`). Will be determined by the file extension
   * of `uri` if missing.
   */
  codeLanguageId?: string;

  /**
   * Text to check. Will be determined as the contents of the file at `uri` if missing.
   */
  text?: string;

  /**
   * Range inside `text` (or the contents of the file at `uri` if missing) if only a part
   * of the document should be checked. Will be set to the range spanning all of `text` if missing.
   */
  range?: Range;
}

type CheckDocumentCommandResult = ServerCommandResult;

_ltex.getServerStatus (Server)

_ltex.getServerStatus is executed by the server to return information about the current resource consumption of LTEX LS. Some information might not be available.

type GetServerStatusCommandParams = null;

interface GetServerStatusCommandResult extends ServerCommandResult {
  /**
   * Process ID of the Java process.
   */
  processId: number;

  /**
   * Wall-clock duration in seconds since the start of LTeX LS.
   */
  wallClockDuration: number;

  /**
   * Current CPU usage as a fraction between 0 and 1.
   */
  cpuUsage?: number;

  /**
   * Duration in seconds during which the CPU was occupied.
   */
  cpuDuration?: number;

  /**
   * Memory in bytes of all currently allocated Java objects (this is a part of `totalMemory`).
   */
  usedMemory: number;

  /**
   * Total memory in bytes currently taken by the JVM.
   */
  totalMemory: number;

  /**
   * Whether LTeX LS is currently busy checking text.
   */
  isChecking: boolean;

  /**
   * URI of the document currently being checked.
   * This field may still be missing even if `isChecking` is true.
   */
  documentUriBeingChecked?: string;
}

Custom LSP Extensions

LTEX LS supports the following custom features that are not specified by the LSP:

  • Custom initialization options
  • Custom requests and notifications

To use custom LSP extensions, the client has to pass a CustomInitializationOptions object to the InitializeParams.initializationOptions field when sending the initialize request. If no such object is passed, LTEX LS will fall back to an LSP-compliant mode and not use any custom LSP extensions.

Custom Initialization Options

Custom initialization options are directly specified in the fields of a CustomInitializationOptions object defined as follows:

interface CustomInitializationOptions {
  /**
   * Locale of UI messages (strings that are sent to the client and that are meant to be
   * displayed in the user interface of the client), specified as an IETF BCP 47 language tag.
   *
   * Logging messages are always in English. Diagnostic messages are always in the language of
   * the checked text they belong to.
   *
   * If not specified, the default locale of the JVM will be used. If the specified locale
   * cannot be resolved to a supported i18n language of LTeX LS, then English will be used.
   */
  locale?: string;

  /**
   * Capabilities for custom requests and notifications.
   */
  customCapabilities?: CustomCapabilities;
}

interface CustomCapabilities {
  /**
   * Whether `ltex/workspaceSpecificConfiguration` requests are supported.
   */
  workspaceSpecificConfiguration?: boolean;
}

Custom Requests and Notifications

Support for custom server-to-client requests and notifications has to be announced by setting the value that corresponds to the name of the custom request or notification in CustomInitializationOptions.customCapabilities to true. Client-to-server requests and notifications are always enabled.

All custom requests and notifications are prefixed with ltex/ during usage.

ltex/workspaceSpecificConfiguration (⮎)

ltex/workspaceSpecificConfiguration is a server-to-client request. Parameters and result are exactly like workspace/configuration (i.e., ConfigurationParams and any[], respectively).

If enabled, LTEX LS will not only send a workspace/configuration request to the client every time a document is checked, but also an ltex/workspaceSpecificConfiguration request. Some settings used for the check are then taken from the result of the ltex/workspaceSpecificConfiguration request instead of the workspace/configuration request. These settings are:

The reason of the existence of ltex/workspaceSpecificConfiguration is that some clients like VS Code have different configuration scopes (e.g., user and workspace). When a configuration like ltex.dictionary appears in multiple scopes, the value in the scope with the higher precedence will override the other values (e.g., workspace scope will override user scope). ltex/workspaceSpecificConfiguration makes it possible for the client to implement a merging mechanism instead, without having to change workspace/configuration.

About

LTeX Language Server: An LSP language server for LanguageTool with LaTeX/Markdown support; core of the LTeX extension for Visual Studio Code

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 98.9%
  • Python 1.1%