mirror of
https://github.com/Microsoft/vscode
synced 2024-10-31 01:12:58 +00:00
add adjustWhitespace
-flag to snippet controller, #57093
This commit is contained in:
parent
8d72e849d3
commit
561f8d6b33
3 changed files with 53 additions and 39 deletions
|
@ -5,22 +5,22 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import { RawContextKey, IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { registerEditorContribution, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { SnippetSession } from './snippetSession';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { showSimpleSuggestions } from 'vs/editor/contrib/suggest/suggest';
|
||||
import { ISuggestion } from 'vs/editor/common/modes';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Choice } from 'vs/editor/contrib/snippet/snippetParser';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { repeat } from 'vs/base/common/strings';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { EditorCommand, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { ISuggestion } from 'vs/editor/common/modes';
|
||||
import { Choice } from 'vs/editor/contrib/snippet/snippetParser';
|
||||
import { showSimpleSuggestions } from 'vs/editor/contrib/suggest/suggest';
|
||||
import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { SnippetSession } from './snippetSession';
|
||||
|
||||
export class SnippetController2 implements IEditorContribution {
|
||||
|
||||
|
@ -65,13 +65,14 @@ export class SnippetController2 implements IEditorContribution {
|
|||
insert(
|
||||
template: string,
|
||||
overwriteBefore: number = 0, overwriteAfter: number = 0,
|
||||
undoStopBefore: boolean = true, undoStopAfter: boolean = true
|
||||
undoStopBefore: boolean = true, undoStopAfter: boolean = true,
|
||||
adjustWhitespace: boolean = true,
|
||||
): void {
|
||||
// this is here to find out more about the yet-not-understood
|
||||
// error that sometimes happens when we fail to inserted a nested
|
||||
// snippet
|
||||
try {
|
||||
this._doInsert(template, overwriteBefore, overwriteAfter, undoStopBefore, undoStopAfter);
|
||||
this._doInsert(template, overwriteBefore, overwriteAfter, undoStopBefore, undoStopAfter, adjustWhitespace);
|
||||
|
||||
} catch (e) {
|
||||
this.cancel();
|
||||
|
@ -85,7 +86,8 @@ export class SnippetController2 implements IEditorContribution {
|
|||
private _doInsert(
|
||||
template: string,
|
||||
overwriteBefore: number = 0, overwriteAfter: number = 0,
|
||||
undoStopBefore: boolean = true, undoStopAfter: boolean = true
|
||||
undoStopBefore: boolean = true, undoStopAfter: boolean = true,
|
||||
adjustWhitespace: boolean = true,
|
||||
): void {
|
||||
|
||||
// don't listen while inserting the snippet
|
||||
|
@ -98,10 +100,10 @@ export class SnippetController2 implements IEditorContribution {
|
|||
|
||||
if (!this._session) {
|
||||
this._modelVersionId = this._editor.getModel().getAlternativeVersionId();
|
||||
this._session = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter);
|
||||
this._session = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter, adjustWhitespace);
|
||||
this._session.insert();
|
||||
} else {
|
||||
this._session.merge(template, overwriteBefore, overwriteAfter);
|
||||
this._session.merge(template, overwriteBefore, overwriteAfter, adjustWhitespace);
|
||||
}
|
||||
|
||||
if (undoStopAfter) {
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./snippetSession';
|
||||
import { getLeadingWhitespace } from 'vs/base/common/strings';
|
||||
import { ITextModel, TrackedRangeStickiness, IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { TextmateSnippet, Placeholder, Choice, Text, SnippetParser } from './snippetParser';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { groupBy } from 'vs/base/common/arrays';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver } from './snippetVariables';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { getLeadingWhitespace } from 'vs/base/common/strings';
|
||||
import 'vs/css!./snippetSession';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IIdentifiedSingleEditOperation, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Choice, Placeholder, SnippetParser, Text, TextmateSnippet } from './snippetParser';
|
||||
import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver } from './snippetVariables';
|
||||
|
||||
export class OneSnippet {
|
||||
|
||||
|
@ -271,7 +271,7 @@ export class OneSnippet {
|
|||
|
||||
export class SnippetSession {
|
||||
|
||||
static adjustWhitespace2(model: ITextModel, position: IPosition, snippet: TextmateSnippet): void {
|
||||
static adjustWhitespace(model: ITextModel, position: IPosition, snippet: TextmateSnippet): void {
|
||||
const line = model.getLineContent(position.lineNumber);
|
||||
const lineLeadingWhitespace = getLeadingWhitespace(line, 0, position.column - 1);
|
||||
|
||||
|
@ -317,7 +317,7 @@ export class SnippetSession {
|
|||
return selection;
|
||||
}
|
||||
|
||||
static createEditsAndSnippets(editor: ICodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean): { edits: IIdentifiedSingleEditOperation[], snippets: OneSnippet[] } {
|
||||
static createEditsAndSnippets(editor: ICodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean, adjustWhitespace: boolean): { edits: IIdentifiedSingleEditOperation[], snippets: OneSnippet[] } {
|
||||
|
||||
const model = editor.getModel();
|
||||
const edits: IIdentifiedSingleEditOperation[] = [];
|
||||
|
@ -365,7 +365,9 @@ export class SnippetSession {
|
|||
// adjust the template string to match the indentation and
|
||||
// whitespace rules of this insert location (can be different for each cursor)
|
||||
const start = snippetSelection.getStartPosition();
|
||||
SnippetSession.adjustWhitespace2(model, start, snippet);
|
||||
if (adjustWhitespace) {
|
||||
SnippetSession.adjustWhitespace(model, start, snippet);
|
||||
}
|
||||
|
||||
snippet.resolveVariables(new CompositeSnippetVariableResolver([
|
||||
modelBasedVariableResolver,
|
||||
|
@ -392,13 +394,15 @@ export class SnippetSession {
|
|||
private readonly _templateMerges: [number, number, string][] = [];
|
||||
private readonly _overwriteBefore: number;
|
||||
private readonly _overwriteAfter: number;
|
||||
private readonly _adjustWhitespace: boolean;
|
||||
private _snippets: OneSnippet[] = [];
|
||||
|
||||
constructor(editor: ICodeEditor, template: string, overwriteBefore: number = 0, overwriteAfter: number = 0) {
|
||||
constructor(editor: ICodeEditor, template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true) {
|
||||
this._editor = editor;
|
||||
this._template = template;
|
||||
this._overwriteBefore = overwriteBefore;
|
||||
this._overwriteAfter = overwriteAfter;
|
||||
this._adjustWhitespace = adjustWhitespace;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
@ -414,7 +418,7 @@ export class SnippetSession {
|
|||
const model = this._editor.getModel();
|
||||
|
||||
// make insert edit and start with first selections
|
||||
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._overwriteBefore, this._overwriteAfter, false);
|
||||
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._overwriteBefore, this._overwriteAfter, false, this._adjustWhitespace);
|
||||
this._snippets = snippets;
|
||||
|
||||
const selections = model.pushEditOperations(this._editor.getSelections(), edits, undoEdits => {
|
||||
|
@ -428,9 +432,9 @@ export class SnippetSession {
|
|||
this._editor.revealRange(selections[0]);
|
||||
}
|
||||
|
||||
merge(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0): void {
|
||||
merge(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true): void {
|
||||
this._templateMerges.push([this._snippets[0]._nestingLevel, this._snippets[0]._placeholderGroupsIdx, template]);
|
||||
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, overwriteBefore, overwriteAfter, true);
|
||||
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, overwriteBefore, overwriteAfter, true, adjustWhitespace);
|
||||
|
||||
this._editor.setSelections(this._editor.getModel().pushEditOperations(this._editor.getSelections(), edits, undoEdits => {
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser';
|
||||
import { SnippetSession } from 'vs/editor/contrib/snippet/snippetSession';
|
||||
import { createTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser';
|
||||
|
||||
suite('SnippetSession', function () {
|
||||
|
||||
|
@ -43,7 +43,7 @@ suite('SnippetSession', function () {
|
|||
|
||||
function assertNormalized(position: IPosition, input: string, expected: string): void {
|
||||
const snippet = new SnippetParser().parse(input);
|
||||
SnippetSession.adjustWhitespace2(model, position, snippet);
|
||||
SnippetSession.adjustWhitespace(model, position, snippet);
|
||||
assert.equal(snippet.toTextmateString(), expected);
|
||||
}
|
||||
|
||||
|
@ -125,6 +125,14 @@ suite('SnippetSession', function () {
|
|||
assertSelections(editor, new Selection(3, 1, 3, 1), new Selection(6, 5, 6, 5));
|
||||
});
|
||||
|
||||
test('snippets, newline NO whitespace adjust', () => {
|
||||
|
||||
editor.setSelection(new Selection(2, 5, 2, 5));
|
||||
const session = new SnippetSession(editor, 'abc\n foo\n bar\n$0', 0, 0, false);
|
||||
session.insert();
|
||||
assert.equal(editor.getModel().getValue(), 'function foo() {\n abc\n foo\n bar\nconsole.log(a);\n}');
|
||||
});
|
||||
|
||||
test('snippets, selections -> next/prev', () => {
|
||||
|
||||
const session = new SnippetSession(editor, 'f$1oo${2:bar}foo$0');
|
||||
|
|
Loading…
Reference in a new issue