Skip to content
/ goxlsw Public

Go+ Language Server that runs in the browser using WebAssembly

License

Notifications You must be signed in to change notification settings

goplus/goxlsw

Repository files navigation

goxlsw

Build Status Go Report Card GitHub release Coverage Status GoDoc

A lightweight Go+ language server that runs in the browser using WebAssembly.

This project follows the Language Server Protocol (LSP) using JSON-RPC 2.0 for message exchange. However, unlike traditional LSP implementations that require a network transport layer, this project operates directly in the browser's memory space through its API interfaces.

Difference between goxls and goxlsw

  • goxls runs locally, while goxlsw runs in the browser using WebAssembly.
  • goxls supports a workspace (multiple projects), while goxlsw supports a single project.
  • goxls supports mixed programming of Go and Go+, while goxlsw only supports a pure Go+ project.

Building from source

  1. Generate required package data:
GODEBUG=gotypesalias=1 go generate ./internal/pkgdata
  1. Build the project:
GOOS=js GOARCH=wasm GODEBUG=gotypesalias=1 go build -trimpath -o spxls.wasm

Usage

This project is a standard Go WebAssembly module. You can use it like any other Go WASM modules in your web applications.

For detailed API references, please check the index.d.ts file.

Supported LSP methods

Category Method Purpose & Explanation
Lifecycle Management
initialize Performs initial handshake, establishes server capabilities and client configuration.
initialized Marks completion of initialization process, enabling request processing.
shutdown Protocol conformance only.
exit Protocol conformance only.
Document Synchronization
textDocument/didOpen Registers new document in server state and triggers initial diagnostics.
textDocument/didChange Synchronizes document content changes between client and server.
textDocument/didSave Processes document save events and triggers related operations.
textDocument/didClose Removes document from server state and cleans up resources.
Code Intelligence
textDocument/hover Shows types and documentation at cursor position.
textDocument/completion Generates context-aware code suggestions.
textDocument/signatureHelp Shows function/method signature information.
Symbols & Navigation
textDocument/declaration Finds symbol declarations.
textDocument/definition Locates symbol definitions across workspace.
textDocument/typeDefinition Navigates to type definitions of variables/fields.
textDocument/implementation Locates implementations.
textDocument/references Finds all references of a symbol.
textDocument/documentHighlight Highlights other occurrences of selected symbol.
textDocument/documentLink Provides clickable links within document content.
Code Quality
textDocument/publishDiagnostics Reports code errors and warnings in real-time.
textDocument/diagnostic Pulls diagnostics for documents on request (pull model).
workspace/diagnostic Pulls diagnostics for all workspace documents on request.
Code Modification
textDocument/formatting Applies standardized formatting rules to document.
textDocument/prepareRename Validates renaming possibility and returns valid range for the operation.
textDocument/rename Performs consistent symbol renaming across workspace.
Semantic Features
textDocument/semanticTokens/full Provides semantic coloring for whole document.
Other
workspace/executeCommand Executes predefined commands for workspace-specific operations.

Predefined commands

Resource renaming

The spx.renameResources command enables renaming of resources referenced by string literals (e.g., play "explosion") across the workspace.

Request:

interface ExecuteCommandParams {
  /**
   * The identifier of the actual command handler.
   */
  command: 'spx.renameResources'

  /**
   * Arguments that the command should be invoked with.
   */
  arguments: SpxRenameResourceParams[]
}
/**
 * Parameters to rename an spx resource in the workspace.
 */
interface SpxRenameResourceParams {
  /**
   * The spx resource.
   */
  resource: SpxResourceIdentifier

  /**
   * The new name of the spx resource.
   */
  newName: string
}
/**
 * The spx resource's identifier.
 */
interface SpxResourceIdentifier {
  /**
   * The spx resource's URI.
   */
  uri: SpxResourceUri
}
/**
 * The spx resource's URI.
 *
 * @example
 * - `spx://resources/sounds/MySound`
 * - `spx://resources/sprites/MySprite`
 * - `spx://resources/sprites/MySprite/costumes/MyCostume`
 * - `spx://resources/sprites/MySprite/animations/MyAnimation`
 * - `spx://resources/backdrops/MyBackdrop`
 * - `spx://resources/widgets/MyWidget`
 */
type SpxResourceUri = string

Response:

  • result: WorkspaceEdit | null describing the modification to the workspace. null should be treated the same as WorkspaceEdit with no changes (no change was required).
  • error: code and message set in case when rename could not be performed for any reason.

Definition lookup

The spx.getDefinitions command retrieves definition identifiers at a given position in a document.

Request:

interface ExecuteCommandParams {
  /**
   * The identifier of the actual command handler.
   */
  command: 'spx.getDefinitions'

  /**
   * Arguments that the command should be invoked with.
   */
  arguments: SpxGetDefinitionsParams[]
}
/**
 * Parameters to get definitions at a specific position in a document.
 */
interface SpxGetDefinitionsParams extends TextDocumentPositionParams {}

Response:

  • result: SpxDefinitionIdentifier[] | null describing the definitions found at the given position. null indicates no definitions were found.
  • error: code and message set in case when definitions could not be retrieved for any reason.
interface SpxDefinitionIdentifier {
  /**
   * Full name of source package.
   * If not provided, it's assumed to be kind-statement.
   * If `main`, it's the current user package.
   * Examples:
   * - `fmt`
   * - `github.com/goplus/spx`
   * - `main`
   */
  package?: string;

  /**
   * Exported name of the definition.
   * If not provided, it's assumed to be kind-package.
   * Examples:
   * - `Println`
   * - `Sprite`
   * - `Sprite.turn`
   * - `for_statement_with_single_condition`
   */
  name?: string;

  /** Overload Identifier.. */
  overloadId?: string;
}

Other JSON structures

Document link data types

/**
 * The data of an spx resource reference DocumentLink.
 */
interface SpxResourceRefDocumentLinkData {
  /**
   * The kind of the spx resource reference.
   */
  kind: SpxResourceRefKind
}
/**
 * The kind of the spx resource reference.
 *
 * - stringLiteral: String literal as a resource-reference, e.g., `play "explosion"`
 * - autoBinding: Auto-binding variable as a resource-reference, e.g., `var explosion Sound`
 * - autoBindingReference: Reference for auto-binding variable as a resource-reference, e.g., `play explosion`
 * - constantReference: Reference for constant as a resource-reference, e.g., `play EXPLOSION` (`EXPLOSION` is a constant)
 */
type SpxResourceRefKind = 'stringLiteral' | 'autoBinding' | 'autoBindingReference' | 'constantReference'