Skip to content

Commit 8105de0

Browse files
committed
[vscode] Support keepWhitespace in SnippetTextEdit and insertSnippet
fixes #15131 Contributed on behalf of STMicroelectronics Signed-off-by: Remi Schnekenburger <[email protected]>
1 parent 224989c commit 8105de0

File tree

6 files changed

+49
-13
lines changed

6 files changed

+49
-13
lines changed

packages/plugin-ext/src/common/plugin-api-rpc.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,10 @@ export interface ApplyEditsOptions extends UndoStopOptions {
12411241
setEndOfLine: EndOfLine | undefined;
12421242
}
12431243

1244+
export interface SnippetEditOptions extends UndoStopOptions {
1245+
keepWhitespace?: boolean;
1246+
}
1247+
12441248
export interface ThemeColor {
12451249
id: string;
12461250
}
@@ -1345,7 +1349,7 @@ export interface TextEditorsMain {
13451349
$trySetSelections(id: string, selections: Selection[]): Promise<void>;
13461350
$tryApplyEdits(id: string, modelVersionId: number, edits: SingleEditOperation[], opts: ApplyEditsOptions): Promise<boolean>;
13471351
$tryApplyWorkspaceEdit(workspaceEditDto: WorkspaceEditDto, metadata?: WorkspaceEditMetadataDto): Promise<boolean>;
1348-
$tryInsertSnippet(id: string, template: string, selections: Range[], opts: UndoStopOptions): Promise<boolean>;
1352+
$tryInsertSnippet(id: string, template: string, selections: Range[], opts: SnippetEditOptions): Promise<boolean>;
13491353
$save(uri: UriComponents): PromiseLike<UriComponents | undefined>;
13501354
$saveAs(uri: UriComponents): PromiseLike<UriComponents | undefined>;
13511355
$saveAll(includeUntitled?: boolean): Promise<boolean>;
@@ -1545,7 +1549,7 @@ export interface WorkspaceFileEditDto {
15451549
export interface WorkspaceTextEditDto {
15461550
resource: UriComponents;
15471551
modelVersionId?: number;
1548-
textEdit: TextEdit & { insertAsSnippet?: boolean };
1552+
textEdit: TextEdit & { insertAsSnippet?: boolean, keepWhitespace?: boolean };
15491553
metadata?: WorkspaceEditEntryMetadataDto;
15501554
}
15511555
export namespace WorkspaceTextEditDto {

packages/plugin-ext/src/main/browser/text-editor-main.ts

+18-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
TextEditorRevealType,
2727
SingleEditOperation,
2828
ApplyEditsOptions,
29-
UndoStopOptions,
29+
SnippetEditOptions,
3030
DecorationOptions
3131
} from '../../common/plugin-api-rpc';
3232
import { Range } from '../../common/plugin-api-rpc-model';
@@ -281,7 +281,7 @@ export class TextEditorMain implements Disposable {
281281
return true;
282282
}
283283

284-
insertSnippet(template: string, ranges: Range[], opts: UndoStopOptions): boolean {
284+
insertSnippet(template: string, ranges: Range[], opts: SnippetEditOptions): boolean {
285285
const snippetController: SnippetController2 | null | undefined = this.editor?.getControl().getContribution('snippetController2');
286286

287287
if (!snippetController || !this.editor) { return false; }
@@ -290,7 +290,13 @@ export class TextEditorMain implements Disposable {
290290
this.editor.getControl().setSelections(selections);
291291
this.editor.focus();
292292

293-
snippetController.insert(template, 0, 0, opts.undoStopBefore, opts.undoStopAfter);
293+
snippetController.insert(template, {
294+
undoStopBefore: opts.undoStopBefore,
295+
undoStopAfter: opts.undoStopAfter,
296+
adjustWhitespace: !opts.keepWhitespace,
297+
overwriteBefore: 0,
298+
overwriteAfter: 0
299+
});
294300

295301
return true;
296302
}
@@ -324,11 +330,17 @@ export class TextEditorMain implements Disposable {
324330
}
325331
}
326332

333+
interface SnippetInsertOptions {
334+
overwriteBefore: number,
335+
overwriteAfter: number,
336+
undoStopBefore: boolean,
337+
undoStopAfter: boolean,
338+
adjustWhitespace: boolean
339+
}
340+
327341
// TODO move to monaco typings!
328342
interface SnippetController2 extends monaco.editor.IEditorContribution {
329-
insert(template: string,
330-
overwriteBefore: number, overwriteAfter: number,
331-
undoStopBefore: boolean, undoStopAfter: boolean): void;
343+
insert(template: string, options?: Partial<SnippetInsertOptions>): void;
332344
finish(): void;
333345
cancel(): void;
334346
dispose(): void;

packages/plugin-ext/src/main/browser/text-editors-main.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ import {
2323
TextEditorRevealType,
2424
SingleEditOperation,
2525
ApplyEditsOptions,
26-
UndoStopOptions,
2726
DecorationRenderOptions,
2827
ThemeDecorationInstanceRenderOptions,
2928
DecorationOptions,
3029
WorkspaceEditDto,
3130
WorkspaceNotebookCellEditDto,
3231
DocumentsMain,
3332
WorkspaceEditMetadataDto,
33+
SnippetEditOptions,
3434
} from '../../common/plugin-api-rpc';
3535
import { Range, TextDocumentShowOptions } from '../../common/plugin-api-rpc-model';
3636
import { EditorsAndDocumentsMain } from './editors-and-documents-main';
@@ -157,7 +157,7 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable {
157157
}
158158
}
159159

160-
$tryInsertSnippet(id: string, template: string, ranges: Range[], opts: UndoStopOptions): Promise<boolean> {
160+
$tryInsertSnippet(id: string, template: string, ranges: Range[], opts: SnippetEditOptions): Promise<boolean> {
161161
if (!this.editorsAndDocuments.getEditor(id)) {
162162
return Promise.reject(disposed(`TextEditor(${id})`));
163163
}

packages/plugin-ext/src/plugin/type-converters.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -342,11 +342,12 @@ export function fromTextEdit(edit: theia.TextEdit): model.TextEdit {
342342
};
343343
}
344344

345-
function fromSnippetTextEdit(edit: theia.SnippetTextEdit): model.TextEdit & { insertAsSnippet?: boolean } {
345+
function fromSnippetTextEdit(edit: theia.SnippetTextEdit): model.TextEdit & { insertAsSnippet?: boolean, keepWhitespace?: boolean } {
346346
return {
347347
text: edit.snippet.value,
348348
range: fromRange(edit.range),
349-
insertAsSnippet: true
349+
insertAsSnippet: true,
350+
keepWhitespace: edit.keepWhitespace
350351
};
351352
}
352353

packages/plugin-ext/src/plugin/types-impl.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,7 @@ export class NotebookRange implements theia.NotebookRange {
13411341
export class SnippetTextEdit implements theia.SnippetTextEdit {
13421342
range: Range;
13431343
snippet: SnippetString;
1344+
keepWhitespace?: boolean;
13441345

13451346
static isSnippetTextEdit(thing: unknown): thing is SnippetTextEdit {
13461347
return thing instanceof SnippetTextEdit || isObject<SnippetTextEdit>(thing)

packages/plugin/src/theia.d.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,20 @@ export module '@theia/plugin' {
11461146
* @return A promise that resolves with a value indicating if the snippet could be inserted. Note that the promise does not signal
11471147
* that the snippet is completely filled-in or accepted.
11481148
*/
1149-
insertSnippet(snippet: SnippetString, location?: Position | Range | Position[] | Range[], options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;
1149+
insertSnippet(snippet: SnippetString, location?: Position | Range | Position[] | Range[], options?: {
1150+
/**
1151+
* Add undo stop before making the edits.
1152+
*/
1153+
readonly undoStopBefore: boolean;
1154+
/**
1155+
* Add undo stop after making the edits.
1156+
*/
1157+
readonly undoStopAfter: boolean;
1158+
/**
1159+
* Keep whitespace of the {@link SnippetString.value} as is.
1160+
*/
1161+
readonly keepWhitespace?: boolean;
1162+
}): Thenable<boolean>;
11501163

11511164
/**
11521165
* Adds a set of decorations to the text editor. If a set of decorations already exists with
@@ -16299,6 +16312,11 @@ export module '@theia/plugin' {
1629916312
*/
1630016313
snippet: SnippetString;
1630116314

16315+
/**
16316+
* Whether the snippet edit should be applied with existing whitespace preserved.
16317+
*/
16318+
keepWhitespace?: boolean;
16319+
1630216320
/**
1630316321
* Create a new snippet edit.
1630416322
*

0 commit comments

Comments
 (0)