///
import * as cp from "child_process";
import * as ls from "./languageclient";
import * as atomIde from "atom-ide";
import * as linter from "atom/linter";
import AutocompleteAdapter from "./adapters/autocomplete-adapter";
import * as CallHierarchyAdapter from "./adapters/call-hierarchy-adapter";
import DatatipAdapter from "./adapters/datatip-adapter";
import DefinitionAdapter from "./adapters/definition-adapter";
import FindReferencesAdapter from "./adapters/find-references-adapter";
import LinterPushV2Adapter from "./adapters/linter-push-v2-adapter";
import LoggingConsoleAdapter from "./adapters/logging-console-adapter";
import OutlineViewAdapter from "./adapters/outline-view-adapter";
import SignatureHelpAdapter from "./adapters/signature-help-adapter";
import * as Utils from "./utils";
import { Socket } from "net";
import { LanguageClientConnection } from "./languageclient";
import { Logger } from "./logger";
import { LanguageServerProcess, ActiveServer } from "./server-manager.js";
import { Disposable, Point, Range, TextEditor } from "atom";
import * as ac from "atom/autocomplete-plus";
export { ActiveServer, LanguageClientConnection, LanguageServerProcess };
export declare type ConnectionType = "stdio" | "socket" | "ipc";
export interface ServerAdapters {
linterPushV2: LinterPushV2Adapter;
loggingConsole: LoggingConsoleAdapter;
signatureHelpAdapter?: SignatureHelpAdapter;
}
/**
* Public: AutoLanguageClient provides a simple way to have all the supported Atom-IDE services wired up entirely for
* you by just subclassing it and implementing at least
*
* - `startServerProcess`
* - `getGrammarScopes`
* - `getLanguageName`
* - `getServerName`
*/
export default class AutoLanguageClient {
private _disposable;
private _serverManager;
private _consoleDelegate?;
private _linterDelegate?;
private _signatureHelpRegistry?;
private _lastAutocompleteRequest?;
private _isDeactivating;
private _serverAdapters;
/** Available if consumeBusySignal is setup */
protected busySignalService?: atomIde.BusySignalService;
protected processStdErr: string;
protected logger: Logger;
protected name: string;
protected socket: Socket;
protected autoComplete?: AutocompleteAdapter;
protected callHierarchy?: typeof CallHierarchyAdapter;
protected datatip?: DatatipAdapter;
protected definitions?: DefinitionAdapter;
protected findReferences?: FindReferencesAdapter;
protected outlineView?: OutlineViewAdapter;
/** Return an array of the grammar scopes you handle, e.g. [ 'source.js' ] */
protected getGrammarScopes(): string[];
/** Return the name of the language you support, e.g. 'JavaScript' */
protected getLanguageName(): string;
/** Return the name of your server, e.g. 'Eclipse JDT' */
protected getServerName(): string;
/** Start your server process */
protected startServerProcess(_projectPath: string): LanguageServerProcess | Promise;
/** (Optional) Determine whether we should start a server for a given editor if we don't have one yet */
protected shouldStartForEditor(editor: TextEditor): boolean;
/** (Optional) Return the parameters used to initialize a client - you may want to extend capabilities */
protected getInitializeParams(projectPath: string, lsProcess: LanguageServerProcess): ls.InitializeParams;
/** (Optional) Early wire-up of listeners before initialize method is sent */
protected preInitialization(_connection: LanguageClientConnection): void;
/** (Optional) Late wire-up of listeners after initialize method has been sent */
protected postInitialization(_server: ActiveServer): void;
/** (Optional) Determine whether to use ipc, stdio or socket to connect to the server */
protected getConnectionType(): ConnectionType;
/** (Optional) Return the name of your root configuration key */
protected getRootConfigurationKey(): string;
/** (Optional) Transform the configuration object before it is sent to the server */
protected mapConfigurationObject(configuration: any): any;
/**
* (Optional) Determines the `languageId` string used for `textDocument/didOpen` notification. The default is to use
* the grammar name.
*
* You can override this like this:
*
* class MyLanguageClient extends AutoLanguageClient {
* getLanguageIdFromEditor(editor: TextEditor) {
* if (editor.getGrammar().scopeName === "source.myLanguage") {
* return "myCustumLanguageId"
* }
* return super.getLanguageIdFromEditor(editor)
* }
* }
*
* @param editor A {TextEditor} which is opened.
* @returns A {string} of `languageId` used for `textDocument/didOpen` notification.
*/
protected getLanguageIdFromEditor(editor: TextEditor): string;
/** Gets a LanguageClientConnection for a given TextEditor */
protected getConnectionForEditor(editor: TextEditor): Promise;
/** Restart all active language servers for this language client in the workspace */
protected restartAllServers(): Promise;
/** Activate does very little for perf reasons - hooks in via ServerManager for later 'activation' */
activate(): void;
private exitCleanup;
/** Deactivate disposes the resources we're using */
deactivate(): Promise;
/**
* Spawn a general language server. Use this inside the `startServerProcess` override if the language server is a
* general executable. Also see the `spawnChildNode` method. If the name is provided as the first argument, it checks
* `bin/platform-arch/exeName` by default, and if doesn't exists uses the exe on PATH. For example on Windows x64, by
* passing `serve-d`, `bin/win32-x64/exeName.exe` is spawned by default.
*
* @param exe The `name` or `path` of the executable
* @param args Args passed to spawn the exe. Defaults to `[]`.
* @param options: Child process spawn options. Defaults to `{}`.
* @param rootPath The path of the folder of the exe file. Defaults to `join("bin", `${process.platform}-${process.arch} `)`.
* @param exeExtention The extention of the exe file. Defaults to `process.platform === "win32" ? ".exe" : ""`
*/
protected spawn(exe: string, args?: string[], options?: cp.SpawnOptions, rootPath?: string, exeExtention?: string): LanguageServerProcess;
/**
* Spawn a language server using Atom's Nodejs process Use this inside the `startServerProcess` override if the
* language server is a JavaScript file. Also see the `spawn` method
*/
protected spawnChildNode(args: string[], options?: cp.SpawnOptions): LanguageServerProcess;
/** LSP logging is only set for warnings & errors by default unless you turn on the core.debugLSP setting */
protected getLogger(): Logger;
/** Starts the server by starting the process, then initializing the language server and starting adapters */
private startServer;
private captureServerErrors;
/**
* The function called whenever the spawned server `error`s. Extend (call super.onSpawnError) or override this if you
* need custom error handling
*/
protected onSpawnError(err: Error): void;
/**
* The function called whenever the spawned server `close`s. Extend (call super.onSpawnClose) or override this if you
* need custom close handling
*/
protected onSpawnClose(code: number | null, signal: NodeJS.Signals | null): void;
/**
* The function called whenever the spawned server `disconnect`s. Extend (call super.onSpawnDisconnect) or override
* this if you need custom disconnect handling
*/
protected onSpawnDisconnect(): void;
/**
* The function called whenever the spawned server `exit`s. Extend (call super.onSpawnExit) or override this if you
* need custom exit handling
*/
protected onSpawnExit(code: number | null, signal: NodeJS.Signals | null): void;
/** (Optional) Finds the project path. If there is a custom logic for finding projects override this method. */
protected determineProjectPath(textEditor: TextEditor): string | null;
/**
* The function called whenever the spawned server returns `data` in `stderr` Extend (call super.onSpawnStdErrData) or
* override this if you need custom stderr data handling
*/
protected onSpawnStdErrData(chunk: Buffer, projectPath: string): void;
/** Creates the RPC connection which can be ipc, socket or stdio */
private createRpcConnection;
/** Start adapters that are not shared between servers */
private startExclusiveAdapters;
shouldSyncForEditor(editor: TextEditor, projectPath: string): boolean;
protected isFileInProject(editor: TextEditor, projectPath: string): boolean;
/**
* A method to override to return an array of grammar scopes that should not be used for autocompletion.
*
* Usually that's used for disabling autocomplete inside comments,
*
* @example If the grammar scopes are [ '.source.js' ], `getAutocompleteDisabledScopes` may return [ '.source.js .comment' ].
*/
protected getAutocompleteDisabledScopes(): Array;
provideAutocomplete(): ac.AutocompleteProvider;
protected getSuggestions(request: ac.SuggestionsRequestedEvent): Promise;
protected getSuggestionDetailsOnSelect(suggestion: ac.AnySuggestion): Promise;
protected onDidConvertAutocomplete(_completionItem: ls.CompletionItem, _suggestion: ac.AnySuggestion, _request: ac.SuggestionsRequestedEvent): void;
protected onDidInsertSuggestion(_arg: ac.SuggestionInsertedEvent): void;
provideDefinitions(): atomIde.DefinitionProvider;
protected getDefinition(editor: TextEditor, point: Point): Promise;
provideOutlines(): atomIde.OutlineProvider;
protected getOutline(editor: TextEditor): Promise;
provideCallHierarchy(): atomIde.CallHierarchyProvider;
protected getIncomingCallHierarchy(editor: TextEditor, point: Point): Promise | null>;
protected getOutgoingCallHierarchy(editor: TextEditor, point: Point): Promise | null>;
consumeLinterV2(registerIndie: (params: {
name: string;
}) => linter.IndieDelegate): void;
provideFindReferences(): atomIde.FindReferencesProvider;
protected getReferences(editor: TextEditor, point: Point): Promise;
consumeDatatip(service: atomIde.DatatipService): void;
protected getDatatip(editor: TextEditor, point: Point): Promise;
consumeConsole(createConsole: atomIde.ConsoleService): Disposable;
provideCodeFormat(): atomIde.RangeCodeFormatProvider;
protected getCodeFormat(editor: TextEditor, range: Range): Promise;
provideRangeCodeFormat(): atomIde.RangeCodeFormatProvider;
protected getRangeCodeFormat(editor: TextEditor, range: Range): Promise;
provideFileCodeFormat(): atomIde.FileCodeFormatProvider;
provideOnSaveCodeFormat(): atomIde.OnSaveCodeFormatProvider;
protected getFileCodeFormat(editor: TextEditor): Promise;
provideOnTypeCodeFormat(): atomIde.OnTypeCodeFormatProvider;
protected getOnTypeCodeFormat(editor: TextEditor, point: Point, character: string): Promise;
provideCodeHighlight(): atomIde.CodeHighlightProvider;
protected getCodeHighlight(editor: TextEditor, position: Point): Promise;
provideCodeActions(): atomIde.CodeActionProvider;
protected getCodeActions(editor: TextEditor, range: Range, diagnostics: atomIde.Diagnostic[]): Promise;
/** Optionally filter code action before they're displayed */
protected filterCodeActions(actions: (ls.Command | ls.CodeAction)[] | null): (ls.Command | ls.CodeAction)[] | null;
/**
* Optionally handle a code action before default handling. Return `false` to prevent default handling, `true` to
* continue with default handling.
*/
protected onApplyCodeActions(_action: ls.Command | ls.CodeAction): Promise;
provideRefactor(): atomIde.RefactorProvider;
protected getRename(editor: TextEditor, position: Point, newName: string): Promise