Skip to content

Commit

Permalink
Merge pull request #207 from CGNonofr/bump-monaco-20
Browse files Browse the repository at this point in the history
Bump to monaco-editor 0.20.0
  • Loading branch information
RomanNikitenko authored Jun 2, 2020
2 parents 98f15c6 + e33200f commit fb587b3
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 135 deletions.
4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"typings": "./lib/index",
"dependencies": {
"glob-to-regexp": "^0.3.0",
"vscode-jsonrpc": "^5.0.0",
"vscode-languageclient": "^6.0.0",
"vscode-jsonrpc": "^5.0.1",
"vscode-languageclient": "^6.1.3",
"vscode-uri": "^2.1.1"
},
"scripts": {
Expand Down
95 changes: 52 additions & 43 deletions client/src/monaco-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
MarkedString, MarkupContent, ColorInformation, ColorPresentation, FoldingRange, FoldingRangeKind,
DiagnosticRelatedInformation, MarkupKind, SymbolKind, DocumentSymbol, CodeAction, SignatureHelpContext, SignatureHelpTriggerKind
} from './services';
import { SemanticTokens } from 'vscode-languageserver-protocol/lib/protocol.sematicTokens.proposed'

import IReadOnlyModel = monaco.editor.IReadOnlyModel;

export type RecursivePartial<T> = {
Expand Down Expand Up @@ -56,9 +58,9 @@ export namespace ProtocolCompletionItem {
}
}

type RangeReplace = { insert: monaco.IRange; replace: monaco.IRange}
type RangeReplace = { insert: monaco.IRange; replace: monaco.IRange }

