diff --git a/src/common/lspLanguageFeatures.ts b/src/common/lspLanguageFeatures.ts index eae88394..10fbf1d5 100644 --- a/src/common/lspLanguageFeatures.ts +++ b/src/common/lspLanguageFeatures.ts @@ -390,3 +390,75 @@ function toCommand(c: lsTypes.Command | undefined): languages.Command | undefine } //#endregion + +//#region HoverAdapter + +export interface ILanguageWorkerWithHover { + doHover(uri: string, position: lsTypes.Position): Promise; +} + +export class HoverAdapter implements languages.HoverProvider { + constructor(private _worker: WorkerAccessor) {} + + provideHover( + model: editor.IReadOnlyModel, + position: Position, + token: CancellationToken + ): Promise { + let resource = model.uri; + + return this._worker(resource) + .then((worker) => { + return worker.doHover(resource.toString(), fromPosition(position)); + }) + .then((info) => { + if (!info) { + return; + } + return { + range: toRange(info.range), + contents: toMarkedStringArray(info.contents) + }; + }); + } +} + +function isMarkupContent(thing: any): thing is lsTypes.MarkupContent { + return ( + thing && typeof thing === 'object' && typeof (thing).kind === 'string' + ); +} + +function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString { + if (typeof entry === 'string') { + return { + value: entry + }; + } + if (isMarkupContent(entry)) { + if (entry.kind === 'plaintext') { + return { + value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&') + }; + } + return { + value: entry.value + }; + } + + return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' }; +} + +function toMarkedStringArray( + contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[] +): IMarkdownString[] | undefined { + if (!contents) { + return void 0; + } + if (Array.isArray(contents)) { + return contents.map(toMarkdownString); + } + return [toMarkdownString(contents)]; +} + +//#endregion diff --git a/src/css/cssMode.ts b/src/css/cssMode.ts index 7d8d3b46..119a8391 100644 --- a/src/css/cssMode.ts +++ b/src/css/cssMode.ts @@ -35,7 +35,7 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable { } if (modeConfiguration.hovers) { providers.push( - languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)) + languages.registerHoverProvider(languageId, new languageFeatures.CSSHoverAdapter(worker)) ); } if (modeConfiguration.documentHighlights) { diff --git a/src/css/languageFeatures.ts b/src/css/languageFeatures.ts index 1b957c00..804a3e33 100644 --- a/src/css/languageFeatures.ts +++ b/src/css/languageFeatures.ts @@ -6,21 +6,15 @@ import { LanguageServiceDefaults } from './monaco.contribution'; import type { CSSWorker } from './cssWorker'; import * as lsTypes from 'vscode-languageserver-types'; -import { - languages, - editor, - IMarkdownString, - Uri, - Position, - CancellationToken -} from '../fillers/monaco-editor-core'; +import { languages, editor, Uri, Position, CancellationToken } from '../fillers/monaco-editor-core'; import { DiagnosticsAdapter, fromPosition, toRange, toTextEdit, fromRange, - CompletionAdapter + CompletionAdapter, + HoverAdapter } from '../common/lspLanguageFeatures'; export interface WorkerAccessor { @@ -39,71 +33,7 @@ export class CSSCompletionAdapter extends CompletionAdapter { } } -function isMarkupContent(thing: any): thing is lsTypes.MarkupContent { - return ( - thing && typeof thing === 'object' && typeof (thing).kind === 'string' - ); -} - -function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString { - if (typeof entry === 'string') { - return { - value: entry - }; - } - if (isMarkupContent(entry)) { - if (entry.kind === 'plaintext') { - return { - value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&') - }; - } - return { - value: entry.value - }; - } - - return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' }; -} - -function toMarkedStringArray( - contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[] -): IMarkdownString[] | undefined { - if (!contents) { - return void 0; - } - if (Array.isArray(contents)) { - return contents.map(toMarkdownString); - } - return [toMarkdownString(contents)]; -} - -// --- hover ------ - -export class HoverAdapter implements languages.HoverProvider { - constructor(private _worker: WorkerAccessor) {} - - provideHover( - model: editor.IReadOnlyModel, - position: Position, - token: CancellationToken - ): Promise { - let resource = model.uri; - - return this._worker(resource) - .then((worker) => { - return worker.doHover(resource.toString(), fromPosition(position)); - }) - .then((info) => { - if (!info) { - return; - } - return { - range: toRange(info.range), - contents: toMarkedStringArray(info.contents) - }; - }); - } -} +export class CSSHoverAdapter extends HoverAdapter {} // --- document highlights ------ diff --git a/src/html/htmlMode.ts b/src/html/htmlMode.ts index 9ec7a11f..c28610a5 100644 --- a/src/html/htmlMode.ts +++ b/src/html/htmlMode.ts @@ -23,7 +23,7 @@ export function setupMode1(defaults: LanguageServiceDefaults): void { languageId, new languageFeatures.HTMLCompletionAdapter(worker) ); - languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)); + languages.registerHoverProvider(languageId, new languageFeatures.HTMLHoverAdapter(worker)); languages.registerDocumentHighlightProvider( languageId, @@ -83,7 +83,7 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable { } if (modeConfiguration.hovers) { providers.push( - languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)) + languages.registerHoverProvider(languageId, new languageFeatures.HTMLHoverAdapter(worker)) ); } if (modeConfiguration.documentHighlights) { diff --git a/src/html/languageFeatures.ts b/src/html/languageFeatures.ts index 0ff3766f..d136b432 100644 --- a/src/html/languageFeatures.ts +++ b/src/html/languageFeatures.ts @@ -8,7 +8,6 @@ import * as lsTypes from 'vscode-languageserver-types'; import { languages, editor, - IMarkdownString, Uri, Position, Range, @@ -19,7 +18,8 @@ import { toRange, toTextEdit, fromRange, - CompletionAdapter + CompletionAdapter, + HoverAdapter } from '../common/lspLanguageFeatures'; export interface WorkerAccessor { @@ -32,71 +32,7 @@ export class HTMLCompletionAdapter extends CompletionAdapter { } } -function isMarkupContent(thing: any): thing is lsTypes.MarkupContent { - return ( - thing && typeof thing === 'object' && typeof (thing).kind === 'string' - ); -} - -function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString { - if (typeof entry === 'string') { - return { - value: entry - }; - } - if (isMarkupContent(entry)) { - if (entry.kind === 'plaintext') { - return { - value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&') - }; - } - return { - value: entry.value - }; - } - - return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' }; -} - -function toMarkedStringArray( - contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[] -): IMarkdownString[] | undefined { - if (!contents) { - return void 0; - } - if (Array.isArray(contents)) { - return contents.map(toMarkdownString); - } - return [toMarkdownString(contents)]; -} - -// --- hover ------ - -export class HoverAdapter implements languages.HoverProvider { - constructor(private _worker: WorkerAccessor) {} - - provideHover( - model: editor.IReadOnlyModel, - position: Position, - token: CancellationToken - ): Promise { - let resource = model.uri; - - return this._worker(resource) - .then((worker) => { - return worker.doHover(resource.toString(), fromPosition(position)); - }) - .then((info) => { - if (!info) { - return; - } - return { - range: toRange(info.range), - contents: toMarkedStringArray(info.contents) - }; - }); - } -} +export class HTMLHoverAdapter extends HoverAdapter {} // --- document highlights ------ diff --git a/src/json/jsonMode.ts b/src/json/jsonMode.ts index 767bb550..d962cbb2 100644 --- a/src/json/jsonMode.ts +++ b/src/json/jsonMode.ts @@ -52,7 +52,7 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable { } if (modeConfiguration.hovers) { providers.push( - languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)) + languages.registerHoverProvider(languageId, new languageFeatures.JSONHoverAdapter(worker)) ); } if (modeConfiguration.documentSymbols) { diff --git a/src/json/languageFeatures.ts b/src/json/languageFeatures.ts index 1670135b..f7b7fd10 100644 --- a/src/json/languageFeatures.ts +++ b/src/json/languageFeatures.ts @@ -9,7 +9,6 @@ import * as lsTypes from 'vscode-languageserver-types'; import { languages, editor, - IMarkdownString, Uri, Position, Range, @@ -21,7 +20,8 @@ import { toRange, toTextEdit, fromRange, - CompletionAdapter + CompletionAdapter, + HoverAdapter } from '../common/lspLanguageFeatures'; export interface WorkerAccessor { @@ -57,71 +57,7 @@ export class JSONCompletionAdapter extends CompletionAdapter { } } -function isMarkupContent(thing: any): thing is lsTypes.MarkupContent { - return ( - thing && typeof thing === 'object' && typeof (thing).kind === 'string' - ); -} - -function toMarkdownString(entry: lsTypes.MarkupContent | lsTypes.MarkedString): IMarkdownString { - if (typeof entry === 'string') { - return { - value: entry - }; - } - if (isMarkupContent(entry)) { - if (entry.kind === 'plaintext') { - return { - value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&') - }; - } - return { - value: entry.value - }; - } - - return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' }; -} - -function toMarkedStringArray( - contents: lsTypes.MarkupContent | lsTypes.MarkedString | lsTypes.MarkedString[] -): IMarkdownString[] | undefined { - if (!contents) { - return void 0; - } - if (Array.isArray(contents)) { - return contents.map(toMarkdownString); - } - return [toMarkdownString(contents)]; -} - -// --- hover ------ - -export class HoverAdapter implements languages.HoverProvider { - constructor(private _worker: WorkerAccessor) {} - - provideHover( - model: editor.IReadOnlyModel, - position: Position, - token: CancellationToken - ): Promise { - let resource = model.uri; - - return this._worker(resource) - .then((worker) => { - return worker.doHover(resource.toString(), fromPosition(position)); - }) - .then((info) => { - if (!info) { - return; - } - return { - range: toRange(info.range), - contents: toMarkedStringArray(info.contents) - }; - }); - } -} +export class JSONHoverAdapter extends HoverAdapter {} // --- definition ------