Skip to content

Commit

Permalink
Check for onEnterRules that decrease indentation when determining new…
Browse files Browse the repository at this point in the history
… line indent
  • Loading branch information
ssigwart committed Nov 7, 2021
1 parent 66b1668 commit db4955b
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/vs/editor/common/modes/languageConfigurationRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export class LanguageConfigurationRegistryImpl {
*
* This function only return the inherited indent based on above lines, it doesn't check whether current line should decrease or not.
*/
public getInheritIndentForLine(autoIndent: EditorAutoIndentStrategy, model: IVirtualModel, lineNumber: number, honorIntentialIndent: boolean = true): { indentation: string; action: IndentAction | null; line?: number; } | null {
public getInheritIndentForLine(autoIndent: EditorAutoIndentStrategy, model: IVirtualModel, lineNumber: number, honorIntentialIndent: boolean = true, indentConverter: IIndentConverter | undefined = undefined): { indentation: string; action: IndentAction | null; line?: number; } | null {
if (autoIndent < EditorAutoIndentStrategy.Full) {
return null;
}
Expand Down Expand Up @@ -442,8 +442,26 @@ export class LanguageConfigurationRegistryImpl {
}

if (honorIntentialIndent) {
let indentation = strings.getLeadingWhitespace(model.getLineContent(precedingUnIgnoredLine));
// Check for onEnter rules that should decrease the indent
if (indentConverter) {
const richEditSupport = this.getLanguageConfiguration(model.getLanguageId());
if (richEditSupport) {
const previousLineText = precedingUnIgnoredLine < 1 ? '' : model.getLineContent(precedingUnIgnoredLine - 1);
const afterEnterText = model.getLineContent(lineNumber);
const enterResult = richEditSupport.onEnter(autoIndent, previousLineText, precedingUnIgnoredLineContent, afterEnterText);
if (enterResult) {
if (enterResult.indentAction === IndentAction.Outdent) {
indentation = indentConverter.unshiftIndent(indentation);
} else if (enterResult.removeText && indentation.length >= enterResult.removeText) {
indentation = indentation.substring(0, indentation.length - enterResult.removeText - 1);
}
}
}
}

return {
indentation: strings.getLeadingWhitespace(model.getLineContent(precedingUnIgnoredLine)),
indentation: indentation,
action: null,
line: precedingUnIgnoredLine
};
Expand Down Expand Up @@ -505,7 +523,7 @@ export class LanguageConfigurationRegistryImpl {
return null;
}

const indent = this.getInheritIndentForLine(autoIndent, virtualModel, lineNumber);
const indent = this.getInheritIndentForLine(autoIndent, virtualModel, lineNumber, true, indentConverter);
const lineContent = virtualModel.getLineContent(lineNumber);

if (indent) {
Expand Down Expand Up @@ -613,7 +631,7 @@ export class LanguageConfigurationRegistryImpl {
};

const currentLineIndent = strings.getLeadingWhitespace(lineTokens.getLineContent());
const afterEnterAction = this.getInheritIndentForLine(autoIndent, virtualModel, range.startLineNumber + 1);
const afterEnterAction = this.getInheritIndentForLine(autoIndent, virtualModel, range.startLineNumber + 1, true, indentConverter);
if (!afterEnterAction) {
const beforeEnter = embeddedLanguage ? currentLineIndent : beforeEnterIndent;
return {
Expand Down
51 changes: 51 additions & 0 deletions src/vs/editor/test/browser/controller/cursor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4529,6 +4529,57 @@ suite('Editor Controller - Indentation Rules', () => {
latexMode.dispose();
model.dispose();
});

test('Issue #136592: onEnterRules should be considered for new line indentation', () => {
const mode = new class extends MockMode {
constructor() {
super('onEnterMode');
this._register(LanguageConfigurationRegistry.register(this.languageId, {
indentationRules: {
increaseIndentPattern: /if/,
decreaseIndentPattern: /never/
},
onEnterRules: [{
beforeText: /outdent/,
action: {
indentAction: IndentAction.Outdent
}
}]
}));
}
}();
usingCursor({
text: [
'if (1)',
' outdent',
'',
'if (1) {',
' keep indent',
'',
'}'
],
languageId: mode.languageId,
}, (editor, model, viewModel) => {

// Use indent
moveTo(editor, viewModel, 6, 1);
viewModel.type('\n', 'keyboard');
assert.strictEqual(model.getLineContent(5), ' keep indent');
assert.strictEqual(model.getLineContent(6), '');
assert.strictEqual(model.getLineContent(7), ' ');
assertCursor(viewModel, new Position(7, 5));

// No indent
moveTo(editor, viewModel, 3, 1);
viewModel.type('\n', 'keyboard');
assert.strictEqual(model.getLineContent(1), 'if (1)');
assert.strictEqual(model.getLineContent(2), ' outdent');
assert.strictEqual(model.getLineContent(3), '');
assert.strictEqual(model.getLineContent(4), '');
assertCursor(viewModel, new Position(4, 1));
});
mode.dispose();
});
});

interface ICursorOpts {
Expand Down

0 comments on commit db4955b

Please sign in to comment.