Skip to content

Commit

Permalink
Fix microsoft#29753. Ignore comments area when reindenting and honor …
Browse files Browse the repository at this point in the history
…onEnter rules when getting inherited indentation.
  • Loading branch information
rebornix committed Jun 28, 2017
1 parent e2a18e4 commit 886f472
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 19 deletions.
63 changes: 53 additions & 10 deletions src/vs/editor/common/modes/languageConfigurationRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,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(model: IVirtualModel, lineNumber: number, honorIntentialIndent: boolean = true) {
public getInheritIndentForLine(model: IVirtualModel, lineNumber: number, honorIntentialIndent: boolean = true): { indentation: string, action: IndentAction, line?: number } {
let indentRulesSupport = this._getIndentRulesSupport(model.getLanguageIdentifier().id);
if (!indentRulesSupport) {
return null;
Expand All @@ -344,12 +344,14 @@ export class LanguageConfigurationRegistryImpl {
if (indentRulesSupport.shouldIncrease(precedingUnIgnoredLineContent) || indentRulesSupport.shouldIndentNextLine(precedingUnIgnoredLineContent)) {
return {
indentation: strings.getLeadingWhitespace(precedingUnIgnoredLineContent),
action: IndentAction.Indent
action: IndentAction.Indent,
line: precedingUnIgnoredLine
};
} else if (indentRulesSupport.shouldDecrease(precedingUnIgnoredLineContent)) {
return {
indentation: strings.getLeadingWhitespace(precedingUnIgnoredLineContent),
action: null
action: null,
line: precedingUnIgnoredLine
};
} else {
// precedingUnIgnoredLine can not be ignored.
Expand All @@ -360,7 +362,8 @@ export class LanguageConfigurationRegistryImpl {
if (precedingUnIgnoredLine === 1) {
return {
indentation: strings.getLeadingWhitespace(model.getLineContent(precedingUnIgnoredLine)),
action: null
action: null,
line: precedingUnIgnoredLine
};
}

Expand All @@ -380,14 +383,16 @@ export class LanguageConfigurationRegistryImpl {

return {
indentation: strings.getLeadingWhitespace(model.getLineContent(stopLine + 1)),
action: null
action: null,
line: stopLine + 1
};
}

if (honorIntentialIndent) {
return {
indentation: strings.getLeadingWhitespace(model.getLineContent(precedingUnIgnoredLine)),
action: null
action: null,
line: precedingUnIgnoredLine
};
} else {
// search from precedingUnIgnoredLine until we find one whose indent is not temporary
Expand All @@ -396,7 +401,8 @@ export class LanguageConfigurationRegistryImpl {
if (indentRulesSupport.shouldIncrease(lineContent)) {
return {
indentation: strings.getLeadingWhitespace(lineContent),
action: IndentAction.Indent
action: IndentAction.Indent,
line: i
};
} else if (indentRulesSupport.shouldIndentNextLine(lineContent)) {
let stopLine = 0;
Expand All @@ -410,19 +416,22 @@ export class LanguageConfigurationRegistryImpl {

return {
indentation: strings.getLeadingWhitespace(model.getLineContent(stopLine + 1)),
action: null
action: null,
line: stopLine + 1
};
} else if (indentRulesSupport.shouldDecrease(lineContent)) {
return {
indentation: strings.getLeadingWhitespace(lineContent),
action: null
action: null,
line: i
};
}
}

return {
indentation: strings.getLeadingWhitespace(model.getLineContent(1)),
action: null
action: null,
line: 1
};
}
}
Expand All @@ -438,6 +447,40 @@ export class LanguageConfigurationRegistryImpl {
let lineContent = virtualModel.getLineContent(lineNumber);

if (indent) {
let inheritLine = indent.line;
if (inheritLine !== undefined) {
let onEnterSupport = this._getOnEnterSupport(languageId);
let enterResult: EnterAction = null;
try {
enterResult = onEnterSupport.onEnter('', virtualModel.getLineContent(inheritLine), '');
} catch (e) {
onUnexpectedError(e);
}

if (enterResult) {
let indentation = strings.getLeadingWhitespace(virtualModel.getLineContent(inheritLine));

if (enterResult.removeText) {
indentation = indentation.substring(0, indentation.length - enterResult.removeText);
}

if (
(enterResult.indentAction === IndentAction.Indent) ||
(enterResult.indentAction === IndentAction.IndentOutdent)
) {
indentation = indentConverter.shiftIndent(indentation);
} else if (enterResult.indentAction === IndentAction.Outdent) {
indentation = indentConverter.unshiftIndent(indentation);
}

if (enterResult.appendText) {
indentation += enterResult.appendText;
}

return strings.getLeadingWhitespace(indentation);
}
}

if (indentRulesSupport.shouldDecrease(lineContent)) {
if (indent.action === IndentAction.Indent) {
return indent.indentation;
Expand Down
50 changes: 41 additions & 9 deletions src/vs/editor/contrib/indentation/common/indentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { EditOperation } from 'vs/editor/common/core/editOperation';
import { TextModel } from 'vs/editor/common/model/textModel';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { ShiftCommand } from 'vs/editor/common/commands/shiftCommand';
import { TextEdit } from 'vs/editor/common/modes';
import { TextEdit, StandardTokenType } from 'vs/editor/common/modes';
import * as IndentUtil from './indentUtils';

export function shiftIndent(tabSize: number, indentation: string, count?: number): string {
Expand Down Expand Up @@ -447,24 +447,39 @@ export class AutoIndentOnPaste implements IEditorContribution {
return newIndentation;
}
};
let indentOfFirstLine = LanguageConfigurationRegistry.getGoodIndentForLine(model, model.getLanguageIdentifier().id, range.startLineNumber, indentConverter);

let startLineNumber = range.startLineNumber;

while (startLineNumber <= range.endLineNumber) {
if (this.shouldIgnoreLine(model, startLineNumber)) {
startLineNumber++;
continue;
}
break;
}

if (startLineNumber > range.endLineNumber) {
return;
}

let indentOfFirstLine = LanguageConfigurationRegistry.getGoodIndentForLine(model, model.getLanguageIdentifier().id, startLineNumber, indentConverter);

if (indentOfFirstLine !== null) {
let firstLineText = model.getLineContent(range.startLineNumber);
let firstLineText = model.getLineContent(startLineNumber);
let oldIndentation = strings.getLeadingWhitespace(firstLineText);
let newSpaceCnt = IndentUtil.getSpaceCnt(indentOfFirstLine, tabSize);
let oldSpaceCnt = IndentUtil.getSpaceCnt(oldIndentation, tabSize);

if (newSpaceCnt !== oldSpaceCnt) {
let newIndent = IndentUtil.generateIndent(newSpaceCnt, tabSize, insertSpaces);
textEdits.push({
range: new Range(range.startLineNumber, 1, range.startLineNumber, oldIndentation.length + 1),
range: new Range(startLineNumber, 1, startLineNumber, oldIndentation.length + 1),
text: newIndent
});
firstLineText = newIndent + firstLineText.substr(oldIndentation.length);
}

if (range.startLineNumber !== range.endLineNumber) {
if (startLineNumber !== range.endLineNumber) {
let virtualModel = {
getLineTokens: (lineNumber: number) => {
return model.getLineTokens(lineNumber);
Expand All @@ -476,20 +491,20 @@ export class AutoIndentOnPaste implements IEditorContribution {
return model.getLanguageIdAtPosition(lineNumber, column);
},
getLineContent: (lineNumber) => {
if (lineNumber === range.startLineNumber) {
if (lineNumber === startLineNumber) {
return firstLineText;
} else {
return model.getLineContent(lineNumber);
}
}
};
let indentOfSecondLine = LanguageConfigurationRegistry.getGoodIndentForLine(virtualModel, model.getLanguageIdentifier().id, range.startLineNumber + 1, indentConverter);
let indentOfSecondLine = LanguageConfigurationRegistry.getGoodIndentForLine(virtualModel, model.getLanguageIdentifier().id, startLineNumber + 1, indentConverter);
let newSpaceCntOfSecondLine = IndentUtil.getSpaceCnt(indentOfSecondLine, tabSize);
let oldSpaceCntOfSecondLine = IndentUtil.getSpaceCnt(strings.getLeadingWhitespace(model.getLineContent(range.startLineNumber + 1)), tabSize);
let oldSpaceCntOfSecondLine = IndentUtil.getSpaceCnt(strings.getLeadingWhitespace(model.getLineContent(startLineNumber + 1)), tabSize);

if (newSpaceCntOfSecondLine !== oldSpaceCntOfSecondLine) {
let spaceCntOffset = newSpaceCntOfSecondLine - oldSpaceCntOfSecondLine;
for (let i = range.startLineNumber + 1; i <= range.endLineNumber; i++) {
for (let i = startLineNumber + 1; i <= range.endLineNumber; i++) {
let lineContent = model.getLineContent(i);
let originalIndent = strings.getLeadingWhitespace(lineContent);
let originalSpacesCnt = IndentUtil.getSpaceCnt(originalIndent, tabSize);
Expand All @@ -512,6 +527,23 @@ export class AutoIndentOnPaste implements IEditorContribution {
this.editor.pushUndoStop();
}

private shouldIgnoreLine(model: ITokenizedModel, lineNumber: number): boolean {
model.forceTokenization(lineNumber);
let nonWhiteSpaceColumn = model.getLineFirstNonWhitespaceColumn(lineNumber);
if (nonWhiteSpaceColumn === 0) {
return true;
}
let tokens = model.getLineTokens(lineNumber);
if (tokens.getTokenCount() > 0) {
let firstNonWhiteSpaceToken = tokens.findTokenAtOffset(nonWhiteSpaceColumn);
if (firstNonWhiteSpaceToken && firstNonWhiteSpaceToken.tokenType === StandardTokenType.Comment) {
return true;
}
}

return false;
}

public getId(): string {
return AutoIndentOnPaste.ID;
}
Expand Down

0 comments on commit 886f472

Please sign in to comment.