codemirror-languageserver
Advanced tools
| import { Extension } from '@codemirror/state'; | ||
| export declare const autocompletion: () => Extension; |
| import { Extension } from '@codemirror/state'; | ||
| export declare const hoverTooltip: () => Extension; |
| /** | ||
| * Initialization options for Pyright language server | ||
| * @see https://github.com/microsoft/pyright/blob/main/docs/settings.md | ||
| */ | ||
| export interface PyrightInitializationOptions { | ||
| python?: { | ||
| pythonPath?: string; | ||
| venvPath?: string; | ||
| analysis?: { | ||
| autoSearchPaths?: boolean; | ||
| extraPaths?: string[]; | ||
| diagnosticMode?: 'workspace' | 'openFilesOnly'; | ||
| stubPath?: string; | ||
| typeshedPaths?: string[]; | ||
| useLibraryCodeForTypes?: boolean; | ||
| typeCheckingMode?: 'off' | 'basic' | 'strict'; | ||
| autoImportCompletions?: boolean; | ||
| indexing?: boolean; | ||
| }; | ||
| }; | ||
| reportMissingImports?: boolean; | ||
| reportMissingTypeStubs?: boolean; | ||
| reportMissingModuleSource?: boolean; | ||
| reportInvalidTypeVarUse?: boolean; | ||
| reportOptionalSubscript?: boolean; | ||
| reportOptionalMemberAccess?: boolean; | ||
| reportOptionalCall?: boolean; | ||
| reportOptionalIterable?: boolean; | ||
| reportOptionalContextManager?: boolean; | ||
| reportOptionalOperand?: boolean; | ||
| reportTypedDictNotRequiredAccess?: boolean; | ||
| reportPrivateImportUsage?: boolean; | ||
| reportConstantRedefinition?: boolean; | ||
| reportIncompatibleMethodOverride?: boolean; | ||
| reportIncompatibleVariableOverride?: boolean; | ||
| reportInconsistentConstructor?: boolean; | ||
| } | ||
| /** | ||
| * Initialization options for Rust Analyzer language server | ||
| * @see https://rust-analyzer.github.io/manual.html#configuration | ||
| */ | ||
| export interface RustAnalyzerInitializationOptions { | ||
| cargo?: { | ||
| buildScripts?: { | ||
| enable?: boolean; | ||
| invocationStrategy?: 'per_workspace' | 'once'; | ||
| invocationLocation?: 'workspace' | 'root'; | ||
| }; | ||
| allTargets?: boolean; | ||
| noDefaultFeatures?: boolean; | ||
| allFeatures?: boolean; | ||
| features?: string[]; | ||
| target?: string; | ||
| runBuildScripts?: boolean; | ||
| useRustcWrapperForBuildScripts?: boolean; | ||
| }; | ||
| procMacro?: { | ||
| enable?: boolean; | ||
| ignored?: Record<string, string[]>; | ||
| server?: string; | ||
| attributes?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| diagnostics?: { | ||
| enable?: boolean; | ||
| disabled?: string[]; | ||
| warningsAsHint?: string[]; | ||
| warningsAsInfo?: string[]; | ||
| remapPrefix?: Record<string, string>; | ||
| experimental?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| completion?: { | ||
| addCallArgumentSnippets?: boolean; | ||
| addCallParenthesis?: boolean; | ||
| postfix?: { | ||
| enable?: boolean; | ||
| }; | ||
| autoimport?: { | ||
| enable?: boolean; | ||
| }; | ||
| privateEditable?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| assist?: { | ||
| importGranularity?: 'preserve' | 'crate' | 'module' | 'item'; | ||
| importEnforceGranularity?: boolean; | ||
| importPrefix?: 'plain' | 'by_self' | 'by_crate'; | ||
| allowMergingIntoGlobImports?: boolean; | ||
| }; | ||
| callInfo?: { | ||
| full?: boolean; | ||
| }; | ||
| lens?: { | ||
| enable?: boolean; | ||
| run?: boolean; | ||
| debug?: boolean; | ||
| implementations?: boolean; | ||
| refs?: boolean; | ||
| methodReferences?: boolean; | ||
| references?: boolean; | ||
| enumVariantReferences?: boolean; | ||
| }; | ||
| hover?: { | ||
| documentation?: boolean; | ||
| keywords?: boolean; | ||
| linksInHover?: boolean; | ||
| memoryLayout?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| workspace?: { | ||
| symbol?: { | ||
| search?: { | ||
| scope?: 'workspace' | 'workspace_and_dependencies'; | ||
| kind?: 'only_types' | 'all_symbols'; | ||
| }; | ||
| }; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for TypeScript/JavaScript language server | ||
| * @see https://github.com/typescript-language-server/typescript-language-server | ||
| */ | ||
| export interface TypeScriptInitializationOptions { | ||
| hostInfo?: string; | ||
| npmLocation?: string; | ||
| globalPlugins?: string[]; | ||
| pluginProbeLocations?: string[]; | ||
| preferences?: { | ||
| includePackageJsonAutoImports?: 'auto' | 'on' | 'off'; | ||
| providePrefixAndSuffixTextForRename?: boolean; | ||
| allowRenameOfImportPath?: boolean; | ||
| includeAutomaticOptionalChainCompletions?: boolean; | ||
| includeCompletionsForModuleExports?: boolean; | ||
| includeCompletionsForImportStatements?: boolean; | ||
| includeCompletionsWithSnippetText?: boolean; | ||
| includeCompletionsWithInsertText?: boolean; | ||
| allowIncompleteCompletions?: boolean; | ||
| importModuleSpecifier?: 'shortest' | 'relative' | 'absolute' | 'auto'; | ||
| importModuleSpecifierEnding?: 'minimal' | 'index' | 'js'; | ||
| allowTextChangesInNewFiles?: boolean; | ||
| lazyConfiguredProjectsFromExternalProject?: boolean; | ||
| providePrefixAndSuffixTextForQuickInfo?: boolean; | ||
| includeInlayParameterNameHints?: 'none' | 'literals' | 'all'; | ||
| includeInlayParameterNameHintsWhenArgumentMatchesName?: boolean; | ||
| includeInlayFunctionParameterTypeHints?: boolean; | ||
| includeInlayVariableTypeHints?: boolean; | ||
| includeInlayVariableTypeHintsWhenTypeMatchesName?: boolean; | ||
| includeInlayPropertyDeclarationTypeHints?: boolean; | ||
| includeInlayFunctionLikeReturnTypeHints?: boolean; | ||
| includeInlayEnumMemberValueHints?: boolean; | ||
| }; | ||
| locale?: string; | ||
| maxTsServerMemory?: number; | ||
| tsserver?: { | ||
| logLevel?: 'off' | 'terse' | 'normal' | 'requestTime' | 'verbose'; | ||
| logVerbosity?: 'off' | 'terse' | 'normal' | 'requestTime' | 'verbose'; | ||
| trace?: 'off' | 'messages' | 'verbose'; | ||
| useSeparateSyntaxServer?: boolean; | ||
| enableTracing?: boolean; | ||
| path?: string; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for ESLint language server | ||
| * @see https://github.com/Microsoft/vscode-eslint | ||
| */ | ||
| export interface ESLintInitializationOptions { | ||
| packageManager?: 'npm' | 'yarn' | 'pnpm'; | ||
| nodePath?: string; | ||
| options?: Record<string, any>; | ||
| rules?: Record<string, any>; | ||
| rulesCustomizations?: Array<{ | ||
| rule: string; | ||
| severity: 'downgrade' | 'upgrade' | 'info' | 'warn' | 'error' | 'off'; | ||
| }>; | ||
| run?: 'onType' | 'onSave'; | ||
| problems?: { | ||
| shortenToSingleLine?: boolean; | ||
| }; | ||
| codeAction?: { | ||
| disableRuleComment?: { | ||
| enable?: boolean; | ||
| location?: 'separateLine' | 'sameLine'; | ||
| }; | ||
| showDocumentation?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| codeActionOnSave?: { | ||
| enable?: boolean; | ||
| mode?: 'all' | 'problems'; | ||
| }; | ||
| format?: { | ||
| enable?: boolean; | ||
| }; | ||
| quiet?: boolean; | ||
| onIgnoredFiles?: 'off' | 'warn'; | ||
| useESLintClass?: boolean; | ||
| experimental?: { | ||
| useFlatConfig?: boolean; | ||
| }; | ||
| workingDirectory?: { | ||
| mode?: 'auto' | 'location'; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for Clangd language server | ||
| * @see https://clangd.llvm.org/config | ||
| */ | ||
| export interface ClangdInitializationOptions { | ||
| compilationDatabasePath?: string; | ||
| compilationDatabaseChanges?: Record<string, any>; | ||
| fallbackFlags?: string[]; | ||
| clangdFileStatus?: boolean; | ||
| utf8?: boolean; | ||
| offsetEncoding?: ('utf-8' | 'utf-16' | 'utf-32')[]; | ||
| index?: { | ||
| background?: 'Build' | 'Skip'; | ||
| threads?: number; | ||
| }; | ||
| completion?: { | ||
| detailedLabel?: boolean; | ||
| allScopes?: boolean; | ||
| }; | ||
| hover?: { | ||
| showAKA?: boolean; | ||
| }; | ||
| inlayHints?: { | ||
| enabled?: boolean; | ||
| parameterNames?: boolean; | ||
| deducedTypes?: boolean; | ||
| designators?: boolean; | ||
| }; | ||
| semanticHighlighting?: boolean; | ||
| diagnostics?: { | ||
| unusedIncludes?: 'None' | 'Strict'; | ||
| missingIncludes?: 'None' | 'Strict'; | ||
| clangTidy?: boolean; | ||
| suppressAll?: boolean; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for Gopls (Go language server) | ||
| * @see https://github.com/golang/tools/blob/master/gopls/doc/settings.md | ||
| */ | ||
| export interface GoplsInitializationOptions { | ||
| buildFlags?: string[]; | ||
| env?: Record<string, string>; | ||
| directoryFilters?: string[]; | ||
| templateExtensions?: string[]; | ||
| memoryMode?: 'DegradeClosed' | 'Normal'; | ||
| gofumpt?: boolean; | ||
| staticcheck?: boolean; | ||
| analyses?: Record<string, boolean>; | ||
| codelenses?: Record<string, boolean>; | ||
| usePlaceholders?: boolean; | ||
| completionBudget?: string; | ||
| diagnosticsDelay?: string; | ||
| experimentalPostfixCompletions?: boolean; | ||
| experimentalWorkspaceModule?: boolean; | ||
| experimentalTemplateSupport?: boolean; | ||
| semanticTokens?: boolean; | ||
| noSemanticString?: boolean; | ||
| noSemanticNumber?: boolean; | ||
| expandWorkspaceToModule?: boolean; | ||
| experimentalUseInvalidMetadata?: boolean; | ||
| hoverKind?: 'FullDocumentation' | 'NoDocumentation' | 'SingleLine' | 'Structured' | 'SynopsisDocumentation'; | ||
| linkTarget?: string; | ||
| linksInHover?: boolean; | ||
| importShortcut?: 'Both' | 'Definition' | 'Link'; | ||
| symbolMatcher?: 'CaseInsensitive' | 'CaseSensitive' | 'FastFuzzy' | 'Fuzzy'; | ||
| symbolStyle?: 'Dynamic' | 'Full' | 'Package'; | ||
| verboseOutput?: boolean; | ||
| } |
| import { Extension } from '@codemirror/state'; | ||
| export declare const mouseHandler: () => Extension; |
+27
-18
@@ -35,12 +35,33 @@ import { | ||
| import { cpp } from '@codemirror/lang-cpp'; | ||
| import { | ||
| languageServer, | ||
| jumpToDefinitionKeymap, | ||
| jumpToDefinitionPos, | ||
| } from '../src'; | ||
| import { languageServer } from '../src'; | ||
| const tabSizeCompartment = new Compartment(); | ||
| const doc = `#include <iostream> | ||
| using namespace std; | ||
| class Animal { | ||
| public: | ||
| void say(string call) { | ||
| cout << call << endl; | ||
| } | ||
| }; | ||
| class Cat : Animal { | ||
| public: | ||
| void meow() { | ||
| this->say("meow"); | ||
| } | ||
| }; | ||
| int main() { | ||
| Cat cat; | ||
| cat.meow(); | ||
| return 0; | ||
| } | ||
| ` | ||
| const view = new EditorView({ | ||
| doc: '#include <iostream>\n\nusing namespace std;\n\nint main() {\n\treturn 0;\n}\n', | ||
| doc, | ||
| parent: document.getElementById('editor'), | ||
@@ -88,15 +109,3 @@ extensions: [ | ||
| }), | ||
| keymap.of([...jumpToDefinitionKeymap]), | ||
| EditorView.domEventHandlers({ | ||
| click: (event, view) => { | ||
| if (!event.ctrlKey && !event.metaKey) return; | ||
| const pos = view.posAtCoords({ | ||
| x: event.clientX, | ||
| y: event.clientY, | ||
| }); | ||
| const ok = jumpToDefinitionPos(pos)(view); | ||
| if (ok) event.preventDefault(); | ||
| }, | ||
| }), | ||
| ], | ||
| }); |
| import { Command, KeyBinding } from '@codemirror/view'; | ||
| export declare const jumpToDefinition: Command; | ||
| export declare const jumpToDefinitionPos: (pos: number) => Command; | ||
| export declare const jumpToDeclaration: Command; | ||
| export declare const jumpToDeclarationPos: (pos: number) => Command; | ||
| export declare const jumpToTypeDefinition: Command; | ||
| export declare const jumpToTypeDefinitionPos: (pos: number) => Command; | ||
| export declare const jumpToDefinitionKeymap: readonly KeyBinding[]; |
+14
-1
@@ -1,2 +0,15 @@ | ||
| export { LanguageServerClient, languageServerPlugin, languageServer, languageServerWithTransport, } from './plugin'; | ||
| export { LanguageServerClient, languageServerPlugin } from './plugin'; | ||
| export { jumpToDefinition, jumpToDefinitionPos, jumpToDefinitionKeymap, } from './definition'; | ||
| export { PyrightInitializationOptions, RustAnalyzerInitializationOptions, TypeScriptInitializationOptions, ESLintInitializationOptions, ClangdInitializationOptions, GoplsInitializationOptions, } from './initialization'; | ||
| import { LanguageServerClient } from './plugin'; | ||
| import type { LanguageServerClientOptions, LanguageServerBaseOptions } from './plugin'; | ||
| interface LanguageServerOptions<InitializationOptions = unknown> extends LanguageServerClientOptions<InitializationOptions> { | ||
| client?: LanguageServerClient<InitializationOptions>; | ||
| allowHTMLContent?: boolean; | ||
| } | ||
| interface LanguageServerWebsocketOptions<InitializationOptions = unknown> extends LanguageServerBaseOptions { | ||
| serverUri: `ws://${string}` | `wss://${string}`; | ||
| initializationOptions?: InitializationOptions; | ||
| } | ||
| export declare function languageServer<InitializationOptions = unknown>(options: LanguageServerWebsocketOptions<InitializationOptions>): import("@codemirror/state").Extension[]; | ||
| export declare function languageServerWithTransport<InitializationOptions = unknown>(options: LanguageServerOptions<InitializationOptions>): import("@codemirror/state").Extension[]; |
+121
-71
@@ -1,5 +0,5 @@ | ||
| import { insertCompletionText, autocompletion } from '@codemirror/autocomplete'; | ||
| import { insertCompletionText, autocompletion as autocompletion$1 } from '@codemirror/autocomplete'; | ||
| import { setDiagnostics } from '@codemirror/lint'; | ||
| import { Facet } from '@codemirror/state'; | ||
| import { ViewPlugin, hoverTooltip } from '@codemirror/view'; | ||
| import { ViewPlugin, hoverTooltip as hoverTooltip$1, EditorView, keymap } from '@codemirror/view'; | ||
| import { RequestManager, Client, WebSocketTransport } from '@open-rpc/client-js'; | ||
@@ -31,7 +31,7 @@ import { CompletionItemKind, DiagnosticSeverity, CompletionTriggerKind } from 'vscode-languageserver-protocol'; | ||
| const useLast = (values) => values.reduce((_, v) => v, ''); | ||
| const client = Facet.define({ | ||
| Facet.define({ | ||
| combine: useLast, | ||
| }); | ||
| const documentUri = Facet.define({ combine: useLast }); | ||
| const languageId = Facet.define({ combine: useLast }); | ||
| Facet.define({ combine: useLast }); | ||
| Facet.define({ combine: useLast }); | ||
| class LanguageServerClient { | ||
@@ -74,3 +74,3 @@ constructor(options) { | ||
| dynamicRegistration: true, | ||
| contentFormat: ['plaintext', 'markdown'], | ||
| contentFormat: ['markdown', 'plaintext'], | ||
| }, | ||
@@ -89,3 +89,3 @@ moniker: {}, | ||
| commitCharactersSupport: true, | ||
| documentationFormat: ['plaintext', 'markdown'], | ||
| documentationFormat: ['markdown', 'plaintext'], | ||
| deprecatedSupport: false, | ||
@@ -99,3 +99,3 @@ preselectSupport: false, | ||
| signatureInformation: { | ||
| documentationFormat: ['plaintext', 'markdown'], | ||
| documentationFormat: ['markdown', 'plaintext'], | ||
| }, | ||
@@ -156,2 +156,8 @@ }, | ||
| } | ||
| async textDocumentDeclaration(params) { | ||
| return await this.request('textDocument/declaration', params, timeout); | ||
| } | ||
| async textDocumentTypeDefinition(params) { | ||
| return await this.request('textDocument/typeDefinition', params, timeout); | ||
| } | ||
| attachPlugin(plugin) { | ||
@@ -183,8 +189,8 @@ this.plugins.push(plugin); | ||
| class LanguageServerPlugin { | ||
| constructor(view, allowHTMLContent) { | ||
| constructor(view, { client, documentUri, languageId, allowHTMLContent, }) { | ||
| this.view = view; | ||
| this.client = client; | ||
| this.documentUri = documentUri; | ||
| this.languageId = languageId; | ||
| this.allowHTMLContent = allowHTMLContent; | ||
| this.client = this.view.state.facet(client); | ||
| this.documentUri = this.view.state.facet(documentUri); | ||
| this.languageId = this.view.state.facet(languageId); | ||
| this.documentVersion = 0; | ||
@@ -391,8 +397,7 @@ this.changesTimeout = 0; | ||
| } | ||
| async requestDefinition(view, { line, character }) { | ||
| if (!this.client.ready || | ||
| !this.client.capabilities.definitionProvider) { | ||
| async requestLocation(view, { line, character }, capability, method) { | ||
| if (!this.client.ready || !this.client.capabilities[capability]) { | ||
| return null; | ||
| } | ||
| const result = await this.client.textDocumentDefinition({ | ||
| const result = await this.client[method]({ | ||
| textDocument: { uri: this.documentUri }, | ||
@@ -414,2 +419,3 @@ position: { line, character }, | ||
| }, | ||
| scrollIntoView: true, | ||
| })); | ||
@@ -422,2 +428,11 @@ } | ||
| } | ||
| async requestDefinition(view, { line, character }) { | ||
| return this.requestLocation(view, { line, character }, 'definitionProvider', 'textDocumentDefinition'); | ||
| } | ||
| async requestDeclaration(view, { line, character }) { | ||
| return this.requestLocation(view, { line, character }, 'declarationProvider', 'textDocumentDeclaration'); | ||
| } | ||
| async requestTypeDefinition(view, { line, character }) { | ||
| return this.requestLocation(view, { line, character }, 'typeDefinitionProvider', 'textDocumentTypeDefinition'); | ||
| } | ||
| processNotification(notification) { | ||
@@ -467,54 +482,2 @@ try { | ||
| const languageServerPlugin = ViewPlugin.fromClass(LanguageServerPlugin); | ||
| function languageServer(options) { | ||
| const serverUri = options.serverUri; | ||
| const { serverUri: _, ...optionsWithoutServerUri } = options; | ||
| return languageServerWithTransport({ | ||
| ...optionsWithoutServerUri, | ||
| transport: new WebSocketTransport(serverUri), | ||
| }); | ||
| } | ||
| function languageServerWithTransport(options) { | ||
| return [ | ||
| client.of(options.client || | ||
| new LanguageServerClient({ | ||
| ...options, | ||
| autoClose: true, | ||
| })), | ||
| documentUri.of(options.documentUri), | ||
| languageId.of(options.languageId), | ||
| languageServerPlugin.of(options.allowHTMLContent), | ||
| hoverTooltip((view, pos) => { | ||
| var _a; | ||
| const plugin = view.plugin(languageServerPlugin); | ||
| return ((_a = plugin === null || plugin === void 0 ? void 0 : plugin.requestHoverTooltip(view, offsetToPos(view.state.doc, pos))) !== null && _a !== void 0 ? _a : null); | ||
| }), | ||
| autocompletion({ | ||
| override: [ | ||
| async (context) => { | ||
| var _a, _b, _c; | ||
| const { state, pos, explicit, view } = context; | ||
| const plugin = view.plugin(languageServerPlugin); | ||
| if (plugin == null) | ||
| return null; | ||
| const line = state.doc.lineAt(pos); | ||
| let trigKind = CompletionTriggerKind.Invoked; | ||
| let trigChar; | ||
| if (!explicit && | ||
| ((_c = (_b = (_a = plugin.client.capabilities) === null || _a === void 0 ? void 0 : _a.completionProvider) === null || _b === void 0 ? void 0 : _b.triggerCharacters) === null || _c === void 0 ? void 0 : _c.includes(line.text[pos - line.from - 1]))) { | ||
| trigKind = CompletionTriggerKind.TriggerCharacter; | ||
| trigChar = line.text[pos - line.from - 1]; | ||
| } | ||
| if (trigKind === CompletionTriggerKind.Invoked && | ||
| !context.matchBefore(/\w+$/)) { | ||
| return null; | ||
| } | ||
| return await plugin.requestCompletion(context, offsetToPos(state.doc, pos), { | ||
| triggerCharacter: trigChar, | ||
| triggerKind: trigKind, | ||
| }); | ||
| }, | ||
| ], | ||
| }), | ||
| ]; | ||
| } | ||
| async function formatContents(contents) { | ||
@@ -567,3 +530,3 @@ if (isLSPMarkupContent(contents)) { | ||
| function jumpTo(view, pos) { | ||
| function requestDefinition(view, pos) { | ||
| const plugin = view.plugin(languageServerPlugin); | ||
@@ -575,8 +538,95 @@ if (!plugin) | ||
| } | ||
| const jumpToDefinition = (view) => jumpTo(view, view.state.selection.main.head); | ||
| const jumpToDefinitionPos = (pos) => (view) => jumpTo(view, pos); | ||
| function requestTypeDefinition(view, pos) { | ||
| const plugin = view.plugin(languageServerPlugin); | ||
| if (!plugin) | ||
| return false; | ||
| plugin.requestTypeDefinition(view, offsetToPos(view.state.doc, pos)); | ||
| return true; | ||
| } | ||
| const jumpToDefinition = (view) => requestDefinition(view, view.state.selection.main.head); | ||
| const jumpToDefinitionPos = (pos) => (view) => requestDefinition(view, pos); | ||
| const jumpToTypeDefinition = (view) => requestTypeDefinition(view, view.state.selection.main.head); | ||
| const jumpToTypeDefinitionPos = (pos) => (view) => requestTypeDefinition(view, pos); | ||
| const jumpToDefinitionKeymap = [ | ||
| { key: 'F12', run: jumpToDefinition, preventDefault: true }, | ||
| { key: 'Mod-F12', run: jumpToTypeDefinition, preventDefault: true }, | ||
| ]; | ||
| const hoverTooltip = () => hoverTooltip$1((view, pos) => { | ||
| var _a; | ||
| const plugin = view.plugin(languageServerPlugin); | ||
| return ((_a = plugin === null || plugin === void 0 ? void 0 : plugin.requestHoverTooltip(view, offsetToPos(view.state.doc, pos))) !== null && _a !== void 0 ? _a : null); | ||
| }); | ||
| const autocompletion = () => autocompletion$1({ | ||
| override: [ | ||
| async (context) => { | ||
| var _a, _b, _c; | ||
| const { state, pos, explicit, view } = context; | ||
| const plugin = view.plugin(languageServerPlugin); | ||
| if (plugin == null) | ||
| return null; | ||
| const line = state.doc.lineAt(pos); | ||
| let trigKind = CompletionTriggerKind.Invoked; | ||
| let trigChar; | ||
| if (!explicit && | ||
| ((_c = (_b = (_a = plugin.client.capabilities) === null || _a === void 0 ? void 0 : _a.completionProvider) === null || _b === void 0 ? void 0 : _b.triggerCharacters) === null || _c === void 0 ? void 0 : _c.includes(line.text[pos - line.from - 1]))) { | ||
| trigKind = CompletionTriggerKind.TriggerCharacter; | ||
| trigChar = line.text[pos - line.from - 1]; | ||
| } | ||
| if (trigKind === CompletionTriggerKind.Invoked && | ||
| !context.matchBefore(/\w+$/)) { | ||
| return null; | ||
| } | ||
| return await plugin.requestCompletion(context, offsetToPos(state.doc, pos), { | ||
| triggerCharacter: trigChar, | ||
| triggerKind: trigKind, | ||
| }); | ||
| }, | ||
| ], | ||
| }); | ||
| const mouseHandler = () => EditorView.domEventHandlers({ | ||
| mousedown: (event, view) => { | ||
| if (!event.ctrlKey && !event.metaKey) | ||
| return; | ||
| const pos = view.posAtCoords({ | ||
| x: event.clientX, | ||
| y: event.clientY, | ||
| }); | ||
| const ok = (event.shiftKey | ||
| ? jumpToTypeDefinitionPos(pos) | ||
| : jumpToDefinitionPos(pos))(view); | ||
| if (ok) | ||
| event.preventDefault(); | ||
| }, | ||
| }); | ||
| function languageServer(options) { | ||
| const serverUri = options.serverUri; | ||
| const { serverUri: _, ...optionsWithoutServerUri } = options; | ||
| return languageServerWithTransport({ | ||
| ...optionsWithoutServerUri, | ||
| transport: new WebSocketTransport(serverUri), | ||
| }); | ||
| } | ||
| function languageServerWithTransport(options) { | ||
| return [ | ||
| languageServerPlugin.of({ | ||
| client: options.client || | ||
| new LanguageServerClient({ | ||
| ...options, | ||
| autoClose: true, | ||
| }), | ||
| documentUri: options.documentUri, | ||
| languageId: options.languageId, | ||
| allowHTMLContent: options.allowHTMLContent, | ||
| }), | ||
| hoverTooltip(), | ||
| autocompletion(), | ||
| keymap.of([...jumpToDefinitionKeymap]), | ||
| mouseHandler(), | ||
| ]; | ||
| } | ||
| export { LanguageServerClient, jumpToDefinition, jumpToDefinitionKeymap, jumpToDefinitionPos, languageServer, languageServerPlugin, languageServerWithTransport }; |
+52
-299
@@ -19,2 +19,10 @@ import { EditorView, Tooltip, ViewPlugin } from '@codemirror/view'; | ||
| ]; | ||
| 'textDocument/declaration': [ | ||
| LSP.DeclarationParams, | ||
| LSP.Location | LSP.Location[] | LSP.LocationLink[] | null | ||
| ]; | ||
| 'textDocument/typeDefinition': [ | ||
| LSP.TypeDefinitionParams, | ||
| LSP.Location | LSP.Location[] | LSP.LocationLink[] | null | ||
| ]; | ||
| } | ||
@@ -37,2 +45,7 @@ interface LSPNotifyMap { | ||
| }[keyof LSPEventMap]; | ||
| interface LanguageServerClientLocationMethods { | ||
| textDocumentDefinition(params: LSP.DefinitionParams): LSP.Location | LSP.Location[] | LSP.LocationLink[] | null; | ||
| textDocumentDeclaration(params: LSP.DeclarationParams): LSP.Location | LSP.Location[] | LSP.LocationLink[] | null; | ||
| textDocumentTypeDefinition(params: LSP.TypeDefinitionParams): LSP.Location | LSP.Location[] | LSP.LocationLink[] | null; | ||
| } | ||
| export declare class LanguageServerClient<InitializationOptions = unknown> { | ||
@@ -59,2 +72,4 @@ ready: boolean; | ||
| textDocumentDefinition(params: LSP.DefinitionParams): Promise<LSP.Location | LSP.Location[] | LSP.LocationLink[]>; | ||
| textDocumentDeclaration(params: LSP.DeclarationParams): Promise<LSP.Location | LSP.Location[] | LSP.LocationLink[]>; | ||
| textDocumentTypeDefinition(params: LSP.TypeDefinitionParams): Promise<LSP.Location | LSP.Location[] | LSP.LocationLink[]>; | ||
| attachPlugin(plugin: LanguageServerPlugin): void; | ||
@@ -66,5 +81,4 @@ detachPlugin(plugin: LanguageServerPlugin): void; | ||
| } | ||
| declare class LanguageServerPlugin implements PluginValue { | ||
| export declare class LanguageServerPlugin implements PluginValue { | ||
| private view; | ||
| private allowHTMLContent; | ||
| client: LanguageServerClient; | ||
@@ -74,4 +88,10 @@ private documentUri; | ||
| private documentVersion; | ||
| private allowHTMLContent; | ||
| private changesTimeout; | ||
| constructor(view: EditorView, allowHTMLContent: boolean); | ||
| constructor(view: EditorView, { client, documentUri, languageId, allowHTMLContent, }: { | ||
| client: LanguageServerClient; | ||
| documentUri: string; | ||
| languageId: string; | ||
| allowHTMLContent: boolean; | ||
| }); | ||
| update({ docChanged }: ViewUpdate): void; | ||
@@ -97,2 +117,9 @@ destroy(): void; | ||
| }): Promise<CompletionResult | null>; | ||
| requestLocation(view: EditorView, { line, character }: { | ||
| line: number; | ||
| character: number; | ||
| }, capability: keyof LSP.ServerCapabilities<any>, method: keyof LanguageServerClientLocationMethods): Promise<{ | ||
| uri: string; | ||
| range: LSP.Range; | ||
| }>; | ||
| requestDefinition(view: EditorView, { line, character }: { | ||
@@ -105,7 +132,26 @@ line: number; | ||
| }>; | ||
| requestDeclaration(view: EditorView, { line, character }: { | ||
| line: number; | ||
| character: number; | ||
| }): Promise<{ | ||
| uri: string; | ||
| range: LSP.Range; | ||
| }>; | ||
| requestTypeDefinition(view: EditorView, { line, character }: { | ||
| line: number; | ||
| character: number; | ||
| }): Promise<{ | ||
| uri: string; | ||
| range: LSP.Range; | ||
| }>; | ||
| processNotification(notification: Notification): void; | ||
| processDiagnostics(params: PublishDiagnosticsParams): void; | ||
| } | ||
| export declare const languageServerPlugin: ViewPlugin<LanguageServerPlugin, boolean>; | ||
| interface LanguageServerBaseOptions { | ||
| export declare const languageServerPlugin: ViewPlugin<LanguageServerPlugin, { | ||
| client: LanguageServerClient; | ||
| documentUri: string; | ||
| languageId: string; | ||
| allowHTMLContent: boolean; | ||
| }>; | ||
| export interface LanguageServerBaseOptions { | ||
| rootUri: string | null; | ||
@@ -116,3 +162,3 @@ workspaceFolders: LSP.WorkspaceFolder[] | null; | ||
| } | ||
| interface LanguageServerClientOptions<InitializationOptions = unknown> extends LanguageServerBaseOptions { | ||
| export interface LanguageServerClientOptions<InitializationOptions = unknown> extends LanguageServerBaseOptions { | ||
| transport: Transport; | ||
@@ -122,295 +168,2 @@ autoClose?: boolean; | ||
| } | ||
| interface LanguageServerOptions<InitializationOptions = unknown> extends LanguageServerClientOptions<InitializationOptions> { | ||
| client?: LanguageServerClient<InitializationOptions>; | ||
| allowHTMLContent?: boolean; | ||
| } | ||
| interface LanguageServerWebsocketOptions<InitializationOptions = unknown> extends LanguageServerBaseOptions { | ||
| serverUri: `ws://${string}` | `wss://${string}`; | ||
| initializationOptions?: InitializationOptions; | ||
| } | ||
| export declare function languageServer<InitializationOptions = unknown>(options: LanguageServerWebsocketOptions<InitializationOptions>): ({ | ||
| extension: import("@codemirror/state").Extension; | ||
| } | readonly import("@codemirror/state").Extension[])[]; | ||
| export declare function languageServerWithTransport<InitializationOptions = unknown>(options: LanguageServerOptions<InitializationOptions>): ({ | ||
| extension: import("@codemirror/state").Extension; | ||
| } | readonly import("@codemirror/state").Extension[])[]; | ||
| /** | ||
| * Initialization options for Pyright language server | ||
| * @see https://github.com/microsoft/pyright/blob/main/docs/settings.md | ||
| */ | ||
| export interface PyrightInitializationOptions { | ||
| python?: { | ||
| pythonPath?: string; | ||
| venvPath?: string; | ||
| analysis?: { | ||
| autoSearchPaths?: boolean; | ||
| extraPaths?: string[]; | ||
| diagnosticMode?: 'workspace' | 'openFilesOnly'; | ||
| stubPath?: string; | ||
| typeshedPaths?: string[]; | ||
| useLibraryCodeForTypes?: boolean; | ||
| typeCheckingMode?: 'off' | 'basic' | 'strict'; | ||
| autoImportCompletions?: boolean; | ||
| indexing?: boolean; | ||
| }; | ||
| }; | ||
| reportMissingImports?: boolean; | ||
| reportMissingTypeStubs?: boolean; | ||
| reportMissingModuleSource?: boolean; | ||
| reportInvalidTypeVarUse?: boolean; | ||
| reportOptionalSubscript?: boolean; | ||
| reportOptionalMemberAccess?: boolean; | ||
| reportOptionalCall?: boolean; | ||
| reportOptionalIterable?: boolean; | ||
| reportOptionalContextManager?: boolean; | ||
| reportOptionalOperand?: boolean; | ||
| reportTypedDictNotRequiredAccess?: boolean; | ||
| reportPrivateImportUsage?: boolean; | ||
| reportConstantRedefinition?: boolean; | ||
| reportIncompatibleMethodOverride?: boolean; | ||
| reportIncompatibleVariableOverride?: boolean; | ||
| reportInconsistentConstructor?: boolean; | ||
| } | ||
| /** | ||
| * Initialization options for Rust Analyzer language server | ||
| * @see https://rust-analyzer.github.io/manual.html#configuration | ||
| */ | ||
| export interface RustAnalyzerInitializationOptions { | ||
| cargo?: { | ||
| buildScripts?: { | ||
| enable?: boolean; | ||
| invocationStrategy?: 'per_workspace' | 'once'; | ||
| invocationLocation?: 'workspace' | 'root'; | ||
| }; | ||
| allTargets?: boolean; | ||
| noDefaultFeatures?: boolean; | ||
| allFeatures?: boolean; | ||
| features?: string[]; | ||
| target?: string; | ||
| runBuildScripts?: boolean; | ||
| useRustcWrapperForBuildScripts?: boolean; | ||
| }; | ||
| procMacro?: { | ||
| enable?: boolean; | ||
| ignored?: Record<string, string[]>; | ||
| server?: string; | ||
| attributes?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| diagnostics?: { | ||
| enable?: boolean; | ||
| disabled?: string[]; | ||
| warningsAsHint?: string[]; | ||
| warningsAsInfo?: string[]; | ||
| remapPrefix?: Record<string, string>; | ||
| experimental?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| completion?: { | ||
| addCallArgumentSnippets?: boolean; | ||
| addCallParenthesis?: boolean; | ||
| postfix?: { | ||
| enable?: boolean; | ||
| }; | ||
| autoimport?: { | ||
| enable?: boolean; | ||
| }; | ||
| privateEditable?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| assist?: { | ||
| importGranularity?: 'preserve' | 'crate' | 'module' | 'item'; | ||
| importEnforceGranularity?: boolean; | ||
| importPrefix?: 'plain' | 'by_self' | 'by_crate'; | ||
| allowMergingIntoGlobImports?: boolean; | ||
| }; | ||
| callInfo?: { | ||
| full?: boolean; | ||
| }; | ||
| lens?: { | ||
| enable?: boolean; | ||
| run?: boolean; | ||
| debug?: boolean; | ||
| implementations?: boolean; | ||
| refs?: boolean; | ||
| methodReferences?: boolean; | ||
| references?: boolean; | ||
| enumVariantReferences?: boolean; | ||
| }; | ||
| hover?: { | ||
| documentation?: boolean; | ||
| keywords?: boolean; | ||
| linksInHover?: boolean; | ||
| memoryLayout?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| workspace?: { | ||
| symbol?: { | ||
| search?: { | ||
| scope?: 'workspace' | 'workspace_and_dependencies'; | ||
| kind?: 'only_types' | 'all_symbols'; | ||
| }; | ||
| }; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for TypeScript/JavaScript language server | ||
| * @see https://github.com/typescript-language-server/typescript-language-server | ||
| */ | ||
| export interface TypeScriptInitializationOptions { | ||
| hostInfo?: string; | ||
| npmLocation?: string; | ||
| globalPlugins?: string[]; | ||
| pluginProbeLocations?: string[]; | ||
| preferences?: { | ||
| includePackageJsonAutoImports?: 'auto' | 'on' | 'off'; | ||
| providePrefixAndSuffixTextForRename?: boolean; | ||
| allowRenameOfImportPath?: boolean; | ||
| includeAutomaticOptionalChainCompletions?: boolean; | ||
| includeCompletionsForModuleExports?: boolean; | ||
| includeCompletionsForImportStatements?: boolean; | ||
| includeCompletionsWithSnippetText?: boolean; | ||
| includeCompletionsWithInsertText?: boolean; | ||
| allowIncompleteCompletions?: boolean; | ||
| importModuleSpecifier?: 'shortest' | 'relative' | 'absolute' | 'auto'; | ||
| importModuleSpecifierEnding?: 'minimal' | 'index' | 'js'; | ||
| allowTextChangesInNewFiles?: boolean; | ||
| lazyConfiguredProjectsFromExternalProject?: boolean; | ||
| providePrefixAndSuffixTextForQuickInfo?: boolean; | ||
| includeInlayParameterNameHints?: 'none' | 'literals' | 'all'; | ||
| includeInlayParameterNameHintsWhenArgumentMatchesName?: boolean; | ||
| includeInlayFunctionParameterTypeHints?: boolean; | ||
| includeInlayVariableTypeHints?: boolean; | ||
| includeInlayVariableTypeHintsWhenTypeMatchesName?: boolean; | ||
| includeInlayPropertyDeclarationTypeHints?: boolean; | ||
| includeInlayFunctionLikeReturnTypeHints?: boolean; | ||
| includeInlayEnumMemberValueHints?: boolean; | ||
| }; | ||
| locale?: string; | ||
| maxTsServerMemory?: number; | ||
| tsserver?: { | ||
| logLevel?: 'off' | 'terse' | 'normal' | 'requestTime' | 'verbose'; | ||
| logVerbosity?: 'off' | 'terse' | 'normal' | 'requestTime' | 'verbose'; | ||
| trace?: 'off' | 'messages' | 'verbose'; | ||
| useSeparateSyntaxServer?: boolean; | ||
| enableTracing?: boolean; | ||
| path?: string; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for ESLint language server | ||
| * @see https://github.com/Microsoft/vscode-eslint | ||
| */ | ||
| export interface ESLintInitializationOptions { | ||
| packageManager?: 'npm' | 'yarn' | 'pnpm'; | ||
| nodePath?: string; | ||
| options?: Record<string, any>; | ||
| rules?: Record<string, any>; | ||
| rulesCustomizations?: Array<{ | ||
| rule: string; | ||
| severity: 'downgrade' | 'upgrade' | 'info' | 'warn' | 'error' | 'off'; | ||
| }>; | ||
| run?: 'onType' | 'onSave'; | ||
| problems?: { | ||
| shortenToSingleLine?: boolean; | ||
| }; | ||
| codeAction?: { | ||
| disableRuleComment?: { | ||
| enable?: boolean; | ||
| location?: 'separateLine' | 'sameLine'; | ||
| }; | ||
| showDocumentation?: { | ||
| enable?: boolean; | ||
| }; | ||
| }; | ||
| codeActionOnSave?: { | ||
| enable?: boolean; | ||
| mode?: 'all' | 'problems'; | ||
| }; | ||
| format?: { | ||
| enable?: boolean; | ||
| }; | ||
| quiet?: boolean; | ||
| onIgnoredFiles?: 'off' | 'warn'; | ||
| useESLintClass?: boolean; | ||
| experimental?: { | ||
| useFlatConfig?: boolean; | ||
| }; | ||
| workingDirectory?: { | ||
| mode?: 'auto' | 'location'; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for Clangd language server | ||
| * @see https://clangd.llvm.org/config | ||
| */ | ||
| export interface ClangdInitializationOptions { | ||
| compilationDatabasePath?: string; | ||
| compilationDatabaseChanges?: Record<string, any>; | ||
| fallbackFlags?: string[]; | ||
| clangdFileStatus?: boolean; | ||
| utf8?: boolean; | ||
| offsetEncoding?: ('utf-8' | 'utf-16' | 'utf-32')[]; | ||
| index?: { | ||
| background?: 'Build' | 'Skip'; | ||
| threads?: number; | ||
| }; | ||
| completion?: { | ||
| detailedLabel?: boolean; | ||
| allScopes?: boolean; | ||
| }; | ||
| hover?: { | ||
| showAKA?: boolean; | ||
| }; | ||
| inlayHints?: { | ||
| enabled?: boolean; | ||
| parameterNames?: boolean; | ||
| deducedTypes?: boolean; | ||
| designators?: boolean; | ||
| }; | ||
| semanticHighlighting?: boolean; | ||
| diagnostics?: { | ||
| unusedIncludes?: 'None' | 'Strict'; | ||
| missingIncludes?: 'None' | 'Strict'; | ||
| clangTidy?: boolean; | ||
| suppressAll?: boolean; | ||
| }; | ||
| } | ||
| /** | ||
| * Initialization options for Gopls (Go language server) | ||
| * @see https://github.com/golang/tools/blob/master/gopls/doc/settings.md | ||
| */ | ||
| export interface GoplsInitializationOptions { | ||
| buildFlags?: string[]; | ||
| env?: Record<string, string>; | ||
| directoryFilters?: string[]; | ||
| templateExtensions?: string[]; | ||
| memoryMode?: 'DegradeClosed' | 'Normal'; | ||
| gofumpt?: boolean; | ||
| staticcheck?: boolean; | ||
| analyses?: Record<string, boolean>; | ||
| codelenses?: Record<string, boolean>; | ||
| usePlaceholders?: boolean; | ||
| completionBudget?: string; | ||
| diagnosticsDelay?: string; | ||
| experimentalPostfixCompletions?: boolean; | ||
| experimentalWorkspaceModule?: boolean; | ||
| experimentalTemplateSupport?: boolean; | ||
| semanticTokens?: boolean; | ||
| noSemanticString?: boolean; | ||
| noSemanticNumber?: boolean; | ||
| expandWorkspaceToModule?: boolean; | ||
| experimentalUseInvalidMetadata?: boolean; | ||
| hoverKind?: 'FullDocumentation' | 'NoDocumentation' | 'SingleLine' | 'Structured' | 'SynopsisDocumentation'; | ||
| linkTarget?: string; | ||
| linksInHover?: boolean; | ||
| importShortcut?: 'Both' | 'Definition' | 'Link'; | ||
| symbolMatcher?: 'CaseInsensitive' | 'CaseSensitive' | 'FastFuzzy' | 'Fuzzy'; | ||
| symbolStyle?: 'Dynamic' | 'Full' | 'Package'; | ||
| verboseOutput?: boolean; | ||
| } | ||
| export {}; |
+1
-1
| { | ||
| "name": "codemirror-languageserver", | ||
| "version": "1.15.0", | ||
| "version": "1.16.0", | ||
| "description": "Language Server Plugin for CodeMirror 6", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
+9
-2
@@ -9,2 +9,11 @@ # Language Server Plugin for CodeMirror 6 | ||
| ## Features | ||
| https://user-images.githubusercontent.com/348107/120141150-c6bb9180-c1fd-11eb-8ada-9b7b7a1e4ade.mp4 | ||
| - ⌨️ Code Completion | ||
| - 📚 Hover Documentation | ||
| - 🩺 Diagnostics | ||
| - 🔍 Go to Definition, Declaration, and Type Definition | ||
| ## Usage | ||
@@ -64,4 +73,2 @@ | ||
| https://user-images.githubusercontent.com/348107/120141150-c6bb9180-c1fd-11eb-8ada-9b7b7a1e4ade.mp4 | ||
| - [Toph](https://toph.co): Competitive programming platform. Toph uses Language Server Plugin for CodeMirror 6 with its integrated code editor. | ||
@@ -68,0 +75,0 @@ |
Sorry, the diff of this file is too big to display
1581547
0.36%19
26.67%41763
0.34%77
10%