mirror of
https://github.com/microsoft/monaco-editor.git
synced 2025-12-22 17:25:39 +01:00
Extract a common CompletionAdapter
This commit is contained in:
parent
0312af769b
commit
1c2358bdf9
7 changed files with 282 additions and 656 deletions
|
|
@ -29,12 +29,12 @@ export interface ILanguageWorkerWithDiagnostics {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DiagnosticsAdapter<T extends ILanguageWorkerWithDiagnostics> {
|
export class DiagnosticsAdapter<T extends ILanguageWorkerWithDiagnostics> {
|
||||||
protected _disposables: IDisposable[] = [];
|
protected readonly _disposables: IDisposable[] = [];
|
||||||
private _listener: { [uri: string]: IDisposable } = Object.create(null);
|
private readonly _listener: { [uri: string]: IDisposable } = Object.create(null);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _languageId: string,
|
private readonly _languageId: string,
|
||||||
protected _worker: WorkerAccessor<T>,
|
protected readonly _worker: WorkerAccessor<T>,
|
||||||
configChangeEvent: IEvent<any>
|
configChangeEvent: IEvent<any>
|
||||||
) {
|
) {
|
||||||
const onModelAdd = (model: editor.IModel): void => {
|
const onModelAdd = (model: editor.IModel): void => {
|
||||||
|
|
@ -97,7 +97,7 @@ export class DiagnosticsAdapter<T extends ILanguageWorkerWithDiagnostics> {
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
this._disposables.forEach((d) => d && d.dispose());
|
this._disposables.forEach((d) => d && d.dispose());
|
||||||
this._disposables = [];
|
this._disposables.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _doValidate(resource: Uri, languageId: string): void {
|
private _doValidate(resource: Uri, languageId: string): void {
|
||||||
|
|
@ -149,3 +149,244 @@ function toDiagnostics(resource: Uri, diag: lsTypes.Diagnostic): editor.IMarkerD
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
//#region CompletionAdapter
|
||||||
|
|
||||||
|
export interface ILanguageWorkerWithCompletions {
|
||||||
|
doComplete(uri: string, position: lsTypes.Position): Promise<lsTypes.CompletionList>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CompletionAdapter<T extends ILanguageWorkerWithCompletions>
|
||||||
|
implements languages.CompletionItemProvider
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private readonly _worker: WorkerAccessor<T>,
|
||||||
|
private readonly _triggerCharacters: string[]
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public get triggerCharacters(): string[] {
|
||||||
|
return this._triggerCharacters;
|
||||||
|
}
|
||||||
|
|
||||||
|
provideCompletionItems(
|
||||||
|
model: editor.IReadOnlyModel,
|
||||||
|
position: Position,
|
||||||
|
context: languages.CompletionContext,
|
||||||
|
token: CancellationToken
|
||||||
|
): Promise<languages.CompletionList | undefined> {
|
||||||
|
const resource = model.uri;
|
||||||
|
|
||||||
|
return this._worker(resource)
|
||||||
|
.then((worker) => {
|
||||||
|
return worker.doComplete(resource.toString(), fromPosition(position));
|
||||||
|
})
|
||||||
|
.then((info) => {
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const wordInfo = model.getWordUntilPosition(position);
|
||||||
|
const wordRange = new Range(
|
||||||
|
position.lineNumber,
|
||||||
|
wordInfo.startColumn,
|
||||||
|
position.lineNumber,
|
||||||
|
wordInfo.endColumn
|
||||||
|
);
|
||||||
|
|
||||||
|
const items: languages.CompletionItem[] = info.items.map((entry) => {
|
||||||
|
const item: languages.CompletionItem = {
|
||||||
|
label: entry.label,
|
||||||
|
insertText: entry.insertText || entry.label,
|
||||||
|
sortText: entry.sortText,
|
||||||
|
filterText: entry.filterText,
|
||||||
|
documentation: entry.documentation,
|
||||||
|
detail: entry.detail,
|
||||||
|
command: toCommand(entry.command),
|
||||||
|
range: wordRange,
|
||||||
|
kind: toCompletionItemKind(entry.kind)
|
||||||
|
};
|
||||||
|
if (entry.textEdit) {
|
||||||
|
if (isInsertReplaceEdit(entry.textEdit)) {
|
||||||
|
item.range = {
|
||||||
|
insert: toRange(entry.textEdit.insert),
|
||||||
|
replace: toRange(entry.textEdit.replace)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
item.range = toRange(entry.textEdit.range);
|
||||||
|
}
|
||||||
|
item.insertText = entry.textEdit.newText;
|
||||||
|
}
|
||||||
|
if (entry.additionalTextEdits) {
|
||||||
|
item.additionalTextEdits =
|
||||||
|
entry.additionalTextEdits.map<languages.TextEdit>(toTextEdit);
|
||||||
|
}
|
||||||
|
if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
|
||||||
|
item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
isIncomplete: info.isIncomplete,
|
||||||
|
suggestions: items
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromPosition(position: Position): lsTypes.Position;
|
||||||
|
export function fromPosition(position: undefined): undefined;
|
||||||
|
export function fromPosition(position: Position | undefined): lsTypes.Position | undefined;
|
||||||
|
export function fromPosition(position: Position | undefined): lsTypes.Position | undefined {
|
||||||
|
if (!position) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
return { character: position.column - 1, line: position.lineNumber - 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromRange(range: IRange): lsTypes.Range;
|
||||||
|
export function fromRange(range: undefined): undefined;
|
||||||
|
export function fromRange(range: IRange | undefined): lsTypes.Range | undefined;
|
||||||
|
export function fromRange(range: IRange | undefined): lsTypes.Range | undefined {
|
||||||
|
if (!range) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
start: {
|
||||||
|
line: range.startLineNumber - 1,
|
||||||
|
character: range.startColumn - 1
|
||||||
|
},
|
||||||
|
end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export function toRange(range: lsTypes.Range): Range;
|
||||||
|
export function toRange(range: undefined): undefined;
|
||||||
|
export function toRange(range: lsTypes.Range | undefined): Range | undefined;
|
||||||
|
export function toRange(range: lsTypes.Range | undefined): Range | undefined {
|
||||||
|
if (!range) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
return new Range(
|
||||||
|
range.start.line + 1,
|
||||||
|
range.start.character + 1,
|
||||||
|
range.end.line + 1,
|
||||||
|
range.end.character + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isInsertReplaceEdit(
|
||||||
|
edit: lsTypes.TextEdit | lsTypes.InsertReplaceEdit
|
||||||
|
): edit is lsTypes.InsertReplaceEdit {
|
||||||
|
return (
|
||||||
|
typeof (<lsTypes.InsertReplaceEdit>edit).insert !== 'undefined' &&
|
||||||
|
typeof (<lsTypes.InsertReplaceEdit>edit).replace !== 'undefined'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toCompletionItemKind(kind: number | undefined): languages.CompletionItemKind {
|
||||||
|
const mItemKind = languages.CompletionItemKind;
|
||||||
|
|
||||||
|
switch (kind) {
|
||||||
|
case lsTypes.CompletionItemKind.Text:
|
||||||
|
return mItemKind.Text;
|
||||||
|
case lsTypes.CompletionItemKind.Method:
|
||||||
|
return mItemKind.Method;
|
||||||
|
case lsTypes.CompletionItemKind.Function:
|
||||||
|
return mItemKind.Function;
|
||||||
|
case lsTypes.CompletionItemKind.Constructor:
|
||||||
|
return mItemKind.Constructor;
|
||||||
|
case lsTypes.CompletionItemKind.Field:
|
||||||
|
return mItemKind.Field;
|
||||||
|
case lsTypes.CompletionItemKind.Variable:
|
||||||
|
return mItemKind.Variable;
|
||||||
|
case lsTypes.CompletionItemKind.Class:
|
||||||
|
return mItemKind.Class;
|
||||||
|
case lsTypes.CompletionItemKind.Interface:
|
||||||
|
return mItemKind.Interface;
|
||||||
|
case lsTypes.CompletionItemKind.Module:
|
||||||
|
return mItemKind.Module;
|
||||||
|
case lsTypes.CompletionItemKind.Property:
|
||||||
|
return mItemKind.Property;
|
||||||
|
case lsTypes.CompletionItemKind.Unit:
|
||||||
|
return mItemKind.Unit;
|
||||||
|
case lsTypes.CompletionItemKind.Value:
|
||||||
|
return mItemKind.Value;
|
||||||
|
case lsTypes.CompletionItemKind.Enum:
|
||||||
|
return mItemKind.Enum;
|
||||||
|
case lsTypes.CompletionItemKind.Keyword:
|
||||||
|
return mItemKind.Keyword;
|
||||||
|
case lsTypes.CompletionItemKind.Snippet:
|
||||||
|
return mItemKind.Snippet;
|
||||||
|
case lsTypes.CompletionItemKind.Color:
|
||||||
|
return mItemKind.Color;
|
||||||
|
case lsTypes.CompletionItemKind.File:
|
||||||
|
return mItemKind.File;
|
||||||
|
case lsTypes.CompletionItemKind.Reference:
|
||||||
|
return mItemKind.Reference;
|
||||||
|
}
|
||||||
|
return mItemKind.Property;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromCompletionItemKind(kind: languages.CompletionItemKind): lsTypes.CompletionItemKind {
|
||||||
|
const mItemKind = languages.CompletionItemKind;
|
||||||
|
|
||||||
|
switch (kind) {
|
||||||
|
case mItemKind.Text:
|
||||||
|
return lsTypes.CompletionItemKind.Text;
|
||||||
|
case mItemKind.Method:
|
||||||
|
return lsTypes.CompletionItemKind.Method;
|
||||||
|
case mItemKind.Function:
|
||||||
|
return lsTypes.CompletionItemKind.Function;
|
||||||
|
case mItemKind.Constructor:
|
||||||
|
return lsTypes.CompletionItemKind.Constructor;
|
||||||
|
case mItemKind.Field:
|
||||||
|
return lsTypes.CompletionItemKind.Field;
|
||||||
|
case mItemKind.Variable:
|
||||||
|
return lsTypes.CompletionItemKind.Variable;
|
||||||
|
case mItemKind.Class:
|
||||||
|
return lsTypes.CompletionItemKind.Class;
|
||||||
|
case mItemKind.Interface:
|
||||||
|
return lsTypes.CompletionItemKind.Interface;
|
||||||
|
case mItemKind.Module:
|
||||||
|
return lsTypes.CompletionItemKind.Module;
|
||||||
|
case mItemKind.Property:
|
||||||
|
return lsTypes.CompletionItemKind.Property;
|
||||||
|
case mItemKind.Unit:
|
||||||
|
return lsTypes.CompletionItemKind.Unit;
|
||||||
|
case mItemKind.Value:
|
||||||
|
return lsTypes.CompletionItemKind.Value;
|
||||||
|
case mItemKind.Enum:
|
||||||
|
return lsTypes.CompletionItemKind.Enum;
|
||||||
|
case mItemKind.Keyword:
|
||||||
|
return lsTypes.CompletionItemKind.Keyword;
|
||||||
|
case mItemKind.Snippet:
|
||||||
|
return lsTypes.CompletionItemKind.Snippet;
|
||||||
|
case mItemKind.Color:
|
||||||
|
return lsTypes.CompletionItemKind.Color;
|
||||||
|
case mItemKind.File:
|
||||||
|
return lsTypes.CompletionItemKind.File;
|
||||||
|
case mItemKind.Reference:
|
||||||
|
return lsTypes.CompletionItemKind.Reference;
|
||||||
|
}
|
||||||
|
return lsTypes.CompletionItemKind.Property;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toTextEdit(textEdit: lsTypes.TextEdit): languages.TextEdit;
|
||||||
|
export function toTextEdit(textEdit: undefined): undefined;
|
||||||
|
export function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined;
|
||||||
|
export function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined {
|
||||||
|
if (!textEdit) {
|
||||||
|
return void 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
range: toRange(textEdit.range),
|
||||||
|
text: textEdit.newText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function toCommand(c: lsTypes.Command | undefined): languages.Command | undefined {
|
||||||
|
return c && c.command === 'editor.action.triggerSuggest'
|
||||||
|
? { id: c.command, title: c.title, arguments: c.arguments }
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
|
||||||
providers.push(
|
providers.push(
|
||||||
languages.registerCompletionItemProvider(
|
languages.registerCompletionItemProvider(
|
||||||
languageId,
|
languageId,
|
||||||
new languageFeatures.CompletionAdapter(worker)
|
new languageFeatures.CSSCompletionAdapter(worker)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,207 +12,30 @@ import {
|
||||||
IMarkdownString,
|
IMarkdownString,
|
||||||
Uri,
|
Uri,
|
||||||
Position,
|
Position,
|
||||||
IRange,
|
|
||||||
Range,
|
|
||||||
CancellationToken
|
CancellationToken
|
||||||
} from '../fillers/monaco-editor-core';
|
} from '../fillers/monaco-editor-core';
|
||||||
import { DiagnosticsAdapter } from '../common/lspLanguageFeatures';
|
import {
|
||||||
|
DiagnosticsAdapter,
|
||||||
|
fromPosition,
|
||||||
|
toRange,
|
||||||
|
toTextEdit,
|
||||||
|
fromRange,
|
||||||
|
CompletionAdapter
|
||||||
|
} from '../common/lspLanguageFeatures';
|
||||||
|
|
||||||
export interface WorkerAccessor {
|
export interface WorkerAccessor {
|
||||||
(first: Uri, ...more: Uri[]): Promise<CSSWorker>;
|
(first: Uri, ...more: Uri[]): Promise<CSSWorker>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- diagnostics --- ---
|
|
||||||
|
|
||||||
export class CSSDiagnosticsAdapter extends DiagnosticsAdapter<CSSWorker> {
|
export class CSSDiagnosticsAdapter extends DiagnosticsAdapter<CSSWorker> {
|
||||||
constructor(languageId: string, worker: WorkerAccessor, defaults: LanguageServiceDefaults) {
|
constructor(languageId: string, worker: WorkerAccessor, defaults: LanguageServiceDefaults) {
|
||||||
super(languageId, worker, defaults.onDidChange);
|
super(languageId, worker, defaults.onDidChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- completion ------
|
export class CSSCompletionAdapter extends CompletionAdapter<CSSWorker> {
|
||||||
|
constructor(worker: WorkerAccessor) {
|
||||||
function fromPosition(position: Position): lsTypes.Position;
|
super(worker, ['/', '-', ':']);
|
||||||
function fromPosition(position: undefined): undefined;
|
|
||||||
function fromPosition(position: Position | undefined): lsTypes.Position | undefined;
|
|
||||||
function fromPosition(position: Position | undefined): lsTypes.Position | undefined {
|
|
||||||
if (!position) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return { character: position.column - 1, line: position.lineNumber - 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromRange(range: IRange): lsTypes.Range;
|
|
||||||
function fromRange(range: undefined): undefined;
|
|
||||||
function fromRange(range: IRange | undefined): lsTypes.Range | undefined;
|
|
||||||
function fromRange(range: IRange | undefined): lsTypes.Range | undefined {
|
|
||||||
if (!range) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
start: {
|
|
||||||
line: range.startLineNumber - 1,
|
|
||||||
character: range.startColumn - 1
|
|
||||||
},
|
|
||||||
end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function toRange(range: lsTypes.Range): Range;
|
|
||||||
function toRange(range: undefined): undefined;
|
|
||||||
function toRange(range: lsTypes.Range | undefined): Range | undefined;
|
|
||||||
function toRange(range: lsTypes.Range | undefined): Range | undefined {
|
|
||||||
if (!range) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return new Range(
|
|
||||||
range.start.line + 1,
|
|
||||||
range.start.character + 1,
|
|
||||||
range.end.line + 1,
|
|
||||||
range.end.character + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isInsertReplaceEdit(
|
|
||||||
edit: lsTypes.TextEdit | lsTypes.InsertReplaceEdit
|
|
||||||
): edit is lsTypes.InsertReplaceEdit {
|
|
||||||
return (
|
|
||||||
typeof (<lsTypes.InsertReplaceEdit>edit).insert !== 'undefined' &&
|
|
||||||
typeof (<lsTypes.InsertReplaceEdit>edit).replace !== 'undefined'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCompletionItemKind(kind: number | undefined): languages.CompletionItemKind {
|
|
||||||
const mItemKind = languages.CompletionItemKind;
|
|
||||||
|
|
||||||
switch (kind) {
|
|
||||||
case lsTypes.CompletionItemKind.Text:
|
|
||||||
return mItemKind.Text;
|
|
||||||
case lsTypes.CompletionItemKind.Method:
|
|
||||||
return mItemKind.Method;
|
|
||||||
case lsTypes.CompletionItemKind.Function:
|
|
||||||
return mItemKind.Function;
|
|
||||||
case lsTypes.CompletionItemKind.Constructor:
|
|
||||||
return mItemKind.Constructor;
|
|
||||||
case lsTypes.CompletionItemKind.Field:
|
|
||||||
return mItemKind.Field;
|
|
||||||
case lsTypes.CompletionItemKind.Variable:
|
|
||||||
return mItemKind.Variable;
|
|
||||||
case lsTypes.CompletionItemKind.Class:
|
|
||||||
return mItemKind.Class;
|
|
||||||
case lsTypes.CompletionItemKind.Interface:
|
|
||||||
return mItemKind.Interface;
|
|
||||||
case lsTypes.CompletionItemKind.Module:
|
|
||||||
return mItemKind.Module;
|
|
||||||
case lsTypes.CompletionItemKind.Property:
|
|
||||||
return mItemKind.Property;
|
|
||||||
case lsTypes.CompletionItemKind.Unit:
|
|
||||||
return mItemKind.Unit;
|
|
||||||
case lsTypes.CompletionItemKind.Value:
|
|
||||||
return mItemKind.Value;
|
|
||||||
case lsTypes.CompletionItemKind.Enum:
|
|
||||||
return mItemKind.Enum;
|
|
||||||
case lsTypes.CompletionItemKind.Keyword:
|
|
||||||
return mItemKind.Keyword;
|
|
||||||
case lsTypes.CompletionItemKind.Snippet:
|
|
||||||
return mItemKind.Snippet;
|
|
||||||
case lsTypes.CompletionItemKind.Color:
|
|
||||||
return mItemKind.Color;
|
|
||||||
case lsTypes.CompletionItemKind.File:
|
|
||||||
return mItemKind.File;
|
|
||||||
case lsTypes.CompletionItemKind.Reference:
|
|
||||||
return mItemKind.Reference;
|
|
||||||
}
|
|
||||||
return mItemKind.Property;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit): languages.TextEdit;
|
|
||||||
function toTextEdit(textEdit: undefined): undefined;
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined;
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined {
|
|
||||||
if (!textEdit) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
range: toRange(textEdit.range),
|
|
||||||
text: textEdit.newText
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCommand(c: lsTypes.Command | undefined): languages.Command | undefined {
|
|
||||||
return c && c.command === 'editor.action.triggerSuggest'
|
|
||||||
? { id: c.command, title: c.title, arguments: c.arguments }
|
|
||||||
: undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CompletionAdapter implements languages.CompletionItemProvider {
|
|
||||||
constructor(private _worker: WorkerAccessor) {}
|
|
||||||
|
|
||||||
public get triggerCharacters(): string[] {
|
|
||||||
return ['/', '-', ':'];
|
|
||||||
}
|
|
||||||
|
|
||||||
provideCompletionItems(
|
|
||||||
model: editor.IReadOnlyModel,
|
|
||||||
position: Position,
|
|
||||||
context: languages.CompletionContext,
|
|
||||||
token: CancellationToken
|
|
||||||
): Promise<languages.CompletionList | undefined> {
|
|
||||||
const resource = model.uri;
|
|
||||||
|
|
||||||
return this._worker(resource)
|
|
||||||
.then((worker) => {
|
|
||||||
return worker.doComplete(resource.toString(), fromPosition(position));
|
|
||||||
})
|
|
||||||
.then((info) => {
|
|
||||||
if (!info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const wordInfo = model.getWordUntilPosition(position);
|
|
||||||
const wordRange = new Range(
|
|
||||||
position.lineNumber,
|
|
||||||
wordInfo.startColumn,
|
|
||||||
position.lineNumber,
|
|
||||||
wordInfo.endColumn
|
|
||||||
);
|
|
||||||
|
|
||||||
const items: languages.CompletionItem[] = info.items.map((entry) => {
|
|
||||||
const item: languages.CompletionItem = {
|
|
||||||
label: entry.label,
|
|
||||||
insertText: entry.insertText || entry.label,
|
|
||||||
sortText: entry.sortText,
|
|
||||||
filterText: entry.filterText,
|
|
||||||
documentation: entry.documentation,
|
|
||||||
detail: entry.detail,
|
|
||||||
command: toCommand(entry.command),
|
|
||||||
range: wordRange,
|
|
||||||
kind: toCompletionItemKind(entry.kind)
|
|
||||||
};
|
|
||||||
if (entry.textEdit) {
|
|
||||||
if (isInsertReplaceEdit(entry.textEdit)) {
|
|
||||||
item.range = {
|
|
||||||
insert: toRange(entry.textEdit.insert),
|
|
||||||
replace: toRange(entry.textEdit.replace)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
item.range = toRange(entry.textEdit.range);
|
|
||||||
}
|
|
||||||
item.insertText = entry.textEdit.newText;
|
|
||||||
}
|
|
||||||
if (entry.additionalTextEdits) {
|
|
||||||
item.additionalTextEdits =
|
|
||||||
entry.additionalTextEdits.map<languages.TextEdit>(toTextEdit);
|
|
||||||
}
|
|
||||||
if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
|
|
||||||
item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
isIncomplete: info.isIncomplete,
|
|
||||||
suggestions: items
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export function setupMode1(defaults: LanguageServiceDefaults): void {
|
||||||
// all modes
|
// all modes
|
||||||
languages.registerCompletionItemProvider(
|
languages.registerCompletionItemProvider(
|
||||||
languageId,
|
languageId,
|
||||||
new languageFeatures.CompletionAdapter(worker)
|
new languageFeatures.HTMLCompletionAdapter(worker)
|
||||||
);
|
);
|
||||||
languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker));
|
languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker));
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
|
||||||
providers.push(
|
providers.push(
|
||||||
languages.registerCompletionItemProvider(
|
languages.registerCompletionItemProvider(
|
||||||
languageId,
|
languageId,
|
||||||
new languageFeatures.CompletionAdapter(worker)
|
new languageFeatures.HTMLCompletionAdapter(worker)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,242 +11,24 @@ import {
|
||||||
IMarkdownString,
|
IMarkdownString,
|
||||||
Uri,
|
Uri,
|
||||||
Position,
|
Position,
|
||||||
IRange,
|
|
||||||
Range,
|
Range,
|
||||||
CancellationToken
|
CancellationToken
|
||||||
} from '../fillers/monaco-editor-core';
|
} from '../fillers/monaco-editor-core';
|
||||||
|
import {
|
||||||
|
fromPosition,
|
||||||
|
toRange,
|
||||||
|
toTextEdit,
|
||||||
|
fromRange,
|
||||||
|
CompletionAdapter
|
||||||
|
} from '../common/lspLanguageFeatures';
|
||||||
|
|
||||||
export interface WorkerAccessor {
|
export interface WorkerAccessor {
|
||||||
(...more: Uri[]): Promise<HTMLWorker>;
|
(...more: Uri[]): Promise<HTMLWorker>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- completion ------
|
export class HTMLCompletionAdapter extends CompletionAdapter<HTMLWorker> {
|
||||||
|
constructor(worker: WorkerAccessor) {
|
||||||
function fromPosition(position: Position): lsTypes.Position;
|
super(worker, ['.', ':', '<', '"', '=', '/']);
|
||||||
function fromPosition(position: undefined): undefined;
|
|
||||||
function fromPosition(position: Position | undefined): lsTypes.Position | undefined;
|
|
||||||
function fromPosition(position: Position | undefined): lsTypes.Position | undefined {
|
|
||||||
if (!position) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return { character: position.column - 1, line: position.lineNumber - 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromRange(range: IRange): lsTypes.Range;
|
|
||||||
function fromRange(range: undefined): undefined;
|
|
||||||
function fromRange(range: IRange | undefined): lsTypes.Range | undefined;
|
|
||||||
function fromRange(range: IRange | undefined): lsTypes.Range | undefined {
|
|
||||||
if (!range) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
start: {
|
|
||||||
line: range.startLineNumber - 1,
|
|
||||||
character: range.startColumn - 1
|
|
||||||
},
|
|
||||||
end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function toRange(range: lsTypes.Range): Range;
|
|
||||||
function toRange(range: undefined): undefined;
|
|
||||||
function toRange(range: lsTypes.Range | undefined): Range | undefined;
|
|
||||||
function toRange(range: lsTypes.Range | undefined): Range | undefined {
|
|
||||||
if (!range) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return new Range(
|
|
||||||
range.start.line + 1,
|
|
||||||
range.start.character + 1,
|
|
||||||
range.end.line + 1,
|
|
||||||
range.end.character + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isInsertReplaceEdit(
|
|
||||||
edit: lsTypes.TextEdit | lsTypes.InsertReplaceEdit
|
|
||||||
): edit is lsTypes.InsertReplaceEdit {
|
|
||||||
return (
|
|
||||||
typeof (<lsTypes.InsertReplaceEdit>edit).insert !== 'undefined' &&
|
|
||||||
typeof (<lsTypes.InsertReplaceEdit>edit).replace !== 'undefined'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCompletionItemKind(kind: number | undefined): languages.CompletionItemKind {
|
|
||||||
const mItemKind = languages.CompletionItemKind;
|
|
||||||
|
|
||||||
switch (kind) {
|
|
||||||
case lsTypes.CompletionItemKind.Text:
|
|
||||||
return mItemKind.Text;
|
|
||||||
case lsTypes.CompletionItemKind.Method:
|
|
||||||
return mItemKind.Method;
|
|
||||||
case lsTypes.CompletionItemKind.Function:
|
|
||||||
return mItemKind.Function;
|
|
||||||
case lsTypes.CompletionItemKind.Constructor:
|
|
||||||
return mItemKind.Constructor;
|
|
||||||
case lsTypes.CompletionItemKind.Field:
|
|
||||||
return mItemKind.Field;
|
|
||||||
case lsTypes.CompletionItemKind.Variable:
|
|
||||||
return mItemKind.Variable;
|
|
||||||
case lsTypes.CompletionItemKind.Class:
|
|
||||||
return mItemKind.Class;
|
|
||||||
case lsTypes.CompletionItemKind.Interface:
|
|
||||||
return mItemKind.Interface;
|
|
||||||
case lsTypes.CompletionItemKind.Module:
|
|
||||||
return mItemKind.Module;
|
|
||||||
case lsTypes.CompletionItemKind.Property:
|
|
||||||
return mItemKind.Property;
|
|
||||||
case lsTypes.CompletionItemKind.Unit:
|
|
||||||
return mItemKind.Unit;
|
|
||||||
case lsTypes.CompletionItemKind.Value:
|
|
||||||
return mItemKind.Value;
|
|
||||||
case lsTypes.CompletionItemKind.Enum:
|
|
||||||
return mItemKind.Enum;
|
|
||||||
case lsTypes.CompletionItemKind.Keyword:
|
|
||||||
return mItemKind.Keyword;
|
|
||||||
case lsTypes.CompletionItemKind.Snippet:
|
|
||||||
return mItemKind.Snippet;
|
|
||||||
case lsTypes.CompletionItemKind.Color:
|
|
||||||
return mItemKind.Color;
|
|
||||||
case lsTypes.CompletionItemKind.File:
|
|
||||||
return mItemKind.File;
|
|
||||||
case lsTypes.CompletionItemKind.Reference:
|
|
||||||
return mItemKind.Reference;
|
|
||||||
}
|
|
||||||
return mItemKind.Property;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromCompletionItemKind(kind: languages.CompletionItemKind): lsTypes.CompletionItemKind {
|
|
||||||
const mItemKind = languages.CompletionItemKind;
|
|
||||||
|
|
||||||
switch (kind) {
|
|
||||||
case mItemKind.Text:
|
|
||||||
return lsTypes.CompletionItemKind.Text;
|
|
||||||
case mItemKind.Method:
|
|
||||||
return lsTypes.CompletionItemKind.Method;
|
|
||||||
case mItemKind.Function:
|
|
||||||
return lsTypes.CompletionItemKind.Function;
|
|
||||||
case mItemKind.Constructor:
|
|
||||||
return lsTypes.CompletionItemKind.Constructor;
|
|
||||||
case mItemKind.Field:
|
|
||||||
return lsTypes.CompletionItemKind.Field;
|
|
||||||
case mItemKind.Variable:
|
|
||||||
return lsTypes.CompletionItemKind.Variable;
|
|
||||||
case mItemKind.Class:
|
|
||||||
return lsTypes.CompletionItemKind.Class;
|
|
||||||
case mItemKind.Interface:
|
|
||||||
return lsTypes.CompletionItemKind.Interface;
|
|
||||||
case mItemKind.Module:
|
|
||||||
return lsTypes.CompletionItemKind.Module;
|
|
||||||
case mItemKind.Property:
|
|
||||||
return lsTypes.CompletionItemKind.Property;
|
|
||||||
case mItemKind.Unit:
|
|
||||||
return lsTypes.CompletionItemKind.Unit;
|
|
||||||
case mItemKind.Value:
|
|
||||||
return lsTypes.CompletionItemKind.Value;
|
|
||||||
case mItemKind.Enum:
|
|
||||||
return lsTypes.CompletionItemKind.Enum;
|
|
||||||
case mItemKind.Keyword:
|
|
||||||
return lsTypes.CompletionItemKind.Keyword;
|
|
||||||
case mItemKind.Snippet:
|
|
||||||
return lsTypes.CompletionItemKind.Snippet;
|
|
||||||
case mItemKind.Color:
|
|
||||||
return lsTypes.CompletionItemKind.Color;
|
|
||||||
case mItemKind.File:
|
|
||||||
return lsTypes.CompletionItemKind.File;
|
|
||||||
case mItemKind.Reference:
|
|
||||||
return lsTypes.CompletionItemKind.Reference;
|
|
||||||
}
|
|
||||||
return lsTypes.CompletionItemKind.Property;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit): languages.TextEdit;
|
|
||||||
function toTextEdit(textEdit: undefined): undefined;
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined;
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined {
|
|
||||||
if (!textEdit) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
range: toRange(textEdit.range),
|
|
||||||
text: textEdit.newText
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCommand(c: lsTypes.Command | undefined): languages.Command | undefined {
|
|
||||||
return c && c.command === 'editor.action.triggerSuggest'
|
|
||||||
? { id: c.command, title: c.title, arguments: c.arguments }
|
|
||||||
: undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CompletionAdapter implements languages.CompletionItemProvider {
|
|
||||||
constructor(private _worker: WorkerAccessor) {}
|
|
||||||
|
|
||||||
public get triggerCharacters(): string[] {
|
|
||||||
return ['.', ':', '<', '"', '=', '/'];
|
|
||||||
}
|
|
||||||
|
|
||||||
provideCompletionItems(
|
|
||||||
model: editor.IReadOnlyModel,
|
|
||||||
position: Position,
|
|
||||||
context: languages.CompletionContext,
|
|
||||||
token: CancellationToken
|
|
||||||
): Promise<languages.CompletionList | undefined> {
|
|
||||||
const resource = model.uri;
|
|
||||||
|
|
||||||
return this._worker(resource)
|
|
||||||
.then((worker) => {
|
|
||||||
return worker.doComplete(resource.toString(), fromPosition(position));
|
|
||||||
})
|
|
||||||
.then((info) => {
|
|
||||||
if (!info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const wordInfo = model.getWordUntilPosition(position);
|
|
||||||
const wordRange = new Range(
|
|
||||||
position.lineNumber,
|
|
||||||
wordInfo.startColumn,
|
|
||||||
position.lineNumber,
|
|
||||||
wordInfo.endColumn
|
|
||||||
);
|
|
||||||
|
|
||||||
const items: languages.CompletionItem[] = info.items.map((entry) => {
|
|
||||||
const item: languages.CompletionItem = {
|
|
||||||
label: entry.label,
|
|
||||||
insertText: entry.insertText || entry.label,
|
|
||||||
sortText: entry.sortText,
|
|
||||||
filterText: entry.filterText,
|
|
||||||
documentation: entry.documentation,
|
|
||||||
detail: entry.detail,
|
|
||||||
command: toCommand(entry.command),
|
|
||||||
range: wordRange,
|
|
||||||
kind: toCompletionItemKind(entry.kind)
|
|
||||||
};
|
|
||||||
if (entry.textEdit) {
|
|
||||||
if (isInsertReplaceEdit(entry.textEdit)) {
|
|
||||||
item.range = {
|
|
||||||
insert: toRange(entry.textEdit.insert),
|
|
||||||
replace: toRange(entry.textEdit.replace)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
item.range = toRange(entry.textEdit.range);
|
|
||||||
}
|
|
||||||
item.insertText = entry.textEdit.newText;
|
|
||||||
}
|
|
||||||
if (entry.additionalTextEdits) {
|
|
||||||
item.additionalTextEdits =
|
|
||||||
entry.additionalTextEdits.map<languages.TextEdit>(toTextEdit);
|
|
||||||
}
|
|
||||||
if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
|
|
||||||
item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
isIncomplete: info.isIncomplete,
|
|
||||||
suggestions: items
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
|
||||||
providers.push(
|
providers.push(
|
||||||
languages.registerCompletionItemProvider(
|
languages.registerCompletionItemProvider(
|
||||||
languageId,
|
languageId,
|
||||||
new languageFeatures.CompletionAdapter(worker)
|
new languageFeatures.JSONCompletionAdapter(worker)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,22 @@ import {
|
||||||
IMarkdownString,
|
IMarkdownString,
|
||||||
Uri,
|
Uri,
|
||||||
Position,
|
Position,
|
||||||
IRange,
|
|
||||||
Range,
|
Range,
|
||||||
CancellationToken
|
CancellationToken
|
||||||
} from '../fillers/monaco-editor-core';
|
} from '../fillers/monaco-editor-core';
|
||||||
import { DiagnosticsAdapter } from '../common/lspLanguageFeatures';
|
import {
|
||||||
|
DiagnosticsAdapter,
|
||||||
|
fromPosition,
|
||||||
|
toRange,
|
||||||
|
toTextEdit,
|
||||||
|
fromRange,
|
||||||
|
CompletionAdapter
|
||||||
|
} from '../common/lspLanguageFeatures';
|
||||||
|
|
||||||
export interface WorkerAccessor {
|
export interface WorkerAccessor {
|
||||||
(...more: Uri[]): Promise<JSONWorker>;
|
(...more: Uri[]): Promise<JSONWorker>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- diagnostics --- ---
|
|
||||||
|
|
||||||
export class JSONDiagnosticsAdapter extends DiagnosticsAdapter<JSONWorker> {
|
export class JSONDiagnosticsAdapter extends DiagnosticsAdapter<JSONWorker> {
|
||||||
constructor(languageId: string, worker: WorkerAccessor, defaults: LanguageServiceDefaults) {
|
constructor(languageId: string, worker: WorkerAccessor, defaults: LanguageServiceDefaults) {
|
||||||
super(languageId, worker, defaults.onDidChange);
|
super(languageId, worker, defaults.onDidChange);
|
||||||
|
|
@ -47,233 +51,9 @@ export class JSONDiagnosticsAdapter extends DiagnosticsAdapter<JSONWorker> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- completion ------
|
export class JSONCompletionAdapter extends CompletionAdapter<JSONWorker> {
|
||||||
|
constructor(worker: WorkerAccessor) {
|
||||||
function fromPosition(position: Position): lsTypes.Position;
|
super(worker, [' ', ':', '"']);
|
||||||
function fromPosition(position: undefined): undefined;
|
|
||||||
function fromPosition(position: Position | undefined): lsTypes.Position | undefined;
|
|
||||||
function fromPosition(position: Position | undefined): lsTypes.Position | undefined {
|
|
||||||
if (!position) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return { character: position.column - 1, line: position.lineNumber - 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromRange(range: IRange): lsTypes.Range;
|
|
||||||
function fromRange(range: undefined): undefined;
|
|
||||||
function fromRange(range: IRange | undefined): lsTypes.Range | undefined;
|
|
||||||
function fromRange(range: IRange | undefined): lsTypes.Range | undefined {
|
|
||||||
if (!range) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
start: {
|
|
||||||
line: range.startLineNumber - 1,
|
|
||||||
character: range.startColumn - 1
|
|
||||||
},
|
|
||||||
end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function toRange(range: lsTypes.Range): Range;
|
|
||||||
function toRange(range: undefined): undefined;
|
|
||||||
function toRange(range: lsTypes.Range | undefined): Range | undefined;
|
|
||||||
function toRange(range: lsTypes.Range | undefined): Range | undefined {
|
|
||||||
if (!range) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return new Range(
|
|
||||||
range.start.line + 1,
|
|
||||||
range.start.character + 1,
|
|
||||||
range.end.line + 1,
|
|
||||||
range.end.character + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isInsertReplaceEdit(
|
|
||||||
edit: lsTypes.TextEdit | lsTypes.InsertReplaceEdit
|
|
||||||
): edit is lsTypes.InsertReplaceEdit {
|
|
||||||
return (
|
|
||||||
typeof (<lsTypes.InsertReplaceEdit>edit).insert !== 'undefined' &&
|
|
||||||
typeof (<lsTypes.InsertReplaceEdit>edit).replace !== 'undefined'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCompletionItemKind(kind: number | undefined): languages.CompletionItemKind {
|
|
||||||
const mItemKind = languages.CompletionItemKind;
|
|
||||||
|
|
||||||
switch (kind) {
|
|
||||||
case lsTypes.CompletionItemKind.Text:
|
|
||||||
return mItemKind.Text;
|
|
||||||
case lsTypes.CompletionItemKind.Method:
|
|
||||||
return mItemKind.Method;
|
|
||||||
case lsTypes.CompletionItemKind.Function:
|
|
||||||
return mItemKind.Function;
|
|
||||||
case lsTypes.CompletionItemKind.Constructor:
|
|
||||||
return mItemKind.Constructor;
|
|
||||||
case lsTypes.CompletionItemKind.Field:
|
|
||||||
return mItemKind.Field;
|
|
||||||
case lsTypes.CompletionItemKind.Variable:
|
|
||||||
return mItemKind.Variable;
|
|
||||||
case lsTypes.CompletionItemKind.Class:
|
|
||||||
return mItemKind.Class;
|
|
||||||
case lsTypes.CompletionItemKind.Interface:
|
|
||||||
return mItemKind.Interface;
|
|
||||||
case lsTypes.CompletionItemKind.Module:
|
|
||||||
return mItemKind.Module;
|
|
||||||
case lsTypes.CompletionItemKind.Property:
|
|
||||||
return mItemKind.Property;
|
|
||||||
case lsTypes.CompletionItemKind.Unit:
|
|
||||||
return mItemKind.Unit;
|
|
||||||
case lsTypes.CompletionItemKind.Value:
|
|
||||||
return mItemKind.Value;
|
|
||||||
case lsTypes.CompletionItemKind.Enum:
|
|
||||||
return mItemKind.Enum;
|
|
||||||
case lsTypes.CompletionItemKind.Keyword:
|
|
||||||
return mItemKind.Keyword;
|
|
||||||
case lsTypes.CompletionItemKind.Snippet:
|
|
||||||
return mItemKind.Snippet;
|
|
||||||
case lsTypes.CompletionItemKind.Color:
|
|
||||||
return mItemKind.Color;
|
|
||||||
case lsTypes.CompletionItemKind.File:
|
|
||||||
return mItemKind.File;
|
|
||||||
case lsTypes.CompletionItemKind.Reference:
|
|
||||||
return mItemKind.Reference;
|
|
||||||
}
|
|
||||||
return mItemKind.Property;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromCompletionItemKind(kind: languages.CompletionItemKind): lsTypes.CompletionItemKind {
|
|
||||||
const mItemKind = languages.CompletionItemKind;
|
|
||||||
|
|
||||||
switch (kind) {
|
|
||||||
case mItemKind.Text:
|
|
||||||
return lsTypes.CompletionItemKind.Text;
|
|
||||||
case mItemKind.Method:
|
|
||||||
return lsTypes.CompletionItemKind.Method;
|
|
||||||
case mItemKind.Function:
|
|
||||||
return lsTypes.CompletionItemKind.Function;
|
|
||||||
case mItemKind.Constructor:
|
|
||||||
return lsTypes.CompletionItemKind.Constructor;
|
|
||||||
case mItemKind.Field:
|
|
||||||
return lsTypes.CompletionItemKind.Field;
|
|
||||||
case mItemKind.Variable:
|
|
||||||
return lsTypes.CompletionItemKind.Variable;
|
|
||||||
case mItemKind.Class:
|
|
||||||
return lsTypes.CompletionItemKind.Class;
|
|
||||||
case mItemKind.Interface:
|
|
||||||
return lsTypes.CompletionItemKind.Interface;
|
|
||||||
case mItemKind.Module:
|
|
||||||
return lsTypes.CompletionItemKind.Module;
|
|
||||||
case mItemKind.Property:
|
|
||||||
return lsTypes.CompletionItemKind.Property;
|
|
||||||
case mItemKind.Unit:
|
|
||||||
return lsTypes.CompletionItemKind.Unit;
|
|
||||||
case mItemKind.Value:
|
|
||||||
return lsTypes.CompletionItemKind.Value;
|
|
||||||
case mItemKind.Enum:
|
|
||||||
return lsTypes.CompletionItemKind.Enum;
|
|
||||||
case mItemKind.Keyword:
|
|
||||||
return lsTypes.CompletionItemKind.Keyword;
|
|
||||||
case mItemKind.Snippet:
|
|
||||||
return lsTypes.CompletionItemKind.Snippet;
|
|
||||||
case mItemKind.Color:
|
|
||||||
return lsTypes.CompletionItemKind.Color;
|
|
||||||
case mItemKind.File:
|
|
||||||
return lsTypes.CompletionItemKind.File;
|
|
||||||
case mItemKind.Reference:
|
|
||||||
return lsTypes.CompletionItemKind.Reference;
|
|
||||||
}
|
|
||||||
return lsTypes.CompletionItemKind.Property;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit): languages.TextEdit;
|
|
||||||
function toTextEdit(textEdit: undefined): undefined;
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined;
|
|
||||||
function toTextEdit(textEdit: lsTypes.TextEdit | undefined): languages.TextEdit | undefined {
|
|
||||||
if (!textEdit) {
|
|
||||||
return void 0;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
range: toRange(textEdit.range),
|
|
||||||
text: textEdit.newText
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCommand(c: lsTypes.Command | undefined): languages.Command | undefined {
|
|
||||||
return c && c.command === 'editor.action.triggerSuggest'
|
|
||||||
? { id: c.command, title: c.title, arguments: c.arguments }
|
|
||||||
: undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CompletionAdapter implements languages.CompletionItemProvider {
|
|
||||||
constructor(private _worker: WorkerAccessor) {}
|
|
||||||
|
|
||||||
public get triggerCharacters(): string[] {
|
|
||||||
return [' ', ':', '"'];
|
|
||||||
}
|
|
||||||
|
|
||||||
provideCompletionItems(
|
|
||||||
model: editor.IReadOnlyModel,
|
|
||||||
position: Position,
|
|
||||||
context: languages.CompletionContext,
|
|
||||||
token: CancellationToken
|
|
||||||
): Promise<languages.CompletionList | undefined> {
|
|
||||||
const resource = model.uri;
|
|
||||||
|
|
||||||
return this._worker(resource)
|
|
||||||
.then((worker) => {
|
|
||||||
return worker.doComplete(resource.toString(), fromPosition(position));
|
|
||||||
})
|
|
||||||
.then((info) => {
|
|
||||||
if (!info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const wordInfo = model.getWordUntilPosition(position);
|
|
||||||
const wordRange = new Range(
|
|
||||||
position.lineNumber,
|
|
||||||
wordInfo.startColumn,
|
|
||||||
position.lineNumber,
|
|
||||||
wordInfo.endColumn
|
|
||||||
);
|
|
||||||
|
|
||||||
const items: languages.CompletionItem[] = info.items.map((entry) => {
|
|
||||||
const item: languages.CompletionItem = {
|
|
||||||
label: entry.label,
|
|
||||||
insertText: entry.insertText || entry.label,
|
|
||||||
sortText: entry.sortText,
|
|
||||||
filterText: entry.filterText,
|
|
||||||
documentation: entry.documentation,
|
|
||||||
detail: entry.detail,
|
|
||||||
command: toCommand(entry.command),
|
|
||||||
range: wordRange,
|
|
||||||
kind: toCompletionItemKind(entry.kind)
|
|
||||||
};
|
|
||||||
if (entry.textEdit) {
|
|
||||||
if (isInsertReplaceEdit(entry.textEdit)) {
|
|
||||||
item.range = {
|
|
||||||
insert: toRange(entry.textEdit.insert),
|
|
||||||
replace: toRange(entry.textEdit.replace)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
item.range = toRange(entry.textEdit.range);
|
|
||||||
}
|
|
||||||
item.insertText = entry.textEdit.newText;
|
|
||||||
}
|
|
||||||
if (entry.additionalTextEdits) {
|
|
||||||
item.additionalTextEdits =
|
|
||||||
entry.additionalTextEdits.map<languages.TextEdit>(toTextEdit);
|
|
||||||
}
|
|
||||||
if (entry.insertTextFormat === lsTypes.InsertTextFormat.Snippet) {
|
|
||||||
item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
isIncomplete: info.isIncomplete,
|
|
||||||
suggestions: items
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue