mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-06 14:24:04 -05:00
[folding] fold comments / region
This commit is contained in:
@@ -17,7 +17,7 @@ import { ScrollType, IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction, registerInstantiatedEditorAction } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { FoldingModel, setCollapseStateAtLevel, CollapseMemento, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateForMatchingLines } from 'vs/editor/contrib/folding/foldingModel';
|
||||
import { FoldingModel, setCollapseStateAtLevel, CollapseMemento, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateForMatchingLines, setCollapseStateForType } from 'vs/editor/contrib/folding/foldingModel';
|
||||
import { FoldingDecorationProvider } from './foldingDecorations';
|
||||
import { FoldingRegions } from './foldingRanges';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
@@ -28,7 +28,7 @@ import { IRange } from 'vs/editor/common/core/range';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
import { IndentRangeProvider } from 'vs/editor/contrib/folding/indentRangeProvider';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { FoldingProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { FoldingProviderRegistry, FoldingRangeType } from 'vs/editor/common/modes';
|
||||
import { SyntaxRangeProvider } from './syntaxRangeProvider';
|
||||
|
||||
export const ID = 'editor.contrib.folding';
|
||||
@@ -553,10 +553,14 @@ class FoldAllBlockCommentsAction extends FoldingAction<void> {
|
||||
}
|
||||
|
||||
invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void {
|
||||
let comments = LanguageConfigurationRegistry.getComments(editor.getModel().getLanguageIdentifier().id);
|
||||
if (comments && comments.blockCommentStartToken) {
|
||||
let regExp = new RegExp('^\\s*' + escapeRegExpCharacters(comments.blockCommentStartToken));
|
||||
setCollapseStateForMatchingLines(foldingModel, regExp, true);
|
||||
if (foldingModel.regions.hasTypes()) {
|
||||
setCollapseStateForType(foldingModel, FoldingRangeType.Comment, true);
|
||||
} else {
|
||||
let comments = LanguageConfigurationRegistry.getComments(editor.getModel().getLanguageIdentifier().id);
|
||||
if (comments && comments.blockCommentStartToken) {
|
||||
let regExp = new RegExp('^\\s*' + escapeRegExpCharacters(comments.blockCommentStartToken));
|
||||
setCollapseStateForMatchingLines(foldingModel, regExp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -577,10 +581,14 @@ class FoldAllRegionsAction extends FoldingAction<void> {
|
||||
}
|
||||
|
||||
invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void {
|
||||
let foldingRules = LanguageConfigurationRegistry.getFoldingRules(editor.getModel().getLanguageIdentifier().id);
|
||||
if (foldingRules && foldingRules.markers && foldingRules.markers.start) {
|
||||
let regExp = new RegExp(foldingRules.markers.start);
|
||||
setCollapseStateForMatchingLines(foldingModel, regExp, true);
|
||||
if (foldingModel.regions.hasTypes()) {
|
||||
setCollapseStateForType(foldingModel, FoldingRangeType.Region, true);
|
||||
} else {
|
||||
let foldingRules = LanguageConfigurationRegistry.getFoldingRules(editor.getModel().getLanguageIdentifier().id);
|
||||
if (foldingRules && foldingRules.markers && foldingRules.markers.start) {
|
||||
let regExp = new RegExp(foldingRules.markers.start);
|
||||
setCollapseStateForMatchingLines(foldingModel, regExp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,10 +609,14 @@ class UnfoldAllRegionsAction extends FoldingAction<void> {
|
||||
}
|
||||
|
||||
invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void {
|
||||
let foldingRules = LanguageConfigurationRegistry.getFoldingRules(editor.getModel().getLanguageIdentifier().id);
|
||||
if (foldingRules && foldingRules.markers && foldingRules.markers.start) {
|
||||
let regExp = new RegExp(foldingRules.markers.start);
|
||||
setCollapseStateForMatchingLines(foldingModel, regExp, false);
|
||||
if (foldingModel.regions.hasTypes()) {
|
||||
setCollapseStateForType(foldingModel, FoldingRangeType.Region, false);
|
||||
} else {
|
||||
let foldingRules = LanguageConfigurationRegistry.getFoldingRules(editor.getModel().getLanguageIdentifier().id);
|
||||
if (foldingRules && foldingRules.markers && foldingRules.markers.start) {
|
||||
let regExp = new RegExp(foldingRules.markers.start);
|
||||
setCollapseStateForMatchingLines(foldingModel, regExp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,3 +308,18 @@ export function setCollapseStateForMatchingLines(foldingModel: FoldingModel, reg
|
||||
}
|
||||
foldingModel.toggleCollapseState(toToggle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all regions of the given type
|
||||
* @param foldingModel the folding model
|
||||
*/
|
||||
export function setCollapseStateForType(foldingModel: FoldingModel, type: string, doCollapse: boolean): void {
|
||||
let regions = foldingModel.regions;
|
||||
let toToggle = [];
|
||||
for (let i = regions.length - 1; i >= 0; i--) {
|
||||
if (doCollapse !== regions.isCollapsed(i) && type === regions.getType(i)) {
|
||||
toToggle.push(regions.toRegion(i));
|
||||
}
|
||||
}
|
||||
foldingModel.toggleCollapseState(toToggle);
|
||||
}
|
||||
|
||||
@@ -20,14 +20,16 @@ export class FoldingRegions {
|
||||
private _endIndexes: Uint32Array;
|
||||
private _collapseStates: Uint32Array;
|
||||
private _parentsComputed: boolean;
|
||||
private _types: string[] | undefined;
|
||||
|
||||
constructor(startIndexes: Uint32Array, endIndexes: Uint32Array) {
|
||||
constructor(startIndexes: Uint32Array, endIndexes: Uint32Array, types?: string[]) {
|
||||
if (startIndexes.length !== endIndexes.length || startIndexes.length > MAX_FOLDING_REGIONS) {
|
||||
throw new Error('invalid startIndexes or endIndexes size');
|
||||
}
|
||||
this._startIndexes = startIndexes;
|
||||
this._endIndexes = endIndexes;
|
||||
this._collapseStates = new Uint32Array(Math.ceil(startIndexes.length / 32));
|
||||
this._types = types;
|
||||
}
|
||||
|
||||
private ensureParentIndices() {
|
||||
@@ -67,6 +69,14 @@ export class FoldingRegions {
|
||||
return this._endIndexes[index] & MAX_LINE_NUMBER;
|
||||
}
|
||||
|
||||
public getType(index: number): string | undefined {
|
||||
return this._types ? this._types[index] : void 0;
|
||||
}
|
||||
|
||||
public hasTypes() {
|
||||
return !!this._types;
|
||||
}
|
||||
|
||||
public isCollapsed(index: number): boolean {
|
||||
let arrayIndex = (index / 32) | 0;
|
||||
let bit = index % 32;
|
||||
|
||||
@@ -52,6 +52,7 @@ export class RangesCollector {
|
||||
private _endIndexes: number[];
|
||||
private _nestingLevels: number[];
|
||||
private _nestingLevelCounts: number[];
|
||||
private _types: string[];
|
||||
private _length: number;
|
||||
private _foldingRangesLimit: number;
|
||||
|
||||
@@ -60,11 +61,12 @@ export class RangesCollector {
|
||||
this._endIndexes = [];
|
||||
this._nestingLevels = [];
|
||||
this._nestingLevelCounts = [];
|
||||
this._types = [];
|
||||
this._length = 0;
|
||||
this._foldingRangesLimit = foldingRangesLimit;
|
||||
}
|
||||
|
||||
public add(startLineNumber: number, endLineNumber: number, nestingLevel: number) {
|
||||
public add(startLineNumber: number, endLineNumber: number, type: string, nestingLevel: number) {
|
||||
if (startLineNumber > MAX_LINE_NUMBER || endLineNumber > MAX_LINE_NUMBER) {
|
||||
return;
|
||||
}
|
||||
@@ -72,6 +74,7 @@ export class RangesCollector {
|
||||
this._startIndexes[index] = startLineNumber;
|
||||
this._endIndexes[index] = endLineNumber;
|
||||
this._nestingLevels[index] = nestingLevel;
|
||||
this._types[index] = type;
|
||||
this._length++;
|
||||
if (nestingLevel < 30) {
|
||||
this._nestingLevelCounts[nestingLevel] = (this._nestingLevelCounts[nestingLevel] || 0) + 1;
|
||||
@@ -86,7 +89,7 @@ export class RangesCollector {
|
||||
startIndexes[i] = this._startIndexes[i];
|
||||
endIndexes[i] = this._endIndexes[i];
|
||||
}
|
||||
return new FoldingRegions(startIndexes, endIndexes);
|
||||
return new FoldingRegions(startIndexes, endIndexes, this._types);
|
||||
} else {
|
||||
let entries = 0;
|
||||
let maxLevel = this._nestingLevelCounts.length;
|
||||
@@ -102,15 +105,17 @@ export class RangesCollector {
|
||||
}
|
||||
let startIndexes = new Uint32Array(entries);
|
||||
let endIndexes = new Uint32Array(entries);
|
||||
let types = [];
|
||||
for (let i = 0, k = 0; i < this._length; i++) {
|
||||
let level = this._nestingLevels[i];
|
||||
if (level < maxLevel) {
|
||||
startIndexes[k] = this._startIndexes[i];
|
||||
endIndexes[k] = this._endIndexes[i];
|
||||
types[k] = this._types[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return new FoldingRegions(startIndexes, endIndexes);
|
||||
return new FoldingRegions(startIndexes, endIndexes, types);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -132,20 +137,20 @@ export function sanitizeRanges(rangeData: IFoldingRangeData[]): FoldingRegions {
|
||||
for (let entry of sorted) {
|
||||
if (!top) {
|
||||
top = entry;
|
||||
collector.add(entry.startLineNumber, entry.endLineNumber, previous.length);
|
||||
collector.add(entry.startLineNumber, entry.endLineNumber, entry.type, previous.length);
|
||||
} else {
|
||||
if (entry.startLineNumber > top.startLineNumber) {
|
||||
if (entry.endLineNumber <= top.endLineNumber) {
|
||||
previous.push(top);
|
||||
top = entry;
|
||||
collector.add(entry.startLineNumber, entry.endLineNumber, previous.length);
|
||||
collector.add(entry.startLineNumber, entry.endLineNumber, entry.type, previous.length);
|
||||
} else if (entry.startLineNumber > top.endLineNumber) {
|
||||
do {
|
||||
top = previous.pop();
|
||||
} while (top && entry.startLineNumber > top.endLineNumber);
|
||||
previous.push(top);
|
||||
top = entry;
|
||||
collector.add(entry.startLineNumber, entry.endLineNumber, previous.length);
|
||||
collector.add(entry.startLineNumber, entry.endLineNumber, entry.type, previous.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,7 +589,7 @@ export namespace ProgressLocation {
|
||||
export namespace FoldingRangeList {
|
||||
export function from(rangeList: vscode.FoldingRangeList): modes.IFoldingRangeList {
|
||||
return {
|
||||
ranges: rangeList.ranges.map(r => ({ startLineNumber: r.startLine + 1, endLineNumber: r.endLine + 1 }))
|
||||
ranges: rangeList.ranges.map(r => ({ startLineNumber: r.startLine + 1, endLineNumber: r.endLine + 1, type: r.type }))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1677,9 +1677,9 @@ export class FoldingRange {
|
||||
|
||||
endLine: number;
|
||||
|
||||
type?: FoldingRangeType;
|
||||
type?: FoldingRangeType | string;
|
||||
|
||||
constructor(startLine: number, endLine: number, type?: FoldingRangeType) {
|
||||
constructor(startLine: number, endLine: number, type?: FoldingRangeType | string) {
|
||||
this.startLine = startLine;
|
||||
this.endLine = endLine;
|
||||
this.type = type;
|
||||
|
||||
Reference in New Issue
Block a user