function isRangeReplace(v: Partial<monaco.IRange> | RangeReplace) : v is RangeReplace {
function isRangeReplace(v: Partial<monaco.IRange> | RangeReplace): v is RangeReplace {
return (v as RangeReplace).insert !== undefined;
}

Expand All @@ -81,7 +83,7 @@ export class MonacoToProtocolConverter {
asRange(range: monaco.IRange): Range;
asRange(range: monaco.IRange | undefined): Range | undefined;
asRange(range: monaco.IRange | null): Range | null;
asRange(range: monaco.IRange | { insert: monaco.IRange; replace: monaco.IRange}) : Range;
asRange(range: monaco.IRange | { insert: monaco.IRange; replace: monaco.IRange }): Range;
asRange(range: Partial<monaco.IRange>): RecursivePartial<Range>;
asRange(range: Partial<monaco.IRange> | undefined): RecursivePartial<Range> | undefined;
asRange(range: Partial<monaco.IRange> | null): RecursivePartial<Range> | null;
Expand Down Expand Up @@ -131,7 +133,7 @@ export class MonacoToProtocolConverter {
}
}

asSignatureHelpContext(context: monaco.languages.SignatureHelpContext) : SignatureHelpContext {
asSignatureHelpContext(context: monaco.languages.SignatureHelpContext): SignatureHelpContext {
return {
triggerKind: this.asSignatureHelpTriggerKind(context.triggerKind),
triggerCharacter: context.triggerCharacter,
Expand All @@ -140,8 +142,8 @@ export class MonacoToProtocolConverter {
};
}

asSignatureHelp(signatureHelp: monaco.languages.SignatureHelp | undefined) : SignatureHelp | undefined {
if(signatureHelp === undefined) {
asSignatureHelp(signatureHelp: monaco.languages.SignatureHelp | undefined): SignatureHelp | undefined {
if (signatureHelp === undefined) {
return undefined;
}
return {
Expand All @@ -151,26 +153,26 @@ export class MonacoToProtocolConverter {
};
}

asSignatureInformation(signatureInformation: monaco.languages.SignatureInformation) : SignatureInformation {
asSignatureInformation(signatureInformation: monaco.languages.SignatureInformation): SignatureInformation {
return {
documentation: this.asMarkupContent(signatureInformation.documentation),
label: signatureInformation.label,
parameters: signatureInformation.parameters.map(paramInfo => this.asParameterInformation(paramInfo))
};
}

asParameterInformation(parameterInformation: monaco.languages.ParameterInformation) : ParameterInformation {
asParameterInformation(parameterInformation: monaco.languages.ParameterInformation): ParameterInformation {
return {
documentation: this.asMarkupContent(parameterInformation.documentation),
label: parameterInformation.label
};
}

asMarkupContent(markupContent: (string | monaco.IMarkdownString | undefined)): string | MarkupContent | undefined {
if(markupContent === undefined) {
if (markupContent === undefined) {
return undefined;
}
if(typeof markupContent === "string") {
if (typeof markupContent === "string") {
return markupContent;
}
return {
Expand All @@ -179,8 +181,8 @@ export class MonacoToProtocolConverter {
};
}

asSignatureHelpTriggerKind(triggerKind: monaco.languages.SignatureHelpTriggerKind) : SignatureHelpTriggerKind {
switch (triggerKind) {
asSignatureHelpTriggerKind(triggerKind: monaco.languages.SignatureHelpTriggerKind): SignatureHelpTriggerKind {
switch (triggerKind) {
case monaco.languages.SignatureHelpTriggerKind.ContentChange:
return SignatureHelpTriggerKind.ContentChange;
case monaco.languages.SignatureHelpTriggerKind.TriggerCharacter:
Expand All @@ -202,7 +204,7 @@ export class MonacoToProtocolConverter {
}

asCompletionItem(item: monaco.languages.CompletionItem): CompletionItem {
const result: CompletionItem = { label: item.label };
const result: CompletionItem = { label: item.label as string };
const protocolItem = ProtocolCompletionItem.is(item) ? item : undefined;
if (item.detail) { result.detail = item.detail; }
// We only send items back we created. So this can't be something else than
Expand Down Expand Up @@ -360,7 +362,7 @@ export class MonacoToProtocolConverter {
asDiagnostic(marker: monaco.editor.IMarkerData): Diagnostic {
const range = this.asRange(new monaco.Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn))
const severity = this.asDiagnosticSeverity(marker.severity);
return Diagnostic.create(range, marker.message, severity, marker.code, marker.source);
return Diagnostic.create(range, marker.message, severity, marker.code as string, marker.source);
}

asDiagnostics(markers: monaco.editor.IMarkerData[]): Diagnostic[] {
Expand Down Expand Up @@ -457,12 +459,12 @@ export class MonacoToProtocolConverter {

export class ProtocolToMonacoConverter {

asResourceEdits(resource: monaco.Uri, edits: TextEdit[], modelVersionId?: number): monaco.languages.ResourceTextEdit {
return {
asResourceEdits(resource: monaco.Uri, edits: TextEdit[], modelVersionId?: number): monaco.languages.WorkspaceTextEdit[] {
return edits.map(edit => ({
resource: resource,
edits: this.asTextEdits(edits),
edit: this.asTextEdit(edit),
modelVersionId
}
}))
}

asWorkspaceEdit(item: WorkspaceEdit): monaco.languages.WorkspaceEdit;
Expand All @@ -472,37 +474,37 @@ export class ProtocolToMonacoConverter {
if (!item) {
return undefined;
}
const edits: (monaco.languages.ResourceTextEdit | monaco.languages.ResourceFileEdit)[] = [];
const edits: (monaco.languages.WorkspaceTextEdit | monaco.languages.WorkspaceFileEdit)[] = [];
if (item.documentChanges) {
item.documentChanges.forEach(change => {
if (ls.CreateFile.is(change)) {
edits.push(<monaco.languages.ResourceFileEdit>{
edits.push(<monaco.languages.WorkspaceFileEdit>{
newUri: monaco.Uri.parse(change.uri),
options: change.options
});
} else if (ls.RenameFile.is(change)) {
edits.push(<monaco.languages.ResourceFileEdit>{
edits.push(<monaco.languages.WorkspaceFileEdit>{
oldUri: monaco.Uri.parse(change.oldUri),
newUri: monaco.Uri.parse(change.newUri),
options: change.options
});
} else if (ls.DeleteFile.is(change)) {
edits.push(<monaco.languages.ResourceFileEdit>{
edits.push(<monaco.languages.WorkspaceFileEdit>{
oldUri: monaco.Uri.parse(change.uri),
options: change.options
});
} else if (ls.TextDocumentEdit.is(change)) {
const resource = monaco.Uri.parse(change.textDocument.uri);
const version = typeof change.textDocument.version === 'number' ? change.textDocument.version : undefined;
edits.push(this.asResourceEdits(resource, change.edits, version));
edits.push(...this.asResourceEdits(resource, change.edits, version));
} else {
console.error(`Unknown workspace edit change received:\n${JSON.stringify(change, undefined, 4)}`);
}
});
} else if (item.changes) {
for (const key of Object.keys(item.changes)) {
const resource = monaco.Uri.parse(key);
edits.push(this.asResourceEdits(resource, item.changes[key]));
edits.push(...this.asResourceEdits(resource, item.changes[key]));
}
}
return {
Expand Down Expand Up @@ -557,14 +559,14 @@ export class ProtocolToMonacoConverter {
}
return {
lenses: items.map((codeLens) => this.asCodeLens(codeLens)),
dispose: () => {}
dispose: () => { }
};
}

asCodeActionList(actions: (Command | CodeAction)[]): monaco.languages.CodeActionList {
return {
actions: actions.map(action => this.asCodeAction(action)),
dispose: () => {}
dispose: () => { }
};
}

Expand Down Expand Up @@ -729,22 +731,22 @@ export class ProtocolToMonacoConverter {
}

asLocationLink(item: undefined | null): undefined;
asLocationLink(item: ls.LocationLink): monaco.languages.LocationLink;
asLocationLink(item: ls.LocationLink | undefined | null): monaco.languages.LocationLink | undefined {
if (!item) {
return undefined;
}
let result: monaco.languages.LocationLink = {
uri: monaco.Uri.parse(item.targetUri),
range: this.asRange(item.targetSelectionRange)!, // See issue: https://github.com/Microsoft/vscode/issues/58649
originSelectionRange: this.asRange(item.originSelectionRange),
targetSelectionRange: this.asRange(item.targetSelectionRange)
};
if (!result.targetSelectionRange) {
throw new Error(`targetSelectionRange must not be undefined or null`);
}
return result;
}
asLocationLink(item: ls.LocationLink): monaco.languages.LocationLink;
asLocationLink(item: ls.LocationLink | undefined | null): monaco.languages.LocationLink | undefined {
if (!item) {
return undefined;
}
let result: monaco.languages.LocationLink = {
uri: monaco.Uri.parse(item.targetUri),
range: this.asRange(item.targetSelectionRange)!, // See issue: https://github.com/Microsoft/vscode/issues/58649
originSelectionRange: this.asRange(item.originSelectionRange),
targetSelectionRange: this.asRange(item.targetSelectionRange)
};
if (!result.targetSelectionRange) {
throw new Error(`targetSelectionRange must not be undefined or null`);
}
return result;
}

asSignatureHelpResult(item: undefined | null): undefined;
asSignatureHelpResult(item: SignatureHelp): monaco.languages.SignatureHelpResult;
Expand Down Expand Up @@ -773,7 +775,7 @@ export class ProtocolToMonacoConverter {
}
return {
value: result,
dispose: () => {}
dispose: () => { }
};
}

Expand Down Expand Up @@ -1124,4 +1126,11 @@ export class ProtocolToMonacoConverter {
return undefined;
}

asSemanticTokens(semanticTokens: SemanticTokens): monaco.languages.SemanticTokens {
return {
resultId: semanticTokens.resultId,
data: Uint32Array.from(semanticTokens.data)
}
}

}
7 changes: 7 additions & 0 deletions client/src/monaco-language-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { ImplementationFeature } from "vscode-languageclient/lib/implementation"
import { ColorProviderFeature } from "vscode-languageclient/lib/colorProvider";
import { WorkspaceFoldersFeature } from "vscode-languageclient/lib/workspaceFolders";
import { FoldingRangeFeature } from "vscode-languageclient/lib/foldingRange";
import { CallHierarchyFeature } from "vscode-languageclient/lib/callHierarchy.proposed";
import { SemanticTokensFeature } from "vscode-languageclient/lib/semanticTokens.proposed";
import * as p2c from 'vscode-languageclient/lib/protocolConverter';
import * as c2p from 'vscode-languageclient/lib/codeConverter';
import { IConnectionProvider, IConnection } from './connection';
Expand Down Expand Up @@ -105,6 +107,11 @@ export class MonacoLanguageClient extends BaseLanguageClient {
}
}

public registerProposedFeatures() {
this.registerFeature(new CallHierarchyFeature(this));
this.registerFeature(new SemanticTokensFeature(this));
}

}
export namespace MonacoLanguageClient {
export interface Options {
Expand Down
62 changes: 61 additions & 1 deletion client/src/monaco-languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import {
DocumentSymbolProvider, CodeActionProvider, CodeLensProvider, DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider,
OnTypeFormattingEditProvider, RenameProvider,
DocumentFilter, DocumentSelector, DocumentLinkProvider, ImplementationProvider, TypeDefinitionProvider, DocumentColorProvider,
FoldingRangeProvider
FoldingRangeProvider,
DocumentSemanticTokensProvider, DocumentRangeSemanticTokensProvider
} from "./services";
import { SemanticTokensLegend } from 'vscode-languageserver-protocol/lib/protocol.sematicTokens.proposed'

import { MonacoDiagnosticCollection } from './monaco-diagnostic-collection';
import { ProtocolToMonacoConverter, MonacoToProtocolConverter } from './monaco-converter';
import { DisposableCollection, Disposable } from './disposable';
Expand Down Expand Up @@ -513,6 +516,63 @@ export class MonacoLanguages implements Languages {
}
}

registerDocumentSemanticTokensProvider(selector: DocumentSelector, provider: DocumentSemanticTokensProvider, legend: SemanticTokensLegend): Disposable {
const semanticTokensProvider = this.createSemanticTokensProvider(selector, provider, legend);
const providers = new DisposableCollection();
for (const language of this.matchLanguage(selector)) {
providers.push(monaco.languages.registerDocumentSemanticTokensProvider(language, semanticTokensProvider));
}
return providers;
}

protected createSemanticTokensProvider(selector: DocumentSelector, provider: DocumentSemanticTokensProvider, legend: SemanticTokensLegend): monaco.languages.DocumentSemanticTokensProvider {
return {
getLegend() {
return legend;
},
provideDocumentSemanticTokens: async (model, lastResultId, token) => {
if (!this.matchModel(selector, MonacoModelIdentifier.fromModel(model))) {
return undefined;
}
const textDocument = this.m2p.asTextDocumentIdentifier(model);
const result = await provider.provideDocumentSemanticTokens({
textDocument
}, token);
return result && this.p2m.asSemanticTokens(result);
},
releaseDocumentSemanticTokens: (resultId) => {
}
}
}

registerDocumentRangeSemanticTokensProvider(selector: DocumentSelector, provider: DocumentRangeSemanticTokensProvider, legend: SemanticTokensLegend): Disposable {
const rangeSemanticTokensProvider = this.createRangeSemanticTokensProvider(selector, provider, legend);
const providers = new DisposableCollection();
for (const language of this.matchLanguage(selector)) {
providers.push(monaco.languages.registerDocumentRangeSemanticTokensProvider(language, rangeSemanticTokensProvider));
}
return providers;
}

protected createRangeSemanticTokensProvider(selector: DocumentSelector, provider: DocumentRangeSemanticTokensProvider, legend: SemanticTokensLegend): monaco.languages.DocumentRangeSemanticTokensProvider {
return {
getLegend() {
return legend;
},
provideDocumentRangeSemanticTokens: async (model, range, token) => {
if (!this.matchModel(selector, MonacoModelIdentifier.fromModel(model))) {
return undefined;
}
const textDocument = this.m2p.asTextDocumentIdentifier(model);
const result = await provider.provideDocumentRangeSemanticTokens({
textDocument,
range: this.m2p.asRange(range)
}, token);
return result && this.p2m.asSemanticTokens(result);
}
}
}

protected matchModel(selector: string | DocumentFilter | DocumentSelector, model: MonacoModelIdentifier): boolean {
if (Array.isArray(selector)) {
return selector.some(filter => this.matchModel(filter, model));
Expand Down
13 changes: 5 additions & 8 deletions client/src/monaco-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class MonacoWorkspace implements Workspace {
// Collect all referenced models
const models: { [uri: string]: monaco.editor.IModel } = edit.edits ? edit.edits.reduce(
(acc: { [uri: string]: monaco.editor.IModel }, currentEdit) => {
const textEdit = currentEdit as monaco.languages.ResourceTextEdit;
const textEdit = currentEdit as monaco.languages.WorkspaceTextEdit;
acc[textEdit.resource.toString()] = monaco.editor.getModel(textEdit.resource) as monaco.editor.ITextModel;
return acc;
}, {}
Expand All @@ -104,18 +104,15 @@ export class MonacoWorkspace implements Workspace {
// Group edits by resource so we can batch them when applying
const editsByResource: { [uri: string]: IIdentifiedSingleEditOperation[] } = edit.edits ? edit.edits.reduce(
(acc: { [uri: string]: IIdentifiedSingleEditOperation[] }, currentEdit) => {
const textEdit = currentEdit as monaco.languages.ResourceTextEdit;
const textEdit = currentEdit as monaco.languages.WorkspaceTextEdit;
const uri = textEdit.resource.toString();
if (!(uri in acc)) {
acc[uri] = [];
}
const operations = textEdit.edits.map(edit => {
return {
range: monaco.Range.lift(edit.range as monaco.IRange),
text: edit.text as string,
}
acc[uri].push({
range: monaco.Range.lift(textEdit.edit.range as monaco.IRange),
text: textEdit.edit.text as string,
});
acc[uri].push(...operations);
return acc;
}, {}
) : {};
Expand Down
Loading

0 comments on commit fb587b3

Please sign in to comment.