### Setup lightning-language-server Repository Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Installs dependencies and links the language server. This is a necessary step after cloning the repository. ```bash cd lightning-language-server yarn install yarn link-lsp ``` -------------------------------- ### Setup salesforcedx-vscode Repository Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Installs dependencies, links the language server, and compiles the Salesforce VSCode Extensions project. This must be done in conjunction with setting up the language server repository. ```bash cd ../salesforcedx-vscode npm install npm run link-lsp npm run compile ``` -------------------------------- ### Project Configuration Example for Tern Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt An example of a `.tern-project` file showcasing common configuration options. It includes specifying libraries to load (`libs`), files to eagerly load (`loadEagerly`), and plugin configurations. ```application/json { "libs": [ "browser", "jquery" ], "loadEagerly": [ "importantfile.js" ], "plugins": { "requirejs": { "baseURL": "./", "paths": {} } } } ``` -------------------------------- ### Start LWC Language Server (Node.js) Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt Initializes and starts the LWC language server as a standalone Node.js process, communicating via LSP. It can be run directly from the command line or after global installation. ```javascript #!/usr/bin/env node require('../lib/server.js'); ``` ```bash # Start the LWC language server from command line node node_modules/@salesforce/lwc-language-server/bin/lwc-language-server.js --stdio # Or install globally and run npm install -g @salesforce/lwc-language-server lwc-language-server --stdio ``` -------------------------------- ### Install, Build, and Test Packages with Yarn Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/lwc-language-server/CONTRIBUTING.md These commands are used to manage the project's dependencies and build process. 'yarn install' downloads and installs all required packages. 'yarn build' compiles the TypeScript source code into JavaScript. 'yarn test' executes the project's test suite. ```sh yarn install # Install necessary packages yarn build # Compile typescript code to javascript yarn test # Run the test ``` -------------------------------- ### Start Aura Language Server (Node.js) Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt Initializes and starts the Aura language server for Aura component development, communicating via LSP. It can be executed from the command line or after global installation. ```javascript #!/usr/bin/env node require('../lib/server.js'); ``` ```bash # Start the Aura language server from command line node node_modules/@salesforce/aura-language-server/bin/aura-language-server.js --stdio # Or install globally and run npm install -g @salesforce/aura-language-server aura-language-server --stdio ``` -------------------------------- ### Tern Server Command-Line Interface Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt This section details the command-line flags supported when starting the Tern server. ```APIDOC ## Tern Server Command-Line Flags The `bin/tern` script starts the Tern server. The following command-line flags are supported: ### `--port ` Specify a port to listen on, instead of the default behavior of letting the OS pick a random unused port. ### `--host ` Specify a host to listen on. Defaults to `127.0.0.1`. Pass `null` or `any` to listen on all available hosts. ### `--persistent` By default, the server will shut itself down after five minutes of inactivity. Pass this option to disable auto-shutdown. ### `--ignore-stdin` By default, the server will close when its standard input stream is closed. Pass this flag to disable that behavior. ### `--verbose` Will cause the server to spit out information about the requests and responses that it handles, and any errors that are raised. Useful for debugging. ### `--no-port-file` The server won't write a `.tern-port` file. Can be used if the port files are a problem for you. Will prevent other clients from finding the server (and may thus result in multiple servers for the same project). ``` -------------------------------- ### Get Documentation Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Retrieves the documentation string and URL for a given expression at a specified location. ```APIDOC ## POST /documentation ### Description Get the documentation string and URL for a given expression, if any. ### Method POST ### Endpoint /documentation ### Parameters #### Request Body - **file** (string) - Required - The file containing the expression. - **end** (number | {line: number, ch: number}) - Required - The end position of the expression. - **start** (number | {line: number, ch: number}) - Optional - The start position of the expression. - **variable** (string) - Optional - A variable name to use instead of an expression in the code. - **docFormat** (string) - Optional - "full" to get the full documentation string with newlines intact. - **lineCharPositions** (boolean) - Optional - If true, returned offsets will be in {line, ch} format. ### Request Example ```json { "file": "/path/to/your/file.js", "end": {"line": 15, "ch": 10} } ``` ### Response #### Success Response (200) - **doc** (string) - Optional - The documentation string. - **url** (string) - Optional - The URL associated with the documentation. - **origin** (string) - Optional - The origin of the documentation. #### Response Example ```json { "doc": "Detailed explanation of the function.", "url": "http://example.com/docs" } ``` ``` -------------------------------- ### Multi-Module Loader Wrapper Example Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/demo/index.html Demonstrates a common pattern for defining modules that can be loaded using different module loaders like CommonJS, AMD, or as plain browser variables. Tern's plugins can handle these different module systems. ```javascript // This one is written using a multi-module-loader wrapper // // If Tern's requirejs plugin is loaded, it'll pick up the // call to define. Alternatively, when its commonjs plugin // is loaded, that'll handle the require calls. (function(root, mod) { if (typeof exports == "object" && typeof module == "object") mod(exports, require("jquery")) // CommonJS else if (typeof define == "function" && define.amd) define(["exports", "jquery"], mod) // AMD else mod(root.output = {}, root.$) // Plain browser env })(this, function(exports, $) { // Write some text to the bottom of the document exports.write = function(text) { $("body").append($("
").text(text)) } }) ``` -------------------------------- ### Enable Auto Recompile on Change Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Starts watch processes for both the lightning-language-server and salesforcedx-vscode repositories to automatically recompile on code changes. ```bash cd ../lightning-language-server yarn watch cd ../salesforcedx-vscode npm run watch ``` -------------------------------- ### JSON Type Definition Example Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt An example of a JSON file used to define types for a library. It specifies global variables, object properties, function signatures, and type aliases. Properties prefixed with '!' have special meanings. ```json { "!name": "mylibrary", "!define": { "point": { "x": "number", "y": "number" } }, "MyConstructor": { "!type": "fn(arg: string)", "staticFunction": "fn() -> bool", "prototype": { "property": "[number]", "clone": "fn() -> +MyConstructor", "getPoint": "fn(i: number) -> point" } }, "someOtherGlobal": "string" } ``` -------------------------------- ### Emacs Tern Auto-Complete Setup Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Configuration for integrating Tern with the auto-complete.el package in Emacs. This enables automatic completion when typing '.' and allows manual invocation. ```commonlisp (eval-after-load 'tern '(progn (require 'tern-auto-complete) (tern-ac-setup))) ``` -------------------------------- ### Index and Query Aura Components with AuraIndexer Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt This snippet demonstrates how to use the AuraIndexer to index and query Aura components, events, and interfaces. It covers configuring the indexer, performing indexing, retrieving all Aura tags, getting specific components by tag name, listing namespaces, and listening for indexer events (additions and deletions). Dependencies include '@salesforce/aura-language-server/indexer' and '@salesforce/aura-language-server/context'. ```typescript import AuraIndexer from '@salesforce/aura-language-server/indexer'; import { AuraWorkspaceContext } from '@salesforce/aura-language-server/context'; import { TagInfo } from '@salesforce/lightning-lsp-common'; // Create workspace context and indexer const context = new AuraWorkspaceContext(['/path/to/workspace']); const indexer = new AuraIndexer(context); // Configure and index all Aura components await indexer.configureAndIndex(); // Wait for indexing to complete await indexer.waitForIndexing(); // Get all Aura component tags const auraTags: Map = indexer.getAuraTags(); console.log(`Found ${auraTags.size} Aura components`); // Get specific component by tag name const componentTag: TagInfo = indexer.getAuraByTag('c:myComponent'); if (componentTag) { console.log('Component name:', componentTag.name); console.log('Namespace:', componentTag.namespace); console.log('Attributes:', componentTag.attributes); console.log('Documentation:', componentTag.documentation); } // Get all registered namespaces const namespaces: string[] = indexer.getAuraNamespaces(); console.log('Available namespaces:', namespaces); // Listen for indexer events indexer.eventEmitter.on('set', (tag: TagInfo) => { console.log('Component added:', tag.name); }); indexer.eventEmitter.on('delete', (tagName: string) => { console.log('Component deleted:', tagName); }); ``` -------------------------------- ### Properties API Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Get a list of all known object property names. ```APIDOC ## GET /properties ### Description Get a list of all known object property names (for any object). ### Method GET ### Endpoint /properties ### Parameters #### Query Parameters - **prefix** (string) - Optional - If provided, only return properties that start with this string. - **sort** (boolean) - Optional - Whether the result should be sorted. Defaults to true. ### Response #### Success Response (200) - **completions** (array) - An array of strings representing the property names. #### Response Example ```json { "completions": [ "property1", "property2", "anotherProperty" ] } ``` ``` -------------------------------- ### Get Definition Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Retrieves the definition of a variable, property, or type at a specified location in a file. It can also provide context and documentation related to the definition. ```APIDOC ## POST /definition ### Description Asks for the definition of something. This will try, for a variable or property, to return the point at which it was defined. If that fails, or the chosen expression is not an identifier or property reference, it will try to return the definition site of the type the expression has. If no type is found, or the type is not an object or function (other types don’t store their definition site), it will fail to return useful information. ### Method POST ### Endpoint /definition ### Parameters #### Request Body - **file** (string) - Required - The file in which the definition was defined, or a reference like "#N". - **end** (number | {line: number, ch: number}) - Required - The end position of the expression. - **start** (number | {line: number, ch: number}) - Optional - The start position of the expression to disambiguate. - **variable** (string) - Optional - A variable name to use instead of an expression in the code. - **docFormat** (string) - Optional - "full" to get the full documentation string with newlines intact. - **lineCharPositions** (boolean) - Optional - If true, returned offsets will be in {line, ch} format. ### Request Example ```json { "file": "/path/to/your/file.js", "end": {"line": 10, "ch": 5}, "start": {"line": 10, "ch": 2} } ``` ### Response #### Success Response (200) - **start** (number | {line: number, ch: number}) - Optional - The start position of the definition. - **end** (number | {line: number, ch: number}) - Optional - The end position of the definition. - **file** (string) - Optional - The file in which the definition was defined. - **context** (string) - Optional - A slice of the code in front of the definition. - **contextOffset** (number) - Optional - The offset from the start of the context to the actual definition. - **doc** (string) - Optional - The documentation string. - **url** (string) - Optional - The URL associated with the definition. - **origin** (string) - Optional - The origin of the definition. #### Response Example ```json { "start": 50, "end": 75, "file": "/path/to/definitions.js", "doc": "This is a function that does X." } ``` ``` -------------------------------- ### AST Expression Navigation (JavaScript) Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Provides functions to find expressions within an Abstract Syntax Tree (AST) based on start and end positions. It supports exact matches, spanning ranges, and closest expressions, returning the AST node and its associated scope. Dependencies include an AST structure and optional scope objects. ```javascript infer.findExpressionAt(ast: AST, start?: number, end: number, scope?: Scope) → {node, state} infer.findExpressionAround(ast: AST, start?: number, end: number, scope?: Scope) → {node, state} infer.findClosestExpression(ast: AST, start?: number, end: number, scope?: Scope) → {node, state} ``` -------------------------------- ### Server Constructor and Options Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Details on how to create a server instance and the configuration options available. ```APIDOC ## Server Constructor and Configuration ### Description The base server is implemented in `lib/tern.js` and exposes a `Server` constructor. This constructor accepts an object with configuration options to initialize the server. ### Method `new Server(options)` ### Parameters #### Request Body (Options Object) - **defs** (array of strings) - The definition objects to load into the server's environment. - **plugins** (object) - Specifies the set of plugins to load, with property names as plugin names and values as their options. - **ecmaVersion** (number) - The ECMAScript version to parse (5 or 6). Defaults to 6. - **getFile** (function) - A function to fetch file content. It can be synchronous (returns string) or asynchronous (takes a callback). - **async** (bool) - Indicates if `getFile` is asynchronous. Defaults to `false`. - **fetchTimeout** (number) - Maximum milliseconds to wait for an asynchronous `getFile`. Defaults to 1000. ### Request Example ```json { "defs": ["browser", "ecma6"], "plugins": { "node": {} }, "ecmaVersion": 6, "async": true } ``` ### Response (N/A - Constructor returns a server instance) ``` -------------------------------- ### Server Constructor Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Creates a new server instance with configurable options for definitions, plugins, ECMAScript version, file fetching, and asynchronous behavior. ```APIDOC ## Server Constructor ### Description Initializes a new server instance with specified configuration options. ### Method `new Server(options)` ### Parameters #### Request Body - **defs** (array of strings) - Optional - The definition objects to load into the server's environment. - **plugins** (object) - Optional - Specifies the set of plugins the server should load. Property names are plugin names, and values are options passed to them. - **ecmaVersion** (number) - Optional - The ECMAScript version to parse. Should be 5 or 6. Default is 6. - **getFile** (function) - Optional - A function to fetch file content. Signature depends on the `async` option. - **async** (boolean) - Optional - Indicates if `getFile` is asynchronous. Default is `false`. - **fetchTimeout** (number) - Optional - Maximum milliseconds to wait for an asynchronous `getFile`. Defaults to 1000. ### Request Example ```json { "defs": ["definitions.json"], "plugins": { "pluginA": {"option": "value"} }, "ecmaVersion": 6, "async": true, "fetchTimeout": 2000 } ``` ### Response #### Success Response (200) - **ServerInstance** (object) - An instance of the server. #### Response Example ```json { "server": "[Server Instance]" } ``` ``` -------------------------------- ### Open Project in VS Code Workspace Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Opens both the lightning-language-server and salesforcedx-vscode repositories in a VS Code workspace. Choose 'multiroot-simple.code-workspace' or 'multiroot-flat.code-workspace' depending on the desired Explorer view. ```bash cd ../lightning-language-server code ./vscode-workspaces/multiroot-simple.code-workspace # or code ./vscode-workspaces/multiroot-flat.code-workspace ``` -------------------------------- ### Clone Git Repositories for Development Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Clones the lightning-language-server and salesforcedx-vscode repositories. These projects need to be cloned into the same parent directory for development. ```bash git clone git@github.com:forcedotcom/lightning-language-server.git git clone git@github.com:forcedotcom/salesforcedx-vscode.git ``` -------------------------------- ### Getting Object Properties by Name Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Retrieves an `AVal` representing a specific property of a type. This method is used to introspect the properties of object types. ```javascript type.getProp(prop: string) → AVal ``` -------------------------------- ### Create LWC Language Server Instance (TypeScript) Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt Programmatically creates and configures an LWC language server instance with full LSP capabilities. This involves instantiating the server and initializing it with workspace parameters and client capabilities. ```typescript import Server from '@salesforce/lwc-language-server/server'; import { InitializeParams, InitializeResult } from 'vscode-languageserver'; // Create a new server instance const server = new Server(); // Initialize the server with workspace configuration const initParams: InitializeParams = { processId: process.pid, rootUri: 'file:///path/to/workspace', workspaceFolders: [ { uri: 'file:///path/to/workspace', name: 'my-sfdx-project' } ], capabilities: { workspace: { workspaceFolders: true }, textDocument: { completion: { completionItem: { snippetSupport: true } } } } }; // Initialize returns server capabilities server.onInitialize(initParams).then((result: InitializeResult) => { console.log('Server capabilities:', result.capabilities); // Output includes: completionProvider, hoverProvider, definitionProvider }); // Start listening for LSP connections server.connection.listen(); ``` -------------------------------- ### Editor Plugins Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Instructions and details for integrating the language server with various text editors, including Emacs and Vim. ```APIDOC ## Editor Plugins If your editor of choice is not yet supported, you are encouraged to try and port one of the existing plugins to it. When figuring out things, the code powering the demo, in `doc/demo/demo.js`, might also come in useful. All these plugins use the [node.js](http://nodejs.org)-based server, and thus require that (as well as [npm](http://npmjs.org)) to be installed. ### Emacs The Emacs mode is part of the main tern [repository](https://github.com/ternjs/tern). It can be installed as follows: 1. Make sure you are using Emacs 24 or later. The Tern mode requires lexical scoping. 2. Clone this repository somewhere. Do `npm install` to get the dependencies. 3. Make Emacs aware of `emacs/tern.el`. For example by adding this to your `.emacs` file: ```elisp (add-to-list 'load-path "/path/to/tern/emacs/") (autoload 'tern-mode "tern.el" nil t) ``` 4. Optionally set `tern-mode` to be automatically enabled for your JavaScript mode of choice. Here’s the snippet for `js-mode`: ```elisp (add-hook 'js-mode-hook (lambda () (tern-mode t))) ``` The Emacs mode uses the `bin/tern` server, and project configuration is done with a [`.tern-project`](#project_file) file. Buffers in `tern-mode` add a `completion-at-point` function that activates Tern’s completion. So, unless you rebound the key, `M-tab` (or `C-M-i`) will trigger completion. When the point is in an argument list, Tern will show argument names and types at the bottom of the screen. The following additional keys are bound: * `M-.`: Jump to the definition of the thing under the cursor. * `M-,`: Brings you back to last place you were when you pressed `M-`. * `C-c C-r`: Rename the variable under the cursor. * `C-c C-c`: Find the type of the thing under the cursor. * `C-c C-d`: Find docs of the thing under the cursor. Press again to open the associated URL (if any). #### Auto-Complete If you want to use `auto-complete.el` for completion, append following codes: ```elisp (eval-after-load 'tern '(progn (require 'tern-auto-complete) (tern-ac-setup))) ``` If `tern-ac-on-dot` is non-nil (default), typing `.`(dot) invokes auto-complete to select completions. Calling the command `tern-ac-complete`, one can invoke auto-complete manually. ### Vim The Vim plugin is maintained in a [separate repository](https://github.com/ternjs/tern_for_vim). Please see its README for details. ``` -------------------------------- ### Getting Function Types from AVals Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html The `getFunctionType()` method specifically checks if an AVal contains a function type, ignoring other type kinds. This is useful when only function types are of interest. ```javascript const functionType = aval.getFunctionType(); ``` -------------------------------- ### RequireJS Module Loading and Definition Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/demo/index.html Illustrates how Tern handles modules loaded with RequireJS and defines custom modules. It shows a main script that loads 'text_util' and 'output' modules, and a definition for the 'text_util' module itself. ```javascript // A simple set of three modules, connected with requirejs requirejs(["text_util", "output"], function(text, output) { window.addEventListener("load", function() { // Pressing alt-. on `garble` jumps to the module var word = text.capitalize(text.garble(prompt("Hi", ""))) output.write(word) }) }) // Trivial requirejs-style module define(function() { return { // Capitalize a string capitalize: function(word) { return word.charAt(0).toUpperCase() + word.slice(1) }, // Garble the vowels in a string garble: function(word) { return word.replace(/[auiyoe]/g, function() { return "auiyoe".charAt(Math.floor(Math.random() * 6)) }) } } }) ``` -------------------------------- ### Expression: Get Type Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Determines the type of a given AST expression node and its associated scope. Returns either an AVal or a plain Type object representing the expression's type. ```javascript infer.expressionType(expr: {node, state}) → AVal ``` -------------------------------- ### Get Prototype of Tern Object Type Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Retrieves the prototype of a Tern object type. Returns `null` if the object type has no prototype. This property is specific to object types created using `infer.Obj`. ```javascript obj.proto ``` -------------------------------- ### Create Component Metadata with TagInfo Objects Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt This snippet illustrates how to create and manage component metadata using TagInfo objects, essential for indexing and code intelligence. It shows the creation of attribute information and full component tag metadata, along with retrieving specific attribute details and generating hover documentation. Key functions used are from '@salesforce/lightning-lsp-common' and '@salesforce/lightning-lsp-common/indexer/attributeInfo'. ```typescript import { createTagInfo, getAttributeInfo, getHover, TagType } from '@salesforce/lightning-lsp-common'; import { createAttributeInfo } from '@salesforce/lightning-lsp-common/indexer/attributeInfo'; import { Location } from 'vscode-languageserver'; // Create attribute information const attributes = [ createAttributeInfo( 'label', 'string', 'The label text to display', false, { uri: 'file:///path/to/component.js', range: { start: { line: 5, character: 0 }, end: { line: 5, character: 20 } } } ), createAttributeInfo( 'disabled', 'boolean', 'Whether the component is disabled', false ) ]; // Create component tag metadata const tagInfo = createTagInfo( '/path/to/component/myComponent.js', 'CUSTOM' as TagType, true, // is LWC component attributes, { uri: 'file:///path/to/component/myComponent.js', range: { start: { line: 0, character: 0 }, end: { line: 50, character: 0 } } } as Location, 'A custom Lightning Web Component for displaying data', 'myComponent', 'c' ); // Get specific attribute information const labelAttr = getAttributeInfo(tagInfo, 'label'); if (labelAttr) { console.log('Attribute:', labelAttr.name); console.log('Type:', labelAttr.type); console.log('Description:', labelAttr.documentation); } // Generate hover documentation const hoverText = getHover(tagInfo); console.log(hoverText); // Output: Full markdown documentation with attributes and methods ``` -------------------------------- ### Getting Types from AVals Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html The `getType(guess?)` method retrieves the current type(s) from an AVal. It returns `null` if no type or conflicting types are present. With `guess: true`, it attempts to infer a type heuristically from propagation edges. ```javascript const currentType = aval.getType(); const guessedType = aval.getType(true); ``` -------------------------------- ### Implement Go-to-Definition for LWC Components Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt Handles LSP definition requests to navigate from a component's usage in code to its definition file. It parses the component tag at the cursor position and returns the URI and range of the component's definition. Dependencies include `vscode-languageserver` and `@salesforce/lwc-language-server/tag`. ```typescript import { TextDocumentPositionParams, Location, Definition } from 'vscode-languageserver'; import { getTagUri } from '@salesforce/lwc-language-server/tag'; server.connection.onDefinition(async (params: TextDocumentPositionParams): Promise => { const document = server.documents.get(params.textDocument.uri); if (!document) { return null; } const offset = document.offsetAt(params.position); const text = document.getText(); // Parse component tag at cursor position const tagMatch = /<(c-[\w-]+)/.exec(text.substring(offset - 20, offset + 20)); if (!tagMatch) { return null; } const tagName = tagMatch[1]; const tag = server.componentIndexer.findTagByName(tagName); if (!tag) { return null; } // Return location of component definition const location: Location = { uri: getTagUri(tag), range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } } }; return location; }); ``` -------------------------------- ### AVal: Get Function Type Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Checks if an AVal represents a function type. Useful when you only need to know if a type is a function, ignoring other type information. AVals can have an 'originNode' property pointing to the AST node they represent. ```javascript aval.getFunctionType() → Type? ``` -------------------------------- ### Getting the Current Type from an AVal Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Requests the current type(s) held by an `AVal`. May return `null` if the `AVal` is empty or has conflicting types. If `guess` is true, an empty `AVal` may use heuristics to suggest a type. ```javascript aval.getType(guess?: bool) → Type? ``` -------------------------------- ### RequireJS Plugin Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Documentation for the RequireJS plugin is not provided in the input text. -------------------------------- ### AST: Find Expression Around Range Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Finds the innermost AST expression node that spans a given range (start and end offsets). Similar to findExpressionAt but returns the closest spanning expression. Optionally accepts a scope to override the default. ```javascript infer.findExpressionAround(ast: AST, start: number?, end: number, scope?: Scope) → {node, state} ``` -------------------------------- ### Use Common Utilities for Path Resolution and File Operations (TypeScript) Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt This snippet showcases the usage of utility functions from '@salesforce/lightning-lsp-common/utils'. It demonstrates path resolution relative to a workspace, checking if a directory is relevant for LWC watching, detecting workspace types (SFDX, CORE_ALL, CORE_PARTIAL), measuring elapsed time for operations, and synchronously reading/writing JSON files. ```typescript import { toResolvedPath, isLWCWatchedDirectory, detectWorkspaceType, elapsedMillis, readJsonSync, writeJsonSync } from '@salesforce/lightning-lsp-common/utils'; // Resolve paths relative to workspace const resolvedPath = toResolvedPath('/workspace/root', 'force-app/main/default/lwc'); console.log('Resolved path:', resolvedPath); // Check if directory should be watched for LWC changes const shouldWatch = isLWCWatchedDirectory('/workspace/force-app/main/default/lwc/myComponent'); if (shouldWatch) { console.log('This is an LWC component directory'); } // Detect workspace type const type = detectWorkspaceType('/path/to/project'); console.log('Workspace type:', type); // 'SFDX', 'CORE_ALL', or 'CORE_PARTIAL' // Measure elapsed time const startTime = process.hrtime(); // ... perform operation ... const elapsed = elapsedMillis(startTime); console.log(`Operation completed in ${elapsed}ms`); // Read and write JSON files synchronously const config = readJsonSync('/path/to/config.json'); console.log('Config:', config); writeJsonSync('/path/to/output.json', { key: 'value' }); console.log('JSON written successfully'); ``` -------------------------------- ### Purge Types by Origin in Tern Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Removes types from the context that originate from a specified list of origins. Optional `start` and `end` parameters can limit the purging to a specific range within the source code. This is useful for managing type precision during incremental analysis. ```javascript infer.purgeTypes(origins: [string], start?: number, end?: number) ``` -------------------------------- ### On-Demand NPM Publish Workflow Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Manually triggers the 'Manual Release' GitHub Actions workflow to publish changes to npm. This is done from the 'Actions' tab of the repository. ```bash # Navigate to the Actions tab in the repository # Select 'Manual Release' under Workflows # Select 'Run Workflow' and ensure the newest version is published ``` -------------------------------- ### AST: Find Expression at Position Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Searches an AST for an expression ending at a specific offset, optionally starting at a given offset. Allows overriding the default scope. Returns a {node, state} object containing the AST node and its associated scope, or null if not found. ```javascript infer.findExpressionAt(ast: AST, start: number?, end: number, scope?: Scope) → {node, state} ``` -------------------------------- ### Configure and Manage LWC Workspace Context Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt Configures and manages workspace-specific settings and TypeScript support for the LWC language server. It detects the workspace type (SFDX, CORE_ALL, CORE_PARTIAL), configures project structure, checks for TypeScript support, and provides access to package directories and the project root. Dependencies include `@salesforce/lwc-language-server/context` and `@salesforce/lightning-lsp-common`. ```typescript import { LWCWorkspaceContext } from '@salesforce/lwc-language-server/context'; import { detectWorkspaceType, WorkspaceType } from '@salesforce/lightning-lsp-common'; // Create workspace context const workspaceRoots = ['/path/to/sfdx-project']; const context = new LWCWorkspaceContext(workspaceRoots); // Detect workspace type (SFDX, CORE_ALL, CORE_PARTIAL) const workspaceType: WorkspaceType = detectWorkspaceType(workspaceRoots[0]); console.log('Workspace type:', workspaceType); // Configure project structure await context.configureProject(); // Check if TypeScript support is enabled const hasTsSupport = await context.hasTypescriptSupport(); if (hasTsSupport) { // Configure TypeScript settings await context.configureProjectForTs(); console.log('TypeScript support enabled'); } // Get SFDX package directories const packageDirs = context.getPackageDirectories(); console.log('Package directories:', packageDirs); // Access project root const projectRoot = context.workspaceRoots[0]; console.log('Project root:', projectRoot); ``` -------------------------------- ### Implement Hover Information for LWC Components Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt Provides rich hover documentation for LWC components and their attributes when hovering over them in the editor. It finds the component tag at the cursor and uses `@salesforce/lightning-lsp-common` to generate Markdown-formatted documentation. Dependencies include `vscode-languageserver` and `@salesforce/lightning-lsp-common`. ```typescript import { TextDocumentPositionParams, Hover, MarkupContent, MarkupKind } from 'vscode-languageserver'; import { getHover } from '@salesforce/lightning-lsp-common'; server.connection.onHover(async (params: TextDocumentPositionParams): Promise => { const document = server.documents.get(params.textDocument.uri); if (!document) { return null; } const offset = document.offsetAt(params.position); const text = document.getText(); // Find component tag at cursor const tagMatch = /<(c-[\w-]+)/.exec(text.substring(offset - 20, offset + 20)); if (!tagMatch) { return null; } const tagName = tagMatch[1]; const tag = server.componentIndexer.findTagByName(tagName); if (!tag || !tag.tagInfo) { return null; } // Generate hover documentation const documentation = getHover(tag.tagInfo, false); return { contents: { kind: MarkupKind.Markdown, value: documentation } as MarkupContent, range: { start: params.position, end: params.position } }; }); ``` -------------------------------- ### Initializing Tern Context Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Demonstrates the constructor for Tern's context object. The 'defs' parameter should be an array of type definition objects used to initialize the global scope of the context. This context is crucial for the type inference process. ```javascript const context = infer.Context(defs: [object]); ``` -------------------------------- ### Debug Language Server in VS Code Source: https://github.com/forcedotcom/lightning-language-server/blob/main/README.md Launches the debugger in VS Code to attach to the language server. Use the 'Launch DX - Aura & LWC' configuration from the debug view. ```bash # Run 'Launch DX - Aura & LWC' from the VSCode debug view ``` -------------------------------- ### Creating Empty Abstract Values Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Constructor for `AVal` objects, which represent sets of types. An empty `AVal` is created initially and types are added to it. ```javascript infer.AVal() ``` -------------------------------- ### Documentation API Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt Retrieve documentation strings and URLs for a given expression in a file. ```APIDOC ## GET /documentation ### Description Get the documentation string and URL for a given expression, if any. ### Method GET ### Endpoint /documentation ### Parameters #### Query Parameters - **file** (string) - Required - The name of the file or a reference to a file (e.g., "#N"). - **end** ({line: number, ch: number} | number) - Required - The end offset of the expression. - **start** ({line: number, ch: number} | number) - Optional - The start offset of the expression to disambiguate. - **docFormat** (string) - Optional - Specifies the format of the documentation string. Use "full" to get the complete string with newlines intact. - **variable** (string) - Optional - Specifies a variable name to look for instead of an expression in the code. ### Response #### Success Response (200) - **doc** (string) - Optional - The documentation string. - **url** (string) - Optional - The URL associated with the documentation. - **origin** (string) - Optional - The origin of the definition or value. #### Response Example ```json { "doc": "This is the documentation string.", "url": "http://example.com", "origin": "definition" } ``` ``` -------------------------------- ### Server Methods Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Available methods for interacting with the Tern server, including file management, requests, and event handling. ```APIDOC ## Server Methods ### Description Provides methods to manage files, perform requests, flush analysis, handle events, and manage definitions within the Tern server. ### Methods #### `addFile(name: string, text?: string, parent?: string)` - **Description**: Registers a file with the server. Can also be used to automatically load a dependency by specifying the parent file. - **Parameters**: - `name` (string) - The name of the file. - `text` (string, optional) - The content of the file. - `parent` (string, optional) - The name of the parent file for dependency tracking. #### `delFile(name: string)` - **Description**: Unregisters a file from the server. - **Parameters**: - `name` (string) - The name of the file to unregister. #### `request(doc: object, callback: fn(error, response))` - **Description**: Performs a request to the server. The `doc` should be a parsed JSON document according to the protocol documentation. The `callback` handles the response or error. - **Parameters**: - `doc` (object) - The request document. - `callback` (function) - The callback function for handling the response. #### `flush(callback: fn())` - **Description**: Forces all files to be fetched and analyzed, then calls the provided callback. - **Parameters**: - `callback` (function) - The callback to execute after flushing. #### `on(eventType: string, handler: fn())` - **Description**: Registers an event handler for a specific event type. - **Parameters**: - `eventType` (string) - The name of the event to listen for. - `handler` (function) - The function to execute when the event is fired. #### `off(eventType: string, handler: fn())` - **Description**: Unregisters an event handler. - **Parameters**: - `eventType` (string) - The name of the event. - `handler` (function) - The handler function to remove. #### `addDefs(defs: object, atFront?: bool)` - **Description**: Adds a set of type definitions to the server. Definitions can be added at the front or back. - **Parameters**: - `defs` (object) - The type definitions to add. - `atFront` (boolean, optional) - If true, adds definitions at the front; otherwise, at the back. #### `deleteDefs(name: string)` - **Description**: Deletes a set of type definitions by name. - **Parameters**: - `name` (string) - The name of the definition set to delete. #### `loadPlugin(name: string, options?: object)` - **Description**: Loads a server plugin. Does nothing if the plugin is already loaded. - **Parameters**: - `name` (string) - The name of the plugin to load. - `options` (object, optional) - Options to pass to the plugin. ``` -------------------------------- ### String Completion Plugin Configuration (JavaScript) Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.html Gathers short strings from code to provide completion suggestions within strings. It accepts a 'maxLength' option to limit the length of strings to gather, defaulting to 15 characters. ```javascript string_completion: { maxLength: 20 } ``` -------------------------------- ### Implement LWC Code Completion with LWC Language Server Source: https://context7.com/forcedotcom/lightning-language-server/llms.txt This snippet details the implementation of code completion for LWC templates and JavaScript using the LWC language server. It shows how to handle LSP completion requests, retrieve document content, and provide context-aware completions, including custom component tags. Dependencies include '@salesforce/lwc-language-server/server' and 'vscode-languageserver'. ```typescript import Server from '@salesforce/lwc-language-server/server'; import { CompletionParams, CompletionItem, CompletionList } from 'vscode-languageserver'; const server = new Server(); // Handle completion requests server.connection.onCompletion(async (params: CompletionParams): Promise => { const document = server.documents.get(params.textDocument.uri); if (!document) { return { isIncomplete: false, items: [] }; } // Get cursor position const offset = document.offsetAt(params.position); const text = document.getText(); // Provide completions based on context const completionItems: CompletionItem[] = []; // Example: Component tag completions const customComponents = server.componentIndexer.customData; for (const tag of customComponents) { completionItems.push({ label: `c-${tag.name}`, kind: 10, // CompletionItemKind.Value documentation: tag.documentation, insertText: `<\/c-${tag.name}>`, detail: `Custom component from ${tag.file}` }); } return { isIncomplete: false, items: completionItems }; }); // Handle completion resolve for additional details server.connection.onCompletionResolve((item: CompletionItem): CompletionItem => { // Add additional documentation or details return item; }); ``` -------------------------------- ### Configure RequireJS Plugin for Tern Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/manual.txt This snippet demonstrates how to configure the RequireJS plugin in a `.tern-project` file. It enables RequireJS-style dependency management by specifying the plugin and its options, such as baseURL and paths, to help Tern resolve module dependencies and their types. ```application/json { "plugins": { "requirejs": { "baseURL": "./", "paths": {} } } } ``` -------------------------------- ### JavaScript Autocomplete and Type Inference Demo Source: https://github.com/forcedotcom/lightning-language-server/blob/main/packages/aura-language-server/src/tern/doc/demo/index.html Demonstrates Tern's autocompletion and type inference capabilities in JavaScript. Users can trigger completions with Ctrl+Space and find types with Ctrl+I. It also shows variable renaming with Ctrl+Q. ```javascript // Use ctrl-space to complete something co document.body.a // Put the cursor in or after an expression, press ctrl-i to // find its type var foo = ["array", "of", "strings"] var bar = foo.slice(0, 2).join("").split("a")[0] // Works for locally defined types too. function CTor() { this.size = 10 } CTor.prototype.hallo = "hallo" var baz = new CTor baz. // You can press ctrl-q when the cursor is on a variable // name to rename it. Try it with CTor... // When the cursor is in an argument list, the arguments // are shown below the editor. [1].reduce( ) ```