UNPKG

13.7 kBTypeScriptView Raw
1/// <reference types="node" />
2import * as cp from "child_process";
3import * as ls from "./languageclient";
4import * as atomIde from "atom-ide";
5import * as linter from "atom/linter";
6import AutocompleteAdapter from "./adapters/autocomplete-adapter";
7import * as CallHierarchyAdapter from "./adapters/call-hierarchy-adapter";
8import DatatipAdapter from "./adapters/datatip-adapter";
9import DefinitionAdapter from "./adapters/definition-adapter";
10import FindReferencesAdapter from "./adapters/find-references-adapter";
11import LinterPushV2Adapter from "./adapters/linter-push-v2-adapter";
12import LoggingConsoleAdapter from "./adapters/logging-console-adapter";
13import OutlineViewAdapter from "./adapters/outline-view-adapter";
14import SignatureHelpAdapter from "./adapters/signature-help-adapter";
15import * as Utils from "./utils";
16import { Socket } from "net";
17import { LanguageClientConnection } from "./languageclient";
18import { Logger } from "./logger";
19import { LanguageServerProcess, ActiveServer } from "./server-manager.js";
20import { Disposable, Point, Range, TextEditor } from "atom";
21import * as ac from "atom/autocomplete-plus";
22export { ActiveServer, LanguageClientConnection, LanguageServerProcess };
23export declare type ConnectionType = "stdio" | "socket" | "ipc";
24export interface ServerAdapters {
25 linterPushV2: LinterPushV2Adapter;
26 loggingConsole: LoggingConsoleAdapter;
27 signatureHelpAdapter?: SignatureHelpAdapter;
28}
29/**
30 * Public: AutoLanguageClient provides a simple way to have all the supported Atom-IDE services wired up entirely for
31 * you by just subclassing it and implementing at least
32 *
33 * - `startServerProcess`
34 * - `getGrammarScopes`
35 * - `getLanguageName`
36 * - `getServerName`
37 */
38export default class AutoLanguageClient {
39 private _disposable;
40 private _serverManager;
41 private _consoleDelegate?;
42 private _linterDelegate?;
43 private _signatureHelpRegistry?;
44 private _lastAutocompleteRequest?;
45 private _isDeactivating;
46 private _serverAdapters;
47 /** Available if consumeBusySignal is setup */
48 protected busySignalService?: atomIde.BusySignalService;
49 protected processStdErr: string;
50 protected logger: Logger;
51 protected name: string;
52 protected socket: Socket;
53 protected autoComplete?: AutocompleteAdapter;
54 protected callHierarchy?: typeof CallHierarchyAdapter;
55 protected datatip?: DatatipAdapter;
56 protected definitions?: DefinitionAdapter;
57 protected findReferences?: FindReferencesAdapter;
58 protected outlineView?: OutlineViewAdapter;
59 /** Return an array of the grammar scopes you handle, e.g. [ 'source.js' ] */
60 protected getGrammarScopes(): string[];
61 /** Return the name of the language you support, e.g. 'JavaScript' */
62 protected getLanguageName(): string;
63 /** Return the name of your server, e.g. 'Eclipse JDT' */
64 protected getServerName(): string;
65 /** Start your server process */
66 protected startServerProcess(_projectPath: string): LanguageServerProcess | Promise<LanguageServerProcess>;
67 /** (Optional) Determine whether we should start a server for a given editor if we don't have one yet */
68 protected shouldStartForEditor(editor: TextEditor): boolean;
69 /** (Optional) Return the parameters used to initialize a client - you may want to extend capabilities */
70 protected getInitializeParams(projectPath: string, lsProcess: LanguageServerProcess): ls.InitializeParams;
71 /** (Optional) Early wire-up of listeners before initialize method is sent */
72 protected preInitialization(_connection: LanguageClientConnection): void;
73 /** (Optional) Late wire-up of listeners after initialize method has been sent */
74 protected postInitialization(_server: ActiveServer): void;
75 /** (Optional) Determine whether to use ipc, stdio or socket to connect to the server */
76 protected getConnectionType(): ConnectionType;
77 /** (Optional) Return the name of your root configuration key */
78 protected getRootConfigurationKey(): string;
79 /** (Optional) Transform the configuration object before it is sent to the server */
80 protected mapConfigurationObject(configuration: any): any;
81 /**
82 * (Optional) Determines the `languageId` string used for `textDocument/didOpen` notification. The default is to use
83 * the grammar name.
84 *
85 * You can override this like this:
86 *
87 * class MyLanguageClient extends AutoLanguageClient {
88 * getLanguageIdFromEditor(editor: TextEditor) {
89 * if (editor.getGrammar().scopeName === "source.myLanguage") {
90 * return "myCustumLanguageId"
91 * }
92 * return super.getLanguageIdFromEditor(editor)
93 * }
94 * }
95 *
96 * @param editor A {TextEditor} which is opened.
97 * @returns A {string} of `languageId` used for `textDocument/didOpen` notification.
98 */
99 protected getLanguageIdFromEditor(editor: TextEditor): string;
100 /** Gets a LanguageClientConnection for a given TextEditor */
101 protected getConnectionForEditor(editor: TextEditor): Promise<LanguageClientConnection | null>;
102 /** Restart all active language servers for this language client in the workspace */
103 protected restartAllServers(): Promise<void>;
104 /** Activate does very little for perf reasons - hooks in via ServerManager for later 'activation' */
105 activate(): void;
106 private exitCleanup;
107 /** Deactivate disposes the resources we're using */
108 deactivate(): Promise<any>;
109 /**
110 * Spawn a general language server. Use this inside the `startServerProcess` override if the language server is a
111 * general executable. Also see the `spawnChildNode` method. If the name is provided as the first argument, it checks
112 * `bin/platform-arch/exeName` by default, and if doesn't exists uses the exe on PATH. For example on Windows x64, by
113 * passing `serve-d`, `bin/win32-x64/exeName.exe` is spawned by default.
114 *
115 * @param exe The `name` or `path` of the executable
116 * @param args Args passed to spawn the exe. Defaults to `[]`.
117 * @param options: Child process spawn options. Defaults to `{}`.
118 * @param rootPath The path of the folder of the exe file. Defaults to `join("bin", `${process.platform}-${process.arch} `)`.
119 * @param exeExtention The extention of the exe file. Defaults to `process.platform === "win32" ? ".exe" : ""`
120 */
121 protected spawn(exe: string, args?: string[], options?: cp.SpawnOptions, rootPath?: string, exeExtention?: string): LanguageServerProcess;
122 /**
123 * Spawn a language server using Atom's Nodejs process Use this inside the `startServerProcess` override if the
124 * language server is a JavaScript file. Also see the `spawn` method
125 */
126 protected spawnChildNode(args: string[], options?: cp.SpawnOptions): LanguageServerProcess;
127 /** LSP logging is only set for warnings & errors by default unless you turn on the core.debugLSP setting */
128 protected getLogger(): Logger;
129 /** Starts the server by starting the process, then initializing the language server and starting adapters */
130 private startServer;
131 private captureServerErrors;
132 /**
133 * The function called whenever the spawned server `error`s. Extend (call super.onSpawnError) or override this if you
134 * need custom error handling
135 */
136 protected onSpawnError(err: Error): void;
137 /**
138 * The function called whenever the spawned server `close`s. Extend (call super.onSpawnClose) or override this if you
139 * need custom close handling
140 */
141 protected onSpawnClose(code: number | null, signal: NodeJS.Signals | null): void;
142 /**
143 * The function called whenever the spawned server `disconnect`s. Extend (call super.onSpawnDisconnect) or override
144 * this if you need custom disconnect handling
145 */
146 protected onSpawnDisconnect(): void;
147 /**
148 * The function called whenever the spawned server `exit`s. Extend (call super.onSpawnExit) or override this if you
149 * need custom exit handling
150 */
151 protected onSpawnExit(code: number | null, signal: NodeJS.Signals | null): void;
152 /** (Optional) Finds the project path. If there is a custom logic for finding projects override this method. */
153 protected determineProjectPath(textEditor: TextEditor): string | null;
154 /**
155 * The function called whenever the spawned server returns `data` in `stderr` Extend (call super.onSpawnStdErrData) or
156 * override this if you need custom stderr data handling
157 */
158 protected onSpawnStdErrData(chunk: Buffer, projectPath: string): void;
159 /** Creates the RPC connection which can be ipc, socket or stdio */
160 private createRpcConnection;
161 /** Start adapters that are not shared between servers */
162 private startExclusiveAdapters;
163 shouldSyncForEditor(editor: TextEditor, projectPath: string): boolean;
164 protected isFileInProject(editor: TextEditor, projectPath: string): boolean;
165 /**
166 * A method to override to return an array of grammar scopes that should not be used for autocompletion.
167 *
168 * Usually that's used for disabling autocomplete inside comments,
169 *
170 * @example If the grammar scopes are [ '.source.js' ], `getAutocompleteDisabledScopes` may return [ '.source.js .comment' ].
171 */
172 protected getAutocompleteDisabledScopes(): Array<string>;
173 provideAutocomplete(): ac.AutocompleteProvider;
174 protected getSuggestions(request: ac.SuggestionsRequestedEvent): Promise<ac.AnySuggestion[]>;
175 protected getSuggestionDetailsOnSelect(suggestion: ac.AnySuggestion): Promise<ac.AnySuggestion | null>;
176 protected onDidConvertAutocomplete(_completionItem: ls.CompletionItem, _suggestion: ac.AnySuggestion, _request: ac.SuggestionsRequestedEvent): void;
177 protected onDidInsertSuggestion(_arg: ac.SuggestionInsertedEvent): void;
178 provideDefinitions(): atomIde.DefinitionProvider;
179 protected getDefinition(editor: TextEditor, point: Point): Promise<atomIde.DefinitionQueryResult | null>;
180 provideOutlines(): atomIde.OutlineProvider;
181 protected getOutline(editor: TextEditor): Promise<atomIde.Outline | null>;
182 provideCallHierarchy(): atomIde.CallHierarchyProvider;
183 protected getIncomingCallHierarchy(editor: TextEditor, point: Point): Promise<atomIde.CallHierarchy<"incoming"> | null>;
184 protected getOutgoingCallHierarchy(editor: TextEditor, point: Point): Promise<atomIde.CallHierarchy<"outgoing"> | null>;
185 consumeLinterV2(registerIndie: (params: {
186 name: string;
187 }) => linter.IndieDelegate): void;
188 provideFindReferences(): atomIde.FindReferencesProvider;
189 protected getReferences(editor: TextEditor, point: Point): Promise<atomIde.FindReferencesReturn | null>;
190 consumeDatatip(service: atomIde.DatatipService): void;
191 protected getDatatip(editor: TextEditor, point: Point): Promise<atomIde.Datatip | null>;
192 consumeConsole(createConsole: atomIde.ConsoleService): Disposable;
193 provideCodeFormat(): atomIde.RangeCodeFormatProvider;
194 protected getCodeFormat(editor: TextEditor, range: Range): Promise<atomIde.TextEdit[]>;
195 provideRangeCodeFormat(): atomIde.RangeCodeFormatProvider;
196 protected getRangeCodeFormat(editor: TextEditor, range: Range): Promise<atomIde.TextEdit[]>;
197 provideFileCodeFormat(): atomIde.FileCodeFormatProvider;
198 provideOnSaveCodeFormat(): atomIde.OnSaveCodeFormatProvider;
199 protected getFileCodeFormat(editor: TextEditor): Promise<atomIde.TextEdit[]>;
200 provideOnTypeCodeFormat(): atomIde.OnTypeCodeFormatProvider;
201 protected getOnTypeCodeFormat(editor: TextEditor, point: Point, character: string): Promise<atomIde.TextEdit[]>;
202 provideCodeHighlight(): atomIde.CodeHighlightProvider;
203 protected getCodeHighlight(editor: TextEditor, position: Point): Promise<Range[] | null>;
204 provideCodeActions(): atomIde.CodeActionProvider;
205 protected getCodeActions(editor: TextEditor, range: Range, diagnostics: atomIde.Diagnostic[]): Promise<atomIde.CodeAction[] | null>;
206 /** Optionally filter code action before they're displayed */
207 protected filterCodeActions(actions: (ls.Command | ls.CodeAction)[] | null): (ls.Command | ls.CodeAction)[] | null;
208 /**
209 * Optionally handle a code action before default handling. Return `false` to prevent default handling, `true` to
210 * continue with default handling.
211 */
212 protected onApplyCodeActions(_action: ls.Command | ls.CodeAction): Promise<boolean>;
213 provideRefactor(): atomIde.RefactorProvider;
214 protected getRename(editor: TextEditor, position: Point, newName: string): Promise<Map<string, atomIde.TextEdit[]> | null>;
215 consumeSignatureHelp(registry: atomIde.SignatureHelpRegistry): Disposable;
216 consumeBusySignal(service: atomIde.BusySignalService): Disposable;
217 /**
218 * `didChangeWatchedFiles` message filtering, override for custom logic.
219 *
220 * @param filePath Path of a file that has changed in the project path
221 * @returns `false` => message will not be sent to the language server
222 */
223 protected filterChangeWatchedFiles(_filePath: string): boolean;
224 /**
225 * If this is set to `true` (the default value), the servers will shut down gracefully. If it is set to `false`, the
226 * servers will be killed without awaiting shutdown response.
227 */
228 protected shutdownGracefully: boolean;
229 /**
230 * Called on language server stderr output.
231 *
232 * @param stderr A chunk of stderr from a language server instance
233 */
234 protected handleServerStderr(stderr: string, _projectPath: string): void;
235 private getServerAdapter;
236 protected reportBusyWhile: Utils.ReportBusyWhile;
237 protected reportBusyWhileDefault: Utils.ReportBusyWhile;
238}