Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/vs/editor/common/config/editorOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,11 @@ export interface IEditorOptions {
* Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown.
*/
inlineCompletionsAccessibilityVerbose?: boolean;

/**
* When the preceding line is a blank line, use OnEnterRule on the previous non-blank line to determine the indentation.
*/
useOnEnterRulesForInheritedIndent?: boolean;
}

/**
Expand Down Expand Up @@ -5647,7 +5652,8 @@ export const enum EditorOption {
defaultColorDecorators,
colorDecoratorsActivatedOn,
inlineCompletionsAccessibilityVerbose,
effectiveExperimentalEditContextEnabled
effectiveExperimentalEditContextEnabled,
useOnEnterRulesForInheritedIndent,
}

export const EditorOptions = {
Expand Down Expand Up @@ -6480,7 +6486,11 @@ export const EditorOptions = {
wrappingInfo: register(new EditorWrappingInfoComputer()),
wrappingIndent: register(new WrappingIndentOption()),
wrappingStrategy: register(new WrappingStrategy()),
effectiveExperimentalEditContextEnabled: register(new EffectiveExperimentalEditContextEnabled())
effectiveExperimentalEditContextEnabled: register(new EffectiveExperimentalEditContextEnabled()),
useOnEnterRulesForInheritedIndent: register(new EditorBooleanOption(
EditorOption.useOnEnterRulesForInheritedIndent, 'useOnEnterRulesForInheritedIndent', false,
{ description: nls.localize('useOnEnterRulesForInheritedIndent', "When the preceding line is a blank line, use OnEnterRule on the previous non-blank line to determine the indentation.") }
)),
};

type EditorOptionsType = typeof EditorOptions;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/editor/common/cursor/cursorTypeEditOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ export class EnterOperation {
const indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);

if (config.autoIndent >= EditorAutoIndentStrategy.Full) {
const ir = getIndentForEnter(config.autoIndent, model, range, {
const ir = getIndentForEnter(config, model, range, {
unshiftIndent: (indent) => {
return unshiftIndent(config, indent);
},
Expand Down Expand Up @@ -815,7 +815,7 @@ export class TabOperation {
private static _goodIndentForLine(config: CursorConfiguration, model: ITextModel, lineNumber: number): string | null {
let action: IndentAction | EnterAction | null = null;
let indentation: string = '';
const expectedIndentAction = getInheritIndentForLine(config.autoIndent, model, lineNumber, false, config.languageConfigurationService);
const expectedIndentAction = getInheritIndentForLine(config.autoIndent, config.useOnEnterRulesForInheritedIndent, model, lineNumber, false, config.languageConfigurationService);
if (expectedIndentAction) {
action = expectedIndentAction.action;
indentation = expectedIndentAction.indentation;
Expand Down
2 changes: 2 additions & 0 deletions src/vs/editor/common/cursorCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export class CursorConfiguration {
public readonly shouldAutoCloseBefore: { quote: (ch: string) => boolean; bracket: (ch: string) => boolean; comment: (ch: string) => boolean };
public readonly wordSegmenterLocales: string[];
public readonly overtypeOnPaste: boolean;
public readonly useOnEnterRulesForInheritedIndent: boolean;

private readonly _languageId: string;
private _electricChars: { [key: string]: boolean } | null;
Expand Down Expand Up @@ -141,6 +142,7 @@ export class CursorConfiguration {
this.autoIndent = options.get(EditorOption.autoIndent);
this.wordSegmenterLocales = options.get(EditorOption.wordSegmenterLocales);
this.overtypeOnPaste = options.get(EditorOption.overtypeOnPaste);
this.useOnEnterRulesForInheritedIndent = options.get(EditorOption.useOnEnterRulesForInheritedIndent);

this.surroundingPairs = {};
this._electricChars = null;
Expand Down
29 changes: 17 additions & 12 deletions src/vs/editor/common/languages/autoIndent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function getPrecedingValidLine(model: IVirtualModel, lineNumber: number, process
*/
export function getInheritIndentForLine(
autoIndent: EditorAutoIndentStrategy,
useOnEnterRulesForInheritedIndent: boolean,
model: IVirtualModel,
lineNumber: number,
honorIntentialIndent: boolean = true,
Expand All @@ -87,7 +88,7 @@ export function getInheritIndentForLine(
if (!indentRulesSupport) {
return null;
}
const processedIndentRulesSupport = new ProcessedIndentRulesSupport(model, indentRulesSupport, languageConfigurationService);
const processedIndentRulesSupport = new ProcessedIndentRulesSupport(model, autoIndent, useOnEnterRulesForInheritedIndent, indentRulesSupport, languageConfigurationService);

if (lineNumber <= 1) {
return {
Expand Down Expand Up @@ -149,7 +150,7 @@ export function getInheritIndentForLine(

const previousLine = precedingUnIgnoredLine - 1;

const previousLineIndentMetadata = indentRulesSupport.getIndentMetadata(model.getLineContent(previousLine));
const previousLineIndentMetadata = indentRulesSupport.getIndentMetadata(autoIndent, useOnEnterRulesForInheritedIndent, model.getLineContent(previousLine));
if (!(previousLineIndentMetadata & (IndentConsts.INCREASE_MASK | IndentConsts.DECREASE_MASK)) &&
(previousLineIndentMetadata & IndentConsts.INDENT_NEXTLINE_MASK)) {
let stopLine = 0;
Expand Down Expand Up @@ -218,6 +219,7 @@ export function getInheritIndentForLine(

export function getGoodIndentForLine(
autoIndent: EditorAutoIndentStrategy,
useOnEnterRulesForInheritedIndent: boolean,
virtualModel: IVirtualModel,
languageId: string,
lineNumber: number,
Expand All @@ -238,8 +240,8 @@ export function getGoodIndentForLine(
return null;
}

const processedIndentRulesSupport = new ProcessedIndentRulesSupport(virtualModel, indentRulesSupport, languageConfigurationService);
const indent = getInheritIndentForLine(autoIndent, virtualModel, lineNumber, undefined, languageConfigurationService);
const processedIndentRulesSupport = new ProcessedIndentRulesSupport(virtualModel, autoIndent, useOnEnterRulesForInheritedIndent, indentRulesSupport, languageConfigurationService);
const indent = getInheritIndentForLine(autoIndent, useOnEnterRulesForInheritedIndent, virtualModel, lineNumber, undefined, languageConfigurationService);

if (indent) {
const inheritLine = indent.line;
Expand Down Expand Up @@ -302,12 +304,13 @@ export function getGoodIndentForLine(
}

export function getIndentForEnter(
autoIndent: EditorAutoIndentStrategy,
cursorConfig: CursorConfiguration,
model: ITextModel,
range: Range,
indentConverter: IIndentConverter,
languageConfigurationService: ILanguageConfigurationService
): { beforeEnter: string; afterEnter: string } | null {
const autoIndent = cursorConfig.autoIndent;
if (autoIndent < EditorAutoIndentStrategy.Full) {
return null;
}
Expand All @@ -328,7 +331,7 @@ export function getIndentForEnter(
const languageIsDifferentFromLineStart = isLanguageDifferentFromLineStart(model, range.getStartPosition());
const currentLine = model.getLineContent(range.startLineNumber);
const currentLineIndent = strings.getLeadingWhitespace(currentLine);
const afterEnterAction = getInheritIndentForLine(autoIndent, virtualModel, range.startLineNumber + 1, undefined, languageConfigurationService);
const afterEnterAction = getInheritIndentForLine(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, virtualModel, range.startLineNumber + 1, undefined, languageConfigurationService);
if (!afterEnterAction) {
const beforeEnter = languageIsDifferentFromLineStart ? currentLineIndent : beforeEnterIndent;
return {
Expand All @@ -343,7 +346,7 @@ export function getIndentForEnter(
afterEnterIndent = indentConverter.shiftIndent(afterEnterIndent);
}

if (indentRulesSupport.shouldDecrease(afterEnterProcessedTokens.getLineContent())) {
if (indentRulesSupport.shouldDecrease(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, afterEnterProcessedTokens.getLineContent())) {
afterEnterIndent = indentConverter.unshiftIndent(afterEnterIndent);
}

Expand Down Expand Up @@ -390,10 +393,10 @@ export function getIndentActionForType(

// If previous content already matches decreaseIndentPattern, it means indentation of this line should already be adjusted
// Users might change the indentation by purpose and we should honor that instead of readjusting.
if (!indentRulesSupport.shouldDecrease(textAroundRange) && indentRulesSupport.shouldDecrease(textAroundRangeWithCharacter)) {
if (!indentRulesSupport.shouldDecrease(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, textAroundRange) && indentRulesSupport.shouldDecrease(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, textAroundRangeWithCharacter)) {
// after typing `ch`, the content matches decreaseIndentPattern, we should adjust the indent to a good manner.
// 1. Get inherited indent action
const r = getInheritIndentForLine(autoIndent, model, range.startLineNumber, false, languageConfigurationService);
const r = getInheritIndentForLine(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, model, range.startLineNumber, false, languageConfigurationService);
if (!r) {
return null;
}
Expand All @@ -409,8 +412,8 @@ export function getIndentActionForType(
const previousLineNumber = range.startLineNumber - 1;
if (previousLineNumber > 0) {
const previousLine = model.getLineContent(previousLineNumber);
if (indentRulesSupport.shouldIndentNextLine(previousLine) && indentRulesSupport.shouldIncrease(textAroundRangeWithCharacter)) {
const inheritedIndentationData = getInheritIndentForLine(autoIndent, model, range.startLineNumber, false, languageConfigurationService);
if (indentRulesSupport.shouldIndentNextLine(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, previousLine) && indentRulesSupport.shouldIncrease(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, textAroundRangeWithCharacter)) {
const inheritedIndentationData = getInheritIndentForLine(cursorConfig.autoIndent, cursorConfig.useOnEnterRulesForInheritedIndent, model, range.startLineNumber, false, languageConfigurationService);
const inheritedIndentation = inheritedIndentationData?.indentation;
if (inheritedIndentation !== undefined) {
const currentLine = model.getLineContent(range.startLineNumber);
Expand All @@ -434,6 +437,8 @@ export function getIndentActionForType(

export function getIndentMetadata(
model: ITextModel,
autoIndent: EditorAutoIndentStrategy,
useOnEnterRulesForInheritedIndent: boolean,
lineNumber: number,
languageConfigurationService: ILanguageConfigurationService
): number | null {
Expand All @@ -444,7 +449,7 @@ export function getIndentMetadata(
if (lineNumber < 1 || lineNumber > model.getLineCount()) {
return null;
}
return indentRulesSupport.getIndentMetadata(model.getLineContent(lineNumber));
return indentRulesSupport.getIndentMetadata(autoIndent, useOnEnterRulesForInheritedIndent, model.getLineContent(lineNumber));
}

function createVirtualModelWithModifiedTokensAtLine(model: ITextModel, modifiedLineNumber: number, modifiedTokens: IViewLineTokens): IVirtualModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ export class ResolvedLanguageConfiguration {
this.indentationRules = this.underlyingConfig.indentationRules;
if (this.underlyingConfig.indentationRules) {
this.indentRulesSupport = new IndentRulesSupport(
this.underlyingConfig.indentationRules
this.underlyingConfig.indentationRules,
this._onEnterSupport
);
} else {
this.indentRulesSupport = null;
Expand Down
55 changes: 39 additions & 16 deletions src/vs/editor/common/languages/supports/indentRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { IndentationRule } from '../languageConfiguration.js';
import { EditorAutoIndentStrategy } from '../../config/editorOptions.js';
import { IndentAction, IndentationRule } from '../languageConfiguration.js';
import { OnEnterSupport } from './onEnter.js';

export const enum IndentConsts {
INCREASE_MASK = 0b00000001,
Expand All @@ -23,59 +25,80 @@ function resetGlobalRegex(reg: RegExp) {
export class IndentRulesSupport {

private readonly _indentationRules: IndentationRule;
private readonly _onEnterSupport: OnEnterSupport | null;

constructor(indentationRules: IndentationRule) {
constructor(indentationRules: IndentationRule, onEnterSupport: OnEnterSupport | null) {
this._indentationRules = indentationRules;
this._onEnterSupport = onEnterSupport;
}

public shouldIncrease(text: string): boolean {
public shouldIncrease(autoIndent: EditorAutoIndentStrategy, useOnEnterRulesForInheritedIndent: boolean, text: string): boolean {
if (this._indentationRules) {
if (this._indentationRules.increaseIndentPattern && resetGlobalRegex(this._indentationRules.increaseIndentPattern) && this._indentationRules.increaseIndentPattern.test(text)) {
return true;
}
// if (this._indentationRules.indentNextLinePattern && this._indentationRules.indentNextLinePattern.test(text)) {
// return true;
// }
}
if (this._onEnterSupport && useOnEnterRulesForInheritedIndent) {
const enterResult = this._onEnterSupport.onEnter(autoIndent, '', '', text);
if (enterResult && enterResult.indentAction === IndentAction.Indent) {
return true;
}
}
return false;
}

public shouldDecrease(text: string): boolean {
public shouldDecrease(autoIndent: EditorAutoIndentStrategy, useOnEnterRulesForInheritedIndent: boolean, text: string): boolean {
if (this._indentationRules && this._indentationRules.decreaseIndentPattern && resetGlobalRegex(this._indentationRules.decreaseIndentPattern) && this._indentationRules.decreaseIndentPattern.test(text)) {
return true;
}
if (this._onEnterSupport && useOnEnterRulesForInheritedIndent) {
const enterResult = this._onEnterSupport.onEnter(autoIndent, '', '', text);
if (enterResult && enterResult.indentAction === IndentAction.Outdent) {
return true;
}
}
return false;
}

public shouldIndentNextLine(text: string): boolean {
public shouldIndentNextLine(autoIndent: EditorAutoIndentStrategy, useOnEnterRulesForInheritedIndent: boolean, text: string): boolean {
if (this._indentationRules && this._indentationRules.indentNextLinePattern && resetGlobalRegex(this._indentationRules.indentNextLinePattern) && this._indentationRules.indentNextLinePattern.test(text)) {
return true;
}

if (this._onEnterSupport && useOnEnterRulesForInheritedIndent) {
const enterResult = this._onEnterSupport.onEnter(autoIndent, '', '', text);
if (enterResult && enterResult.indentAction === IndentAction.IndentOutdent) {
return true;
}
}
return false;
}

public shouldIgnore(text: string): boolean {
public shouldIgnore(autoIndent: EditorAutoIndentStrategy, useOnEnterRulesForInheritedIndent: boolean, text: string): boolean {
// the text matches `unIndentedLinePattern`
if (this._indentationRules && this._indentationRules.unIndentedLinePattern && resetGlobalRegex(this._indentationRules.unIndentedLinePattern) && this._indentationRules.unIndentedLinePattern.test(text)) {
return true;
}

if (this._onEnterSupport && useOnEnterRulesForInheritedIndent) {
const enterResult = this._onEnterSupport.onEnter(autoIndent, '', '', text);
if (enterResult && enterResult.indentAction === IndentAction.None) {
return true;
}
}
return false;
}

public getIndentMetadata(text: string): number {
public getIndentMetadata(autoIndent: EditorAutoIndentStrategy, useOnEnterRulesForInheritedIndent: boolean, text: string): number {
let ret = 0;
if (this.shouldIncrease(text)) {
if (this.shouldIncrease(autoIndent, useOnEnterRulesForInheritedIndent, text)) {
ret += IndentConsts.INCREASE_MASK;
}
if (this.shouldDecrease(text)) {
if (this.shouldDecrease(autoIndent, useOnEnterRulesForInheritedIndent, text)) {
ret += IndentConsts.DECREASE_MASK;
}
if (this.shouldIndentNextLine(text)) {
if (this.shouldIndentNextLine(autoIndent, useOnEnterRulesForInheritedIndent, text)) {
ret += IndentConsts.INDENT_NEXTLINE_MASK;
}
if (this.shouldIgnore(text)) {
if (this.shouldIgnore(autoIndent, useOnEnterRulesForInheritedIndent, text)) {
ret += IndentConsts.UNINDENT_MASK;
}
return ret;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { IViewLineTokens, LineTokens } from '../../tokens/lineTokens.js';
import { IndentRulesSupport } from './indentRules.js';
import { StandardTokenType } from '../../encodedTokenAttributes.js';
import { Position } from '../../core/position.js';
import { EditorAutoIndentStrategy } from '../../config/editorOptions.js';

/**
* This class is a wrapper class around {@link IndentRulesSupport}.
Expand All @@ -22,14 +23,20 @@ import { Position } from '../../core/position.js';
export class ProcessedIndentRulesSupport {

private readonly _indentRulesSupport: IndentRulesSupport;
private readonly _autoIndent: EditorAutoIndentStrategy;
private readonly _useOnEnterRulesForInheritedIndent: boolean;
private readonly _indentationLineProcessor: IndentationLineProcessor;

constructor(
model: IVirtualModel,
autoIndent: EditorAutoIndentStrategy,
useOnEnterRulesForInheritedIndent: boolean,
indentRulesSupport: IndentRulesSupport,
languageConfigurationService: ILanguageConfigurationService
) {
this._indentRulesSupport = indentRulesSupport;
this._autoIndent = autoIndent;
this._useOnEnterRulesForInheritedIndent = useOnEnterRulesForInheritedIndent;
this._indentationLineProcessor = new IndentationLineProcessor(model, languageConfigurationService);
}

Expand All @@ -38,31 +45,31 @@ export class ProcessedIndentRulesSupport {
*/
public shouldIncrease(lineNumber: number, newIndentation?: string): boolean {
const processedLine = this._indentationLineProcessor.getProcessedLine(lineNumber, newIndentation);
return this._indentRulesSupport.shouldIncrease(processedLine);
return this._indentRulesSupport.shouldIncrease(this._autoIndent, this._useOnEnterRulesForInheritedIndent, processedLine);
}

/**
* Apply the new indentation and return whether the indentation level should be decreased after the given line number
*/
public shouldDecrease(lineNumber: number, newIndentation?: string): boolean {
const processedLine = this._indentationLineProcessor.getProcessedLine(lineNumber, newIndentation);
return this._indentRulesSupport.shouldDecrease(processedLine);
return this._indentRulesSupport.shouldDecrease(this._autoIndent, this._useOnEnterRulesForInheritedIndent, processedLine);
}

/**
* Apply the new indentation and return whether the indentation level should remain unchanged at the given line number
*/
public shouldIgnore(lineNumber: number, newIndentation?: string): boolean {
const processedLine = this._indentationLineProcessor.getProcessedLine(lineNumber, newIndentation);
return this._indentRulesSupport.shouldIgnore(processedLine);
return this._indentRulesSupport.shouldIgnore(this._autoIndent, this._useOnEnterRulesForInheritedIndent, processedLine);
}

/**
* Apply the new indentation and return whether the indentation level should increase on the line after the given line number
*/
public shouldIndentNextLine(lineNumber: number, newIndentation?: string): boolean {
const processedLine = this._indentationLineProcessor.getProcessedLine(lineNumber, newIndentation);
return this._indentRulesSupport.shouldIndentNextLine(processedLine);
return this._indentRulesSupport.shouldIndentNextLine(this._autoIndent, this._useOnEnterRulesForInheritedIndent, processedLine);
}

}
Expand Down
3 changes: 2 additions & 1 deletion src/vs/editor/common/standalone/standaloneEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ export enum EditorOption {
defaultColorDecorators = 154,
colorDecoratorsActivatedOn = 155,
inlineCompletionsAccessibilityVerbose = 156,
effectiveExperimentalEditContextEnabled = 157
effectiveExperimentalEditContextEnabled = 157,
useOnEnterRulesForInheritedIndent = 158
}

/**
Expand Down
Loading