浏览代码

Extract a common `HoverAdapter`

Alex Dima 3 年之前
父节点
当前提交
ca17e09d53

+ 72 - 0
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<lsTypes.Hover | null>;
+}
+
+export class HoverAdapter<T extends ILanguageWorkerWithHover> implements languages.HoverProvider {
+	constructor(private _worker: WorkerAccessor<T>) {}
+
+	provideHover(
+		model: editor.IReadOnlyModel,
+		position: Position,
+		token: CancellationToken
+	): Promise<languages.Hover | undefined> {
+		let resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => {
+				return worker.doHover(resource.toString(), fromPosition(position));
+			})
+			.then((info) => {
+				if (!info) {
+					return;
+				}
+				return <languages.Hover>{
+					range: toRange(info.range),
+					contents: toMarkedStringArray(info.contents)
+				};
+			});
+	}
+}
+
+function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
+	return (
+		thing && typeof thing === 'object' && typeof (<lsTypes.MarkupContent>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

+ 1 - 1
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) {

+ 4 - 74
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<CSSWorker> {
 	}
 }
 
-function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
-	return (
-		thing && typeof thing === 'object' && typeof (<lsTypes.MarkupContent>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<languages.Hover | undefined> {
-		let resource = model.uri;
-
-		return this._worker(resource)
-			.then((worker) => {
-				return worker.doHover(resource.toString(), fromPosition(position));
-			})
-			.then((info) => {
-				if (!info) {
-					return;
-				}
-				return <languages.Hover>{
-					range: toRange(info.range),
-					contents: toMarkedStringArray(info.contents)
-				};
-			});
-	}
-}
+export class CSSHoverAdapter extends HoverAdapter<CSSWorker> {}
 
 // --- document highlights ------
 

+ 2 - 2
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) {

+ 3 - 67
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<HTMLWorker> {
 	}
 }
 
-function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
-	return (
-		thing && typeof thing === 'object' && typeof (<lsTypes.MarkupContent>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<languages.Hover | undefined> {
-		let resource = model.uri;
-
-		return this._worker(resource)
-			.then((worker) => {
-				return worker.doHover(resource.toString(), fromPosition(position));
-			})
-			.then((info) => {
-				if (!info) {
-					return;
-				}
-				return <languages.Hover>{
-					range: toRange(info.range),
-					contents: toMarkedStringArray(info.contents)
-				};
-			});
-	}
-}
+export class HTMLHoverAdapter extends HoverAdapter<HTMLWorker> {}
 
 // --- document highlights ------
 

+ 1 - 1
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) {

+ 3 - 67
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<JSONWorker> {
 	}
 }
 
-function isMarkupContent(thing: any): thing is lsTypes.MarkupContent {
-	return (
-		thing && typeof thing === 'object' && typeof (<lsTypes.MarkupContent>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<languages.Hover | undefined> {
-		let resource = model.uri;
-
-		return this._worker(resource)
-			.then((worker) => {
-				return worker.doHover(resource.toString(), fromPosition(position));
-			})
-			.then((info) => {
-				if (!info) {
-					return;
-				}
-				return <languages.Hover>{
-					range: toRange(info.range),
-					contents: toMarkedStringArray(info.contents)
-				};
-			});
-	}
-}
+export class JSONHoverAdapter extends HoverAdapter<JSONWorker> {}
 
 // --- definition ------