-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adjust selectionRange API #474
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,11 +7,11 @@ | |
import * as UUID from './utils/uuid'; | ||
import * as Is from './utils/is'; | ||
|
||
import { languages as Languages, Disposable, TextDocument, ProviderResult, Position as VPosition, SelectionRange as VSelectionRange, SelectionRangeKind as VSelectionRangeKind } from 'vscode'; | ||
import { languages as Languages, Disposable, TextDocument, ProviderResult, Position as VPosition, SelectionRange as VSelectionRange } from 'vscode'; | ||
|
||
import { | ||
ClientCapabilities, CancellationToken, ServerCapabilities, TextDocumentRegistrationOptions, DocumentSelector, StaticRegistrationOptions, | ||
SelectionRangeRequest, SelectionRangeProviderOptions, SelectionRangeKind, SelectionRange, SelectionRangeParams | ||
SelectionRangeRequest, SelectionRangeProviderOptions, SelectionRange, SelectionRangeParams | ||
} from 'vscode-languageserver-protocol'; | ||
|
||
import { TextDocumentFeature, BaseLanguageClient } from './client'; | ||
|
@@ -24,12 +24,12 @@ function ensure<T, K extends keyof T>(target: T, key: K): T[K] { | |
} | ||
|
||
export interface ProvideSelectionRangeSignature { | ||
(document: TextDocument, positions: VPosition[], token: CancellationToken): ProviderResult<VSelectionRange[][]>; | ||
(document: TextDocument, positions: VPosition[], token: CancellationToken): ProviderResult<VSelectionRange[]>; | ||
} | ||
|
||
|
||
export interface SelectionRangeProviderMiddleware { | ||
provideSelectionRanges?: (this: void, document: TextDocument, positions: VPosition[], token: CancellationToken, next: ProvideSelectionRangeSignature) => ProviderResult<VSelectionRange[][]>; | ||
provideSelectionRanges?: (this: void, document: TextDocument, positions: VPosition[], token: CancellationToken, next: ProvideSelectionRangeSignature) => ProviderResult<VSelectionRange[]>; | ||
} | ||
|
||
export class SelectionRangeFeature extends TextDocumentFeature<TextDocumentRegistrationOptions> { | ||
|
@@ -75,7 +75,7 @@ export class SelectionRangeFeature extends TextDocumentFeature<TextDocumentRegis | |
}; | ||
let middleware = client.clientOptions.middleware!; | ||
return Languages.registerSelectionRangeProvider(options.documentSelector!, { | ||
provideSelectionRanges(document: TextDocument, positions: VPosition[], token: CancellationToken): ProviderResult<VSelectionRange[][]> { | ||
provideSelectionRanges(document: TextDocument, positions: VPosition[], token: CancellationToken): ProviderResult<VSelectionRange[]> { | ||
return middleware.provideSelectionRanges | ||
? middleware.provideSelectionRanges(document, positions, token, provideSelectionRanges) | ||
: provideSelectionRanges(document, positions, token); | ||
|
@@ -84,84 +84,89 @@ export class SelectionRangeFeature extends TextDocumentFeature<TextDocumentRegis | |
}); | ||
} | ||
|
||
private asSelectionRanges(selectionRanges: SelectionRange[][] | null): VSelectionRange[][] { | ||
private asSelectionRanges(selectionRanges: SelectionRange[] | null): VSelectionRange[] { | ||
if (!Array.isArray(selectionRanges)) { | ||
return []; | ||
} | ||
let result: VSelectionRange[][] = []; | ||
for (let ranges of selectionRanges) { | ||
if (!Array.isArray(ranges)) { | ||
let result: VSelectionRange[] = []; | ||
for (let range of selectionRanges) { | ||
let vrange = this.asSelectionRange(range); | ||
if (vrange == null) { | ||
return []; | ||
} | ||
let inner: VSelectionRange[] = []; | ||
result.push(inner); | ||
for (let range of ranges) { | ||
inner.push(new VSelectionRange( | ||
this._client.protocol2CodeConverter.asRange(range.range), | ||
this.asSelectionRangeKind(range.kind), | ||
)); | ||
} | ||
result.push(vrange); | ||
} | ||
return result; | ||
} | ||
|
||
private asSelectionRangeKind(kind?: string): VSelectionRangeKind { | ||
switch (kind) { | ||
case SelectionRangeKind.Empty: | ||
return VSelectionRangeKind.Empty; | ||
case SelectionRangeKind.Statement: | ||
return VSelectionRangeKind.Statement; | ||
case SelectionRangeKind.Declaration: | ||
return VSelectionRangeKind.Declaration; | ||
default: | ||
return VSelectionRangeKind.Empty | ||
private asSelectionRange(selectionRange: SelectionRange): VSelectionRange | undefined { | ||
let range = this._client.protocol2CodeConverter.asRange(selectionRange.range); | ||
let parent = undefined; | ||
if (selectionRange.parent) { | ||
parent = this.asSelectionRange(selectionRange.parent); | ||
if (!parent || !(parent.range.contains(range) && !parent.range.isEqual(range))) { | ||
return undefined | ||
} | ||
} | ||
return new VSelectionRange(range, parent); | ||
} | ||
} | ||
|
||
declare module 'vscode' { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note that the API is not proposed in insiders, so we should remove this once we update vscode dependency |
||
|
||
export class SelectionRangeKind { | ||
/** | ||
* A selection range represents a part of a selection hierarchy. A selection range | ||
* may have a parent selection range that contains it. | ||
*/ | ||
export class SelectionRange { | ||
|
||
/** | ||
* Empty Kind. | ||
* The [range](#Range) of this selection range. | ||
*/ | ||
static readonly Empty: SelectionRangeKind; | ||
range: Range; | ||
|
||
/** | ||
* The statment kind, its value is `statement`, possible extensions can be | ||
* `statement.if` etc | ||
* The parent selection range containing this range. | ||
*/ | ||
static readonly Statement: SelectionRangeKind; | ||
parent?: SelectionRange; | ||
|
||
/** | ||
* The declaration kind, its value is `declaration`, possible extensions can be | ||
* `declaration.function`, `declaration.class` etc. | ||
* Creates a new selection range. | ||
* | ||
* @param range The range of the selection range. | ||
* @param parent The parent of the selection range. | ||
*/ | ||
static readonly Declaration: SelectionRangeKind; | ||
|
||
readonly value: string; | ||
|
||
private constructor(value: string); | ||
|
||
append(value: string): SelectionRangeKind; | ||
} | ||
|
||
export class SelectionRange { | ||
kind: SelectionRangeKind; | ||
range: Range; | ||
constructor(range: Range, kind: SelectionRangeKind); | ||
constructor(range: Range, parent?: SelectionRange); | ||
} | ||
|
||
export interface SelectionRangeProvider { | ||
/** | ||
* Provide selection ranges starting at a given position. The first range must [contain](#Range.contains) | ||
* position and subsequent ranges must contain the previous range. | ||
* Provide selection ranges for the given positions. | ||
* | ||
* Selection ranges should be computed individually and independend for each postion. The editor will merge | ||
* and deduplicate ranges but providers must return hierarchies of selection ranges so that a range | ||
* is [contained](#Range.contains) by its parent. | ||
* | ||
* @param document The document in which the command was invoked. | ||
* @param positions The positions at which the command was invoked. | ||
* @param token A cancellation token. | ||
* @return Selection ranges or a thenable that resolves to such. The lack of a result can be | ||
* signaled by returning `undefined` or `null`. | ||
*/ | ||
provideSelectionRanges(document: TextDocument, position: Position[], token: CancellationToken): ProviderResult<SelectionRange[][]>; | ||
provideSelectionRanges(document: TextDocument, positions: Position[], token: CancellationToken): ProviderResult<SelectionRange[]>; | ||
} | ||
|
||
export namespace languages { | ||
/** | ||
* Register a selection range provider. | ||
* | ||
* Multiple providers can be registered for a language. In that case providers are asked in | ||
* parallel and the results are merged. A failing provider (rejected promise or exception) will | ||
* not cause a failure of the whole operation. | ||
* | ||
* @param selector A selector that defines the documents this provider is applicable to. | ||
* @param provider A selection range provider. | ||
* @return A [disposable](#Disposable) that unregisters this provider when being disposed. | ||
*/ | ||
export function registerSelectionRangeProvider(selector: DocumentSelector, provider: SelectionRangeProvider): Disposable; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the proper way to report invalid data? eg, when parent is smaller than a child?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jrieken any recommendation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, child must be contained by parents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, and this code checks this conditions. The question is, what to do if the server implementation returns wrong data?
The behavior should be such that:
Is there some function like
show_error_dialog_if_in_dev_mode_otherwise_log_a_warning
?