Browse Source

add selection ranges

Martin Aeschlimann 5 năm trước cách đây
mục cha
commit
3835b013c3
6 tập tin đã thay đổi với 220 bổ sung181 xóa
  1. 3 3
      package.json
  2. 3 0
      src/jsonMode.ts
  3. 24 19
      src/jsonWorker.ts
  4. 106 81
      src/languageFeatures.ts
  5. 2 1
      src/monaco.contribution.ts
  6. 82 77
      src/monaco.d.ts

+ 3 - 3
package.json

@@ -25,9 +25,9 @@
     "monaco-plugin-helpers": "^1.0.2",
     "requirejs": "^2.3.6",
     "typescript": "3.7.3",
-    "terser": "^4.4.2",
+    "terser": "^4.4.3",
     "vscode-json-languageservice": "3.4.10",
-    "vscode-languageserver-types": "3.14.0",
-    "vscode-languageserver-textdocument": "1.0.0-next.5"
+    "vscode-languageserver-types": "3.15.0-next.9",
+    "vscode-languageserver-textdocument": "^1.0.0-next.5"
   }
 }

+ 3 - 0
src/jsonMode.ts

@@ -58,6 +58,9 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable {
 		if (modeConfiguration.diagnostics) {
 			providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults));
 		}
+		if (modeConfiguration.selectionRanges) {
+			providers.push(monaco.languages.registerSelectionRangeProvider(languageId, new languageFeatures.SelectionRangeAdapter(worker)));
+		}
 	}
 
 	registerProviders();

+ 24 - 19
src/jsonWorker.ts

@@ -8,11 +8,10 @@ import Thenable = monaco.Thenable;
 import IWorkerContext = monaco.worker.IWorkerContext;
 
 import * as jsonService from 'vscode-json-languageservice';
-import * as ls from 'vscode-languageserver-types';
 
 let defaultSchemaRequestService;
