Skip to content

Commit 2eebf16

Browse files
committed
debt - add ISuggestion.textEdit and fill it in when missing
1 parent 5148523 commit 2eebf16

6 files changed

Lines changed: 72 additions & 48 deletions

File tree

src/vs/editor/common/modes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ export interface ISuggestion {
395395
label: string;
396396
codeSnippet: string;
397397
type: string;
398+
textEdit?: EditorCommon.ISingleEditOperation;
398399
highlights?: IHighlight[];
399400
typeLabel?: string;
400401
documentationLabel?: string;

src/vs/editor/contrib/suggest/common/suggest.ts

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
'use strict';
66

77
import {sequence} from 'vs/base/common/async';
8-
import {IModel, IPosition} from 'vs/editor/common/editorCommon';
8+
import {IModel, IPosition, IRange} from 'vs/editor/common/editorCommon';
99
import {TPromise} from 'vs/base/common/winjs.base';
1010
import {mixin} from 'vs/base/common/objects';
1111
import {onUnexpectedError, illegalArgument} from 'vs/base/common/errors';
@@ -42,29 +42,52 @@ export function suggest(model: IModel, position: IPosition, triggerCharacter: st
4242

4343
// for each support in the group ask for suggestions
4444
let promises = supports.map(support => {
45-
return support.suggest(resource, position, triggerCharacter).then(value => {
45+
return support.suggest(resource, position, triggerCharacter).then(values => {
4646

4747
let result: ISuggestions2[] = [];
48-
for (let suggestions of value) {
48+
for (let suggestResult of values) {
4949

50-
if (!suggestions
51-
|| !Array.isArray(suggestions.suggestions)
52-
|| suggestions.suggestions.length === 0) {
50+
if (!suggestResult
51+
|| !Array.isArray(suggestResult.suggestions)
52+
|| suggestResult.suggestions.length === 0) {
5353

5454
continue;
5555
}
5656

5757
const suggestions2: ISuggestions2 = {
5858
support,
59-
currentWord: suggestions.currentWord,
60-
incomplete: suggestions.incomplete,
61-
overwriteAfter: suggestions.overwriteAfter,
62-
overwriteBefore: suggestions.overwriteBefore,
63-
suggestions: suggestions.suggestions
59+
currentWord: suggestResult.currentWord,
60+
incomplete: suggestResult.incomplete,
61+
overwriteAfter: suggestResult.overwriteAfter,
62+
overwriteBefore: suggestResult.overwriteBefore,
63+
suggestions: suggestResult.suggestions
64+
}
65+
66+
const defaultRange: IRange = {
67+
startLineNumber: position.lineNumber,
68+
startColumn: position.column,
69+
endLineNumber: position.lineNumber,
70+
endColumn: position.column
71+
};
72+
73+
if (typeof suggestResult.overwriteBefore === 'number' && suggestResult.overwriteBefore > 0) {
74+
defaultRange.startColumn -= suggestResult.overwriteBefore;
75+
}
76+
if (typeof suggestResult.overwriteAfter === 'number' && suggestResult.overwriteAfter > 0) {
77+
defaultRange.endColumn += suggestResult.overwriteAfter
78+
}
79+
80+
for (let suggestion of suggestResult.suggestions) {
81+
if (!suggestion.textEdit) {
82+
suggestion.textEdit = {
83+
text: suggestion.codeSnippet,
84+
range: defaultRange
85+
};
86+
}
6487
}
6588

6689
// add additional properties
67-
mixin(suggestions2, suggestions, false);
90+
mixin(suggestions2, suggestResult, false);
6891
result.push(suggestions2);
6992
}
7093

src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export class ExtHostLanguageFeatureCommands {
168168
for (let group of value) {
169169
for (let suggestions of group) {
170170
for (let suggestion of suggestions.suggestions) {
171-
const item = typeConverters.Suggest.to(suggestion, suggestions);
171+
const item = typeConverters.Suggest.to(suggestion);
172172
items.push(item);
173173
}
174174
}

src/vs/workbench/api/common/extHostLanguageFeatures.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ class DocumentFormattingAdapter implements modes.IFormattingSupport {
337337

338338
return asWinJsPromise(token => this._provider.provideDocumentFormattingEdits(doc, <any>options, token)).then(value => {
339339
if (Array.isArray(value)) {
340-
return value.map(TypeConverters.fromTextEdit);
340+
return value.map(TypeConverters.TextEdit.from);
341341
}
342342
});
343343
}
@@ -360,7 +360,7 @@ class RangeFormattingAdapter implements modes.IFormattingSupport {
360360

361361
return asWinJsPromise(token => this._provider.provideDocumentRangeFormattingEdits(doc, ran, <any>options, token)).then(value => {
362362
if (Array.isArray(value)) {
363-
return value.map(TypeConverters.fromTextEdit);
363+
return value.map(TypeConverters.TextEdit.from);
364364
}
365365
});
366366
}
@@ -385,7 +385,7 @@ class OnTypeFormattingAdapter implements modes.IFormattingSupport {
385385

386386
return asWinJsPromise(token => this._provider.provideOnTypeFormattingEdits(doc, pos, ch, <any> options, token)).then(value => {
387387
if (Array.isArray(value)) {
388-
return value.map(TypeConverters.fromTextEdit);
388+
return value.map(TypeConverters.TextEdit.from);
389389
}
390390
});
391391
}
@@ -489,7 +489,7 @@ class SuggestAdapter implements modes.ISuggestSupport {
489489

490490
for (let i = 0; i < value.length; i++) {
491491
const item = value[i];
492-
const [suggestion] = TypeConverters.Suggest.from(item, defaultSuggestions); SuggestAdapter._convertCompletionItem(item);
492+
const suggestion = TypeConverters.Suggest.from(item);
493493

494494
if (item.textEdit) {
495495

@@ -540,22 +540,10 @@ class SuggestAdapter implements modes.ISuggestSupport {
540540
return TPromise.as(suggestion);
541541
}
542542
return asWinJsPromise(token => this._provider.resolveCompletionItem(item, token)).then(resolvedItem => {
543-
return SuggestAdapter._convertCompletionItem(resolvedItem || item);
543+
return TypeConverters.Suggest.from(resolvedItem || item);
544544
});
545545
}
546546

547-
private static _convertCompletionItem(item: vscode.CompletionItem): modes.ISuggestion {
548-
return {
549-
label: item.label,
550-
codeSnippet: item.insertText || item.label,
551-
type: CompletionItemKind[item.kind || CompletionItemKind.Text].toString().toLowerCase(),
552-
typeLabel: item.detail,
553-
documentationLabel: item.documentation,
554-
sortText: item.sortText,
555-
filterText: item.filterText
556-
};
557-
}
558-
559547
getFilter(): any{
560548
throw new Error('illegal state');
561549
}

src/vs/workbench/api/common/pluginHostTypeConverters.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,15 @@ export function fromRangeOrRangeWithMessage(ranges:vscode.Range[]|vscode.Decorat
168168
}
169169
}
170170

171-
export function fromTextEdit(edit: vscode.TextEdit) {
172-
return <ISingleEditOperation>{
173-
text: edit.newText,
174-
range: fromRange(edit.range)
171+
export const TextEdit = {
172+
from(edit: vscode.TextEdit): ISingleEditOperation{
173+
return <ISingleEditOperation>{
174+
text: edit.newText,
175+
range: fromRange(edit.range)
176+
}
177+
},
178+
to(edit: ISingleEditOperation): vscode.TextEdit {
179+
return new types.TextEdit(toRange(edit.range), edit.text);
175180
}
176181
}
177182

@@ -315,33 +320,29 @@ export function toDocumentHighlight(occurrence: modes.IOccurence): types.Documen
315320

316321
export const Suggest = {
317322

318-
from(item: vscode.CompletionItem, defaultContainer: modes.ISuggestResult): [modes.ISuggestion, modes.ISuggestResult] {
323+
from(item: vscode.CompletionItem): modes.ISuggestion {
319324
const suggestion: modes.ISuggestion = {
320325
label: item.label,
321326
codeSnippet: item.insertText || item.label,
322327
type: types.CompletionItemKind[item.kind || types.CompletionItemKind.Text].toString().toLowerCase(),
323328
typeLabel: item.detail,
329+
textEdit: item.textEdit && TextEdit.from(item.textEdit),
324330
documentationLabel: item.documentation,
325331
sortText: item.sortText,
326332
filterText: item.filterText
327333
};
328-
329-
if (item.textEdit) {
330-
// TODO@joh
331-
}
332-
333-
return [suggestion, defaultContainer];
334+
return suggestion;
334335
},
335336

336-
to(suggestion: modes.ISuggestion, container: modes.ISuggestResult): types.CompletionItem {
337+
to(suggestion: modes.ISuggestion): types.CompletionItem {
337338
const result = new types.CompletionItem(suggestion.label);
338339
result.insertText = suggestion.codeSnippet;
339340
result.kind = types.CompletionItemKind[suggestion.type.charAt(0).toUpperCase() + suggestion.type.substr(1)];
340341
result.detail = suggestion.typeLabel;
341342
result.documentation = suggestion.documentationLabel;
342343
result.sortText = suggestion.sortText;
343344
result.filterText = suggestion.filterText;
344-
// todo@joh edit range!
345+
result.textEdit = suggestion.textEdit && <any> TextEdit.to(suggestion.textEdit);
345346
return result;
346347
}
347348
}

src/vs/workbench/test/common/api/extHostLanguageFeatureCommands.test.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ suite('ExtHostLanguageFeatureCommands', function() {
236236

237237
test('Suggest, back and forth', function(done) {
238238
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
239-
provideCompletionItems(): any {
240-
return [
241-
new types.CompletionItem('item1'),
242-
new types.CompletionItem('item2')
243-
];
239+
provideCompletionItems(doc, pos): any {
240+
let a = new types.CompletionItem('item1');
241+
let b = new types.CompletionItem('item2');
242+
b.textEdit = types.TextEdit.replace(new types.Range(0, 0, 0, 4), 'foo');
243+
return [a, b];
244244
}
245245
}, []));
246246

@@ -249,7 +249,18 @@ suite('ExtHostLanguageFeatureCommands', function() {
249249
assert.equal(values.length, 2);
250250
let [first, second] = values;
251251
assert.equal(first.label, 'item1');
252+
assert.equal(first.textEdit.newText, 'item1');
253+
assert.equal(first.textEdit.range.start.line, 0);
254+
assert.equal(first.textEdit.range.start.character, 0);
255+
assert.equal(first.textEdit.range.end.line, 0);
256+
assert.equal(first.textEdit.range.end.character, 0);
257+
252258
assert.equal(second.label, 'item2');
259+
assert.equal(second.textEdit.newText, 'foo');
260+
assert.equal(second.textEdit.range.start.line, 0);
261+
assert.equal(second.textEdit.range.start.character, 0);
262+
assert.equal(second.textEdit.range.end.line, 0);
263+
assert.equal(second.textEdit.range.end.character, 4);
253264
done();
254265
});
255266
});

0 commit comments

Comments
 (0)