Skip to content

goplus/xgolsw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xgolsw

Build Status Go Report Card GitHub release Coverage Status GoDoc

A lightweight XGo 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 xgols and xgolsw

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

Building from source

  1. [Optional] Generate required package data:
go generate ./internal/pkgdata
  1. Build the project:
GOOS=js GOARCH=wasm 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.
textDocument/inlayHint Provides inline hints such as parameter names and type annotations.
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.

Input slots lookup

The spx.getInputSlots command retrieves all modifiable items (input slots) in a document, which can be used to provide UI controls for assisting users with code modifications.

Request:

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

  /**
   * Arguments that the command should be invoked with.
   */
  arguments: [SpxGetInputSlotsParams]
}
/**
 * Parameters to get input slots in a document.
 */
interface SpxGetInputSlotsParams {
  /**
   * The text document identifier.
   */
  textDocument: TextDocumentIdentifier
}

Response:

  • result: SpxInputSlot[] | null describing the input slots found in the document. null indicates no input slots were found.
  • error: code and message set in case when input slots could not be retrieved for any reason.
/**
 * Represents a modifiable item in the code.
 */
interface SpxInputSlot {
  /**
   * Kind of the slot.
   * - Value: Modifiable values that can be replaced with different values.
   * - Address: Modifiable operation objects that can be replaced with user-defined objects.
   */
  kind: SpxInputSlotKind

  /**
   * Info describing what inputs are accepted by the slot.
   */
  accept: SpxInputSlotAccept

  /**
   * Current input in the slot.
   */
  input: SpxInput

  /**
   * Names for available user-predefined identifiers.
   */
  predefinedNames: string[]

  /**
   * Range in code for the slot.
   */
  range: Range
}
/**
 * The kind of input slot.
 */
enum SpxInputSlotKind {
  /**
   * The slot accepts value, which may be an in-place value or a predefined identifier.
   * For example: `123` in `println 123`.
   */
  Value = 'value',

  /**
   * The slot accepts address, which must be a predefined identifier.
   * For example: `x` in `x = 123`.
   */
  Address = 'address'
}
/**
 * Info about what inputs are accepted by a slot.
 */
type SpxInputSlotAccept =
  | {
      /**
       * Input type accepted by the slot.
       */
      type:
        | SpxInputType.Integer
        | SpxInputType.Decimal
        | SpxInputType.String
        | SpxInputType.Boolean
        | SpxInputType.SpxDirection
        | SpxInputType.SpxColor
        | SpxInputType.SpxEffectKind
        | SpxInputType.SpxKey
        | SpxInputType.SpxPlayAction
        | SpxInputType.SpxSpecialObj
        | SpxInputType.SpxRotationStyle
        | SpxInputType.Unknown
    }
  | {
      /**
       * Input type accepted by the slot.
       */
      type: SpxInputType.SpxResourceName
      /**
       * Resource context.
       */
      resourceContext: SpxResourceContextURI
    }
/**
 * The type of input for a slot.
 */
enum SpxInputType {
  /**
   * Integer number values.
   */
  Integer = 'integer',

  /**
   * Decimal number values.
   */
  Decimal = 'decimal',

  /**
   * String values.
   */
  String = 'string',

  /**
   * Boolean values.
   */
  Boolean = 'boolean',

  /**
   * Resource name (`SpriteName`, `SoundName`, etc.) in spx.
   */
  SpxResourceName = 'spx-resource-name',

  /**
   * Direction values in spx.
   */
  SpxDirection = 'spx-direction',

  /**
   * Color values in spx.
   */
  SpxColor = 'spx-color',

  /**
   * Effect kind values in spx.
   */
  SpxEffectKind = 'spx-effect-kind',

  /**
   * Keyboard key values in spx.
   */
  SpxKey = 'spx-key',

  /**
   * Sound playback action values in spx.
   */
  SpxPlayAction = 'spx-play-action',

  /**
   * Special object values in spx.
   */
  SpxSpecialObj = 'spx-special-obj',

  /**
   * Rotation style values in spx.
   */
  SpxRotationStyle = 'spx-rotation-style',

  /**
   * Unknown type.
   */
  Unknown = 'unknown'
}
/**
 * Name for color constructors.
 */
type SpxInputTypeSpxColorConstructor = 'HSB' | 'HSBA'
/**
 * Input value with type information.
 */
type SpxInputTypedValue =
  | { type: SpxInputType.Integer; value: number }
  | { type: SpxInputType.Decimal; value: number }
  | { type: SpxInputType.String; value: string }
  | { type: SpxInputType.Boolean; value: boolean }
  | { type: SpxInputType.SpxResourceName; value: ResourceURI }
  | { type: SpxInputType.SpxDirection; value: number }
  | {
      type: SpxInputType.SpxColor
      value: {
        /**
         * Constructor for color.
         */
        constructor: SpxInputTypeSpxColorConstructor
        /**
         * Arguments passed to the constructor.
         */
        args: number[]
      }
    }
  | { type: SpxInputType.SpxEffectKind; value: string }
  | { type: SpxInputType.SpxKey; value: string }
  | { type: SpxInputType.SpxPlayAction; value: string }
  | { type: SpxInputType.SpxSpecialObj; value: string }
  | { type: SpxInputType.SpxRotationStyle; value: string }
  | { type: SpxInputType.Unknown; value: void }
/**
 * URI of the resource context. Examples:
 * - `spx://resources/sprites`
 * - `spx://resources/sounds`
 * - `spx://resources/sprites/<sName>/costumes`
 */
type SpxResourceContextURI = string
/**
 * Represents the current input in a slot.
 */
type SpxInput<T extends SpxInputTypedValue = SpxInputTypedValue> =
  | {
      /**
       * In-place value
       * For example: `"hello world"`, `123`, `true`, spx `Left`, spx `HSB(0,0,0)`
       */
      kind: SpxInputKind.InPlace

      /**
       * Type of the input.
       */
      type: T['type']

      /**
       * In-place value.
       */
      value: T['value']
    }
  | {
      /**
       * (Reference to) user predefined identifier
       * For example: var `costume1`, const `name2`, field `num3`
       */
      kind: SpxInputKind.Predefined

      /**
       * Type of the input.
       */
      type: T['type']

      /**
       * Name for user predefined identifer.
       */
      name: string
    }
/**
 * The kind of input.
 */
enum SpxInputKind {
  /**
   * In-place value
   * For example: `"hello world"`, `123`, `true`, spx `Left`, spx `HSB(0,0,0)`
   */
  InPlace = 'in-place',

  /**
   * (Reference to) user predefined identifier
   * For example: var `costume1`, const `name2`, field `num3`
   */
  Predefined = 'predefined'
}

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'

Completion item data types

/**
 * The data of a completion item.
 */
interface CompletionItemData {
  /**
   * The corresponding definition of the completion item.
   */
  definition?: SpxDefinitionIdentifier
}
/**
 * The identifier of a definition.
 */
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/v2`
   * - `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;
}

About

Go+ Language Server that runs in the browser using WebAssembly

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 6

Languages