-if (typeof fetch !== 'undefined'){
-	defaultSchemaRequestService = function (url) { return fetch(url).then(response => response.text())};
+if (typeof fetch !== 'undefined') {
+	defaultSchemaRequestService = function (url) { return fetch(url).then(response => response.text()) };
 }
 
 class PromiseAdapter<T> implements jsonService.Thenable<T> {
@@ -57,7 +56,7 @@ export class JSONWorker {
 		this._languageService.configure(this._languageSettings);
 	}
 
-	doValidation(uri: string): Thenable<ls.Diagnostic[]> {
+	doValidation(uri: string): Thenable<jsonService.Diagnostic[]> {
 		let document = this._getTextDocument(uri);
 		if (document) {
 			let jsonDocument = this._languageService.parseJSONDocument(document);
@@ -65,20 +64,20 @@ export class JSONWorker {
 		}
 		return Promise.resolve([]);
 	}
-	doComplete(uri: string, position: ls.Position): Thenable<ls.CompletionList> {
+	doComplete(uri: string, position: jsonService.Position): Thenable<jsonService.CompletionList> {
 		let document = this._getTextDocument(uri);
 		let jsonDocument = this._languageService.parseJSONDocument(document);
 		return this._languageService.doComplete(document, position, jsonDocument);
 	}
-	doResolve(item: ls.CompletionItem): Thenable<ls.CompletionItem> {
+	doResolve(item: jsonService.CompletionItem): Thenable<jsonService.CompletionItem> {
 		return this._languageService.doResolve(item);
 	}
-	doHover(uri: string, position: ls.Position): Thenable<ls.Hover> {
+	doHover(uri: string, position: jsonService.Position): Thenable<jsonService.Hover> {
 		let document = this._getTextDocument(uri);
 		let jsonDocument = this._languageService.parseJSONDocument(document);
 		return this._languageService.doHover(document, position, jsonDocument);
 	}
-	format(uri: string, range: ls.Range, options: ls.FormattingOptions): Thenable<ls.TextEdit[]> {
+	format(uri: string, range: jsonService.Range, options: jsonService.FormattingOptions): Thenable<jsonService.TextEdit[]> {
 		let document = this._getTextDocument(uri);
 		let textEdits = this._languageService.format(document, range, options);
 		return Promise.resolve(textEdits);
@@ -86,34 +85,40 @@ export class JSONWorker {
 	resetSchema(uri: string): Thenable<boolean> {
 		return Promise.resolve(this._languageService.resetSchema(uri));
 	}
-	findDocumentSymbols(uri: string): Thenable<ls.SymbolInformation[]> {
+	findDocumentSymbols(uri: string): Thenable<jsonService.SymbolInformation[]> {
 		let document = this._getTextDocument(uri);
 		let jsonDocument = this._languageService.parseJSONDocument(document);
 		let symbols = this._languageService.findDocumentSymbols(document, jsonDocument);
 		return Promise.resolve(symbols);
 	}
-	findDocumentColors(uri: string): Thenable<ls.ColorInformation[]> {
+	findDocumentColors(uri: string): Thenable<jsonService.ColorInformation[]> {
 		let document = this._getTextDocument(uri);
-		let stylesheet = this._languageService.parseJSONDocument(document);
-		let colorSymbols = this._languageService.findDocumentColors(document, stylesheet);
+		let jsonDocument = this._languageService.parseJSONDocument(document);
+		let colorSymbols = this._languageService.findDocumentColors(document, jsonDocument);
 		return Promise.resolve(colorSymbols);
 	}
-	getColorPresentations(uri: string, color: ls.Color, range: ls.Range): Thenable<ls.ColorPresentation[]> {
+	getColorPresentations(uri: string, color: jsonService.Color, range: jsonService.Range): Thenable<jsonService.ColorPresentation[]> {
 		let document = this._getTextDocument(uri);
-		let stylesheet = this._languageService.parseJSONDocument(document);
-		let colorPresentations = this._languageService.getColorPresentations(document, stylesheet, color, range);
+		let jsonDocument = this._languageService.parseJSONDocument(document);
+		let colorPresentations = this._languageService.getColorPresentations(document, jsonDocument, color, range);
 		return Promise.resolve(colorPresentations);
 	}
-	provideFoldingRanges(uri: string, context?: { rangeLimit?: number; }): Thenable<ls.FoldingRange[]> {
+	getFoldingRanges(uri: string, context?: { rangeLimit?: number; }): Thenable<jsonService.FoldingRange[]> {
 		let document = this._getTextDocument(uri);
 		let ranges = this._languageService.getFoldingRanges(document, context);
 		return Promise.resolve(ranges);
 	}
-	private _getTextDocument(uri: string): ls.TextDocument {
+	getSelectionRanges(uri: string, positions: jsonService.Position[]): Thenable<jsonService.SelectionRange[]> {
+		let document = this._getTextDocument(uri);
+		let jsonDocument = this._languageService.parseJSONDocument(document);
+		let ranges = this._languageService.getSelectionRanges(document, positions, jsonDocument);
+		return Promise.resolve(ranges);
+	}
+	private _getTextDocument(uri: string): jsonService.TextDocument {
 		let models = this._ctx.getMirrorModels();
 		for (let model of models) {
 			if (model.uri.toString() === uri) {
-				return ls.TextDocument.create(uri, this._languageId, model.version, model.getValue());
+				return jsonService.TextDocument.create(uri, this._languageId, model.version, model.getValue());
 			}
 		}
 		return null;
@@ -123,7 +128,7 @@ export class JSONWorker {
 export interface ICreateData {
 	languageId: string;
 	languageSettings: jsonService.LanguageSettings;
-    enableSchemaRequest: boolean;
+	enableSchemaRequest: boolean;
 }
 
 export function create(ctx: IWorkerContext, createData: ICreateData): JSONWorker {

+ 106 - 81
src/languageFeatures.ts

@@ -7,7 +7,7 @@
 import { LanguageServiceDefaultsImpl } from './monaco.contribution';
 import { JSONWorker } from './jsonWorker';
 
-import * as ls from 'vscode-languageserver-types';
+import * as jsonService from 'vscode-json-languageservice';
 
 import Uri = monaco.Uri;
 import Position = monaco.Position;
@@ -116,16 +116,16 @@ export class DiagnosticsAdapter {
 
 function toSeverity(lsSeverity: number): monaco.MarkerSeverity {
 	switch (lsSeverity) {
-		case ls.DiagnosticSeverity.Error: return monaco.MarkerSeverity.Error;
-		case ls.DiagnosticSeverity.Warning: return monaco.MarkerSeverity.Warning;
-		case ls.DiagnosticSeverity.Information: return monaco.MarkerSeverity.Info;
-		case ls.DiagnosticSeverity.Hint: return monaco.MarkerSeverity.Hint;
+		case jsonService.DiagnosticSeverity.Error: return monaco.MarkerSeverity.Error;
+		case jsonService.DiagnosticSeverity.Warning: return monaco.MarkerSeverity.Warning;
+		case jsonService.DiagnosticSeverity.Information: return monaco.MarkerSeverity.Info;
+		case jsonService.DiagnosticSeverity.Hint: return monaco.MarkerSeverity.Hint;
 		default:
 			return monaco.MarkerSeverity.Info;
 	}
 }
 
-function toDiagnostics(resource: Uri, diag: ls.Diagnostic): monaco.editor.IMarkerData {
+function toDiagnostics(resource: Uri, diag: jsonService.Diagnostic): monaco.editor.IMarkerData {
 	let code = typeof diag.code === 'number' ? String(diag.code) : <string>diag.code;
 
 	return {
@@ -142,20 +142,20 @@ function toDiagnostics(resource: Uri, diag: ls.Diagnostic): monaco.editor.IMarke
 
 // --- completion ------
 
-function fromPosition(position: Position): ls.Position {
+function fromPosition(position: Position): jsonService.Position {
 	if (!position) {
 		return void 0;
 	}
 	return { character: position.column - 1, line: position.lineNumber - 1 };
 }
 
-function fromRange(range: IRange): ls.Range {
+function fromRange(range: IRange): jsonService.Range {
 	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: ls.Range): Range {
+function toRange(range: jsonService.Range): Range {
 	if (!range) {
 		return void 0;
 	}
@@ -166,55 +166,55 @@ function toCompletionItemKind(kind: number): monaco.languages.CompletionItemKind
 	let mItemKind = monaco.languages.CompletionItemKind;
 
 	switch (kind) {
-		case ls.CompletionItemKind.Text: return mItemKind.Text;
-		case ls.CompletionItemKind.Method: return mItemKind.Method;
-		case ls.CompletionItemKind.Function: return mItemKind.Function;
-		case ls.CompletionItemKind.Constructor: return mItemKind.Constructor;
-		case ls.CompletionItemKind.Field: return mItemKind.Field;
-		case ls.CompletionItemKind.Variable: return mItemKind.Variable;
-		case ls.CompletionItemKind.Class: return mItemKind.Class;
-		case ls.CompletionItemKind.Interface: return mItemKind.Interface;
-		case ls.CompletionItemKind.Module: return mItemKind.Module;
-		case ls.CompletionItemKind.Property: return mItemKind.Property;
-		case ls.CompletionItemKind.Unit: return mItemKind.Unit;
-		case ls.CompletionItemKind.Value: return mItemKind.Value;
-		case ls.CompletionItemKind.Enum: return mItemKind.Enum;
-		case ls.CompletionItemKind.Keyword: return mItemKind.Keyword;
-		case ls.CompletionItemKind.Snippet: return mItemKind.Snippet;
-		case ls.CompletionItemKind.Color: return mItemKind.Color;
-		case ls.CompletionItemKind.File: return mItemKind.File;
-		case ls.CompletionItemKind.Reference: return mItemKind.Reference;
+		case jsonService.CompletionItemKind.Text: return mItemKind.Text;
+		case jsonService.CompletionItemKind.Method: return mItemKind.Method;
+		case jsonService.CompletionItemKind.Function: return mItemKind.Function;
+		case jsonService.CompletionItemKind.Constructor: return mItemKind.Constructor;
+		case jsonService.CompletionItemKind.Field: return mItemKind.Field;
+		case jsonService.CompletionItemKind.Variable: return mItemKind.Variable;
+		case jsonService.CompletionItemKind.Class: return mItemKind.Class;
+		case jsonService.CompletionItemKind.Interface: return mItemKind.Interface;
+		case jsonService.CompletionItemKind.Module: return mItemKind.Module;
+		case jsonService.CompletionItemKind.Property: return mItemKind.Property;
+		case jsonService.CompletionItemKind.Unit: return mItemKind.Unit;
+		case jsonService.CompletionItemKind.Value: return mItemKind.Value;
+		case jsonService.CompletionItemKind.Enum: return mItemKind.Enum;
+		case jsonService.CompletionItemKind.Keyword: return mItemKind.Keyword;
+		case jsonService.CompletionItemKind.Snippet: return mItemKind.Snippet;
+		case jsonService.CompletionItemKind.Color: return mItemKind.Color;
+		case jsonService.CompletionItemKind.File: return mItemKind.File;
+		case jsonService.CompletionItemKind.Reference: return mItemKind.Reference;
 	}
 	return mItemKind.Property;
 }
 
-function fromCompletionItemKind(kind: monaco.languages.CompletionItemKind): ls.CompletionItemKind {
+function fromCompletionItemKind(kind: monaco.languages.CompletionItemKind): jsonService.CompletionItemKind {
 	let mItemKind = monaco.languages.CompletionItemKind;
 
 	switch (kind) {
-		case mItemKind.Text: return ls.CompletionItemKind.Text;
-		case mItemKind.Method: return ls.CompletionItemKind.Method;
-		case mItemKind.Function: return ls.CompletionItemKind.Function;
-		case mItemKind.Constructor: return ls.CompletionItemKind.Constructor;
-		case mItemKind.Field: return ls.CompletionItemKind.Field;
-		case mItemKind.Variable: return ls.CompletionItemKind.Variable;
-		case mItemKind.Class: return ls.CompletionItemKind.Class;
-		case mItemKind.Interface: return ls.CompletionItemKind.Interface;
-		case mItemKind.Module: return ls.CompletionItemKind.Module;
-		case mItemKind.Property: return ls.CompletionItemKind.Property;
-		case mItemKind.Unit: return ls.CompletionItemKind.Unit;
-		case mItemKind.Value: return ls.CompletionItemKind.Value;
-		case mItemKind.Enum: return ls.CompletionItemKind.Enum;
-		case mItemKind.Keyword: return ls.CompletionItemKind.Keyword;
-		case mItemKind.Snippet: return ls.CompletionItemKind.Snippet;
-		case mItemKind.Color: return ls.CompletionItemKind.Color;
-		case mItemKind.File: return ls.CompletionItemKind.File;
-		case mItemKind.Reference: return ls.CompletionItemKind.Reference;
-	}
-	return ls.CompletionItemKind.Property;
+		case mItemKind.Text: return jsonService.CompletionItemKind.Text;
+		case mItemKind.Method: return jsonService.CompletionItemKind.Method;
+		case mItemKind.Function: return jsonService.CompletionItemKind.Function;
+		case mItemKind.Constructor: return jsonService.CompletionItemKind.Constructor;
+		case mItemKind.Field: return jsonService.CompletionItemKind.Field;
+		case mItemKind.Variable: return jsonService.CompletionItemKind.Variable;
+		case mItemKind.Class: return jsonService.CompletionItemKind.Class;
+		case mItemKind.Interface: return jsonService.CompletionItemKind.Interface;
+		case mItemKind.Module: return jsonService.CompletionItemKind.Module;
+		case mItemKind.Property: return jsonService.CompletionItemKind.Property;
+		case mItemKind.Unit: return jsonService.CompletionItemKind.Unit;
+		case mItemKind.Value: return jsonService.CompletionItemKind.Value;
+		case mItemKind.Enum: return jsonService.CompletionItemKind.Enum;
+		case mItemKind.Keyword: return jsonService.CompletionItemKind.Keyword;
+		case mItemKind.Snippet: return jsonService.CompletionItemKind.Snippet;
+		case mItemKind.Color: return jsonService.CompletionItemKind.Color;
+		case mItemKind.File: return jsonService.CompletionItemKind.File;
+		case mItemKind.Reference: return jsonService.CompletionItemKind.Reference;
+	}
+	return jsonService.CompletionItemKind.Property;
 }
 
-function toTextEdit(textEdit: ls.TextEdit): monaco.editor.ISingleEditOperation {
+function toTextEdit(textEdit: jsonService.TextEdit): monaco.editor.ISingleEditOperation {
 	if (!textEdit) {
 		return void 0;
 	}
@@ -263,7 +263,7 @@ export class CompletionAdapter implements monaco.languages.CompletionItemProvide
 				if (entry.additionalTextEdits) {
 					item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit)
 				}
-				if (entry.insertTextFormat === ls.InsertTextFormat.Snippet) {
+				if (entry.insertTextFormat === jsonService.InsertTextFormat.Snippet) {
 					item.insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
 				}
 				return item;
@@ -277,11 +277,11 @@ export class CompletionAdapter implements monaco.languages.CompletionItemProvide
 	}
 }
 
-function isMarkupContent(thing: any): thing is ls.MarkupContent {
-	return thing && typeof thing === 'object' && typeof (<ls.MarkupContent>thing).kind === 'string';
+function isMarkupContent(thing: any): thing is jsonService.MarkupContent {
+	return thing && typeof thing === 'object' && typeof (<jsonService.MarkupContent>thing).kind === 'string';
 }
 
-function toMarkdownString(entry: ls.MarkupContent | ls.MarkedString): monaco.IMarkdownString {
+function toMarkdownString(entry: jsonService.MarkupContent | jsonService.MarkedString): monaco.IMarkdownString {
 	if (typeof entry === 'string') {
 		return {
 			value: entry
@@ -301,7 +301,7 @@ function toMarkdownString(entry: ls.MarkupContent | ls.MarkedString): monaco.IMa
 	return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
 }
 
-function toMarkedStringArray(contents: ls.MarkupContent | ls.MarkedString | ls.MarkedString[]): monaco.IMarkdownString[] {
+function toMarkedStringArray(contents: jsonService.MarkupContent | jsonService.MarkedString | jsonService.MarkedString[]): monaco.IMarkdownString[] {
 	if (!contents) {
 		return void 0;
 	}
@@ -338,7 +338,7 @@ export class HoverAdapter implements monaco.languages.HoverProvider {
 
 // --- definition ------
 
-function toLocation(location: ls.Location): monaco.languages.Location {
+function toLocation(location: jsonService.Location): monaco.languages.Location {
 	return {
 		uri: Uri.parse(location.uri),
 		range: toRange(location.range)
@@ -348,28 +348,28 @@ function toLocation(location: ls.Location): monaco.languages.Location {
 
 // --- document symbols ------
 
-function toSymbolKind(kind: ls.SymbolKind): monaco.languages.SymbolKind {
+function toSymbolKind(kind: jsonService.SymbolKind): monaco.languages.SymbolKind {
 	let mKind = monaco.languages.SymbolKind;
 
 	switch (kind) {
-		case ls.SymbolKind.File: return mKind.Array;
-		case ls.SymbolKind.Module: return mKind.Module;
-		case ls.SymbolKind.Namespace: return mKind.Namespace;
-		case ls.SymbolKind.Package: return mKind.Package;
-		case ls.SymbolKind.Class: return mKind.Class;
-		case ls.SymbolKind.Method: return mKind.Method;
-		case ls.SymbolKind.Property: return mKind.Property;
-		case ls.SymbolKind.Field: return mKind.Field;
-		case ls.SymbolKind.Constructor: return mKind.Constructor;
-		case ls.SymbolKind.Enum: return mKind.Enum;
-		case ls.SymbolKind.Interface: return mKind.Interface;
-		case ls.SymbolKind.Function: return mKind.Function;
-		case ls.SymbolKind.Variable: return mKind.Variable;
-		case ls.SymbolKind.Constant: return mKind.Constant;
-		case ls.SymbolKind.String: return mKind.String;
-		case ls.SymbolKind.Number: return mKind.Number;
-		case ls.SymbolKind.Boolean: return mKind.Boolean;
-		case ls.SymbolKind.Array: return mKind.Array;
+		case jsonService.SymbolKind.File: return mKind.Array;
+		case jsonService.SymbolKind.Module: return mKind.Module;
+		case jsonService.SymbolKind.Namespace: return mKind.Namespace;
+		case jsonService.SymbolKind.Package: return mKind.Package;
+		case jsonService.SymbolKind.Class: return mKind.Class;
+		case jsonService.SymbolKind.Method: return mKind.Method;
+		case jsonService.SymbolKind.Property: return mKind.Property;
+		case jsonService.SymbolKind.Field: return mKind.Field;
+		case jsonService.SymbolKind.Constructor: return mKind.Constructor;
+		case jsonService.SymbolKind.Enum: return mKind.Enum;
+		case jsonService.SymbolKind.Interface: return mKind.Interface;
+		case jsonService.SymbolKind.Function: return mKind.Function;
+		case jsonService.SymbolKind.Variable: return mKind.Variable;
+		case jsonService.SymbolKind.Constant: return mKind.Constant;
+		case jsonService.SymbolKind.String: return mKind.String;
+		case jsonService.SymbolKind.Number: return mKind.Number;
+		case jsonService.SymbolKind.Boolean: return mKind.Boolean;
+		case jsonService.SymbolKind.Array: return mKind.Array;
 	}
 	return mKind.Function;
 }
@@ -401,7 +401,7 @@ export class DocumentSymbolAdapter implements monaco.languages.DocumentSymbolPro
 }
 
 
-function fromFormattingOptions(options: monaco.languages.FormattingOptions): ls.FormattingOptions {
+function fromFormattingOptions(options: monaco.languages.FormattingOptions): jsonService.FormattingOptions {
 	return {
 		tabSize: options.tabSize,
 		insertSpaces: options.insertSpaces
@@ -496,7 +496,7 @@ export class FoldingRangeAdapter implements monaco.languages.FoldingRangeProvide
 	public provideFoldingRanges(model: monaco.editor.IReadOnlyModel, context: monaco.languages.FoldingContext, token: CancellationToken): Thenable<monaco.languages.FoldingRange[]> {
 		const resource = model.uri;
 
-		return this._worker(resource).then(worker => worker.provideFoldingRanges(resource.toString(), context)).then(ranges => {
+		return this._worker(resource).then(worker => worker.getFoldingRanges(resource.toString(), context)).then(ranges => {
 			if (!ranges) {
 				return;
 			}
@@ -506,7 +506,7 @@ export class FoldingRangeAdapter implements monaco.languages.FoldingRangeProvide
 					end: range.endLine + 1
 				};
 				if (typeof range.kind !== 'undefined') {
-					result.kind = toFoldingRangeKind(<ls.FoldingRangeKind>range.kind);
+					result.kind = toFoldingRangeKind(<jsonService.FoldingRangeKind>range.kind);
 				}
 				return result;
 			});
@@ -515,11 +515,36 @@ export class FoldingRangeAdapter implements monaco.languages.FoldingRangeProvide
 
 }
 
-function toFoldingRangeKind(kind: ls.FoldingRangeKind): monaco.languages.FoldingRangeKind {
+function toFoldingRangeKind(kind: jsonService.FoldingRangeKind): monaco.languages.FoldingRangeKind {
 	switch (kind) {
-		case ls.FoldingRangeKind.Comment: return monaco.languages.FoldingRangeKind.Comment;
-		case ls.FoldingRangeKind.Imports: return monaco.languages.FoldingRangeKind.Imports;
-		case ls.FoldingRangeKind.Region: return monaco.languages.FoldingRangeKind.Region;
+		case jsonService.FoldingRangeKind.Comment: return monaco.languages.FoldingRangeKind.Comment;
+		case jsonService.FoldingRangeKind.Imports: return monaco.languages.FoldingRangeKind.Imports;
+		case jsonService.FoldingRangeKind.Region: return monaco.languages.FoldingRangeKind.Region;
 	}
 	return void 0;
 }
+
+export class SelectionRangeAdapter implements monaco.languages.SelectionRangeProvider {
+
+	constructor(private _worker: WorkerAccessor) {
+	}
+
+	public provideSelectionRanges(model: monaco.editor.IReadOnlyModel, positions: Position[], token: CancellationToken): Thenable<monaco.languages.SelectionRange[][]> {
+		const resource = model.uri;
+
+		return this._worker(resource).then(worker => worker.getSelectionRanges(resource.toString(), positions.map(fromPosition))).then(selectionRanges => {
+			if (!selectionRanges) {
+				return;
+			}
+			return selectionRanges.map(selectionRange => {
+				const result: monaco.languages.SelectionRange[] = [];
+				while (selectionRange) {
+					result.push({ range: toRange(selectionRange.range) });
+					selectionRange = selectionRange.parent;
+				}
+				return result;
+			});
+		});
+	}
+
+}

+ 2 - 1
src/monaco.contribution.ts

@@ -66,7 +66,8 @@ const modeConfigurationDefault: monaco.languages.json.ModeConfiguration = {
 	tokens: true,
 	colors: true,
 	foldingRanges: true,
-	diagnostics: true
+	diagnostics: true,
+	selectionRanges: true
 }
 
 const jsonDefaults = new LanguageServiceDefaultsImpl('json', diagnosticDefault, modeConfigurationDefault);

+ 82 - 77
src/monaco.d.ts

@@ -4,93 +4,98 @@
  *--------------------------------------------------------------------------------------------*/
 
 declare module monaco.languages.json {
-    export interface DiagnosticsOptions {
-        /**
-         * If set, the validator will be enabled and perform syntax validation as well as schema based validation.
-         */
-        readonly validate?: boolean;
-        /**
-         * If set, comments are tolerated. If set to false, syntax errors will be emitted for comments.
-         */
-        readonly allowComments?: boolean;
-        /**
-         * A list of known schemas and/or associations of schemas to file names.
-         */
-        readonly schemas?: {
-            /**
-             * The URI of the schema, which is also the identifier of the schema.
-             */
-            readonly uri: string;
-            /**
-             * A list of file names that are associated to the schema. The '*' wildcard can be used. For example '*.schema.json', 'package.json'
-             */
-            readonly fileMatch?: string[];
-            /**
-             * The schema for the given URI.
-             */
-            readonly schema?: any;
-        }[];
-        /**
-         *  If set, the schema service would load schema content on-demand with 'fetch' if available
-         */
-        readonly enableSchemaRequest?: boolean;
-    }
+	export interface DiagnosticsOptions {
+		/**
+		 * If set, the validator will be enabled and perform syntax validation as well as schema based validation.
+		 */
+		readonly validate?: boolean;
+		/**
+		 * If set, comments are tolerated. If set to false, syntax errors will be emitted for comments.
+		 */
+		readonly allowComments?: boolean;
+		/**
+		 * A list of known schemas and/or associations of schemas to file names.
+		 */
+		readonly schemas?: {
+			/**
+			 * The URI of the schema, which is also the identifier of the schema.
+			 */
+			readonly uri: string;
+			/**
+			 * A list of file names that are associated to the schema. The '*' wildcard can be used. For example '*.schema.json', 'package.json'
+			 */
+			readonly fileMatch?: string[];
+			/**
+			 * The schema for the given URI.
+			 */
+			readonly schema?: any;
+		}[];
+		/**
+		 *  If set, the schema service would load schema content on-demand with 'fetch' if available
+		 */
+		readonly enableSchemaRequest?: boolean;
+	}
 
-    export interface ModeConfiguration {
-        /**
-         * Defines whether the built-in documentFormattingEdit provider is enabled.
-         */
-        readonly documentFormattingEdits?: boolean;
+	export interface ModeConfiguration {
+		/**
+		 * Defines whether the built-in documentFormattingEdit provider is enabled.
+		 */
+		readonly documentFormattingEdits?: boolean;
 
-        /**
-         * Defines whether the built-in documentRangeFormattingEdit provider is enabled.
-         */
-        readonly documentRangeFormattingEdits?: boolean;
+		/**
+		 * Defines whether the built-in documentRangeFormattingEdit provider is enabled.
+		 */
+		readonly documentRangeFormattingEdits?: boolean;
 
-        /**
-         * Defines whether the built-in completionItemProvider is enabled.
-         */
-        readonly completionItems?: boolean;
+		/**
+		 * Defines whether the built-in completionItemProvider is enabled.
+		 */
+		readonly completionItems?: boolean;
 
-        /**
-         * Defines whether the built-in hoverProvider is enabled.
-         */
-        readonly hovers?: boolean;
+		/**
+		 * Defines whether the built-in hoverProvider is enabled.
+		 */
+		readonly hovers?: boolean;
 
-        /**
-         * Defines whether the built-in documentSymbolProvider is enabled.
-         */
-        readonly documentSymbols?: boolean;
+		/**
+		 * Defines whether the built-in documentSymbolProvider is enabled.
+		 */
+		readonly documentSymbols?: boolean;
 
-        /**
-         * Defines whether the built-in tokens provider is enabled.
-         */
-        readonly tokens?: boolean;
+		/**
+		 * Defines whether the built-in tokens provider is enabled.
+		 */
+		readonly tokens?: boolean;
 
-        /**
-        * Defines whether the built-in color provider is enabled.
-        */
-        readonly colors?: boolean;
+		/**
+		 * Defines whether the built-in color provider is enabled.
+		 */
+		readonly colors?: boolean;
 
-        /**
-        * Defines whether the built-in foldingRange provider is enabled.
-        */
-       readonly foldingRanges?: boolean;
+		/**
+		 * Defines whether the built-in foldingRange provider is enabled.
+		 */
+		readonly foldingRanges?: boolean;
 
-        /**
-        * Defines whether the built-in diagnostic provider is enabled.
-        */
-       readonly diagnostics?: boolean;
+		/**
+		 * Defines whether the built-in diagnostic provider is enabled.
+		 */
+		readonly diagnostics?: boolean;
 
-    }
+		/**
+		 * Defines whether the built-in selection range provider is enabled.
+		 */
+		readonly selectionRanges?: boolean;
 
-    export interface LanguageServiceDefaults {
-        readonly onDidChange: IEvent<LanguageServiceDefaults>;
-        readonly diagnosticsOptions: DiagnosticsOptions;
-        readonly modeConfiguration: ModeConfiguration;
-        setDiagnosticsOptions(options: DiagnosticsOptions): void;
-        setModeConfiguration(modeConfiguration: ModeConfiguration): void;
-    }
+	}
 
-    export var jsonDefaults: LanguageServiceDefaults;
+	export interface LanguageServiceDefaults {
+		readonly onDidChange: IEvent<LanguageServiceDefaults>;
+		readonly diagnosticsOptions: DiagnosticsOptions;
+		readonly modeConfiguration: ModeConfiguration;
+		setDiagnosticsOptions(options: DiagnosticsOptions): void;
+		setModeConfiguration(modeConfiguration: ModeConfiguration): void;
+	}
+
+	export var jsonDefaults: LanguageServiceDefaults;
 }