提交 e48a3284 编写于 作者: M Matt Bierner

When folding markdown headers, leave single new line before next header

上级 e822e655
......@@ -31,6 +31,9 @@ export default class MarkdownFoldingProvider implements vscode.FoldingProvider {
for (let i = startIndex + 1; i < toc.length; ++i) {
if (toc[i].level <= entry.level) {
end = toc[i].line - 1;
if (document.lineAt(end).isEmptyOrWhitespace && end >= start + 1) {
end = end - 1;
}
break;
}
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as vscode from 'vscode';
import 'mocha';
import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributions } from '../markdownExtensions';
import MarkdownFoldingProvider from '../features/foldingProvider';
import { InMemoryDocument } from './inMemoryDocument';
const testFileName = vscode.Uri.parse('test.md');
suite('markdown.FoldingProvider', () => {
test('Should not return anything for empty document', async () => {
const folds = await getFoldsForDocument(``);
assert.strictEqual(folds.ranges.length, 0);
});
test('Should not return anything for document without headers', async () => {
const folds = await getFoldsForDocument(`a
**b** afas
a#b
a`);
assert.strictEqual(folds.ranges.length, 0);
});
test('Should fold from header to end of document', async () => {
const folds = await getFoldsForDocument(`a
# b
c
d`);
assert.strictEqual(folds.ranges.length, 1);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 3);
});
test('Should leave single newline before next header', async () => {
const folds = await getFoldsForDocument(`
# a
x
# b
y`);
assert.strictEqual(folds.ranges.length, 2);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 3);
});
test('Should collapse multuple newlines to single newline before next header', async () => {
const folds = await getFoldsForDocument(`
# a
x
# b
y`);
assert.strictEqual(folds.ranges.length, 2);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 5);
});
test('Should not collapse if there is no newline before next header', async () => {
const folds = await getFoldsForDocument(`
# a
x
# b
y`);
assert.strictEqual(folds.ranges.length, 2);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 2);
});
});
async function getFoldsForDocument(contents: string) {
const doc = new InMemoryDocument(testFileName, contents);
const provider = new MarkdownFoldingProvider(newEngine());
return await provider.provideFoldingRanges(doc, {}, new vscode.CancellationTokenSource().token);
}
function newEngine(): MarkdownEngine {
return new MarkdownEngine(new class implements MarkdownContributions {
readonly previewScripts: vscode.Uri[] = [];
readonly previewStyles: vscode.Uri[] = [];
readonly previewResourceRoots: vscode.Uri[] = [];
readonly markdownItPlugins: Promise<(md: any) => any>[] = [];
});
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
export class InMemoryDocument implements vscode.TextDocument {
private readonly _lines: string[];
constructor(
public readonly uri: vscode.Uri,
private readonly _contents: string
) {
this._lines = this._contents.split(/\n/g);
}
fileName: string = '';
isUntitled: boolean = false;
languageId: string = '';
version: number = 1;
isDirty: boolean = false;
isClosed: boolean = false;
eol: vscode.EndOfLine = vscode.EndOfLine.LF;
get lineCount(): number {
return this._lines.length;
}
lineAt(line: any): vscode.TextLine {
return {
lineNumber: line,
text: this._lines[line],
range: new vscode.Range(0, 0, 0, 0),
firstNonWhitespaceCharacterIndex: 0,
rangeIncludingLineBreak: new vscode.Range(0, 0, 0, 0),
isEmptyOrWhitespace: false
};
}
offsetAt(_position: vscode.Position): never {
throw new Error('Method not implemented.');
}
positionAt(_offset: number): never {
throw new Error('Method not implemented.');
}
getText(_range?: vscode.Range | undefined): string {
return this._contents;
}
getWordRangeAtPosition(_position: vscode.Position, _regex?: RegExp | undefined): never {
throw new Error('Method not implemented.');
}
validateRange(_range: vscode.Range): never {
throw new Error('Method not implemented.');
}
validatePosition(_position: vscode.Position): never {
throw new Error('Method not implemented.');
}
save(): never {
throw new Error('Method not implemented.');
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import 'mocha';
import { TableOfContentsProvider } from '../tableOfContentsProvider';
import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributions } from '../markdownExtensions';
import { InMemoryDocument } from './inMemoryDocument';
const testFileName = vscode.Uri.parse('test.md');
......@@ -83,62 +84,6 @@ suite('markdown.TableOfContentsProvider', () => {
});
});
class InMemoryDocument implements vscode.TextDocument {
private readonly _lines: string[];
constructor(
public readonly uri: vscode.Uri,
private readonly _contents: string
) {
this._lines = this._contents.split(/\n/g);
}
fileName: string = '';
isUntitled: boolean = false;
languageId: string = '';
version: number = 1;
isDirty: boolean = false;
isClosed: boolean = false;
eol: vscode.EndOfLine = vscode.EndOfLine.LF;
get lineCount(): number {
return this._lines.length;
}
lineAt(line: any): vscode.TextLine {
return {
lineNumber: line,
text: this._lines[line],
range: new vscode.Range(0, 0, 0, 0),
firstNonWhitespaceCharacterIndex: 0,
rangeIncludingLineBreak: new vscode.Range(0, 0, 0, 0),
isEmptyOrWhitespace: false
};
}
offsetAt(_position: vscode.Position): never {
throw new Error('Method not implemented.');
}
positionAt(_offset: number): never {
throw new Error('Method not implemented.');
}
getText(_range?: vscode.Range | undefined): string {
return this._contents;
}
getWordRangeAtPosition(_position: vscode.Position, _regex?: RegExp | undefined): never {
throw new Error('Method not implemented.');
}
validateRange(_range: vscode.Range): never {
throw new Error('Method not implemented.');
}
validatePosition(_position: vscode.Position): never {
throw new Error('Method not implemented.');
}
save(): never {
throw new Error('Method not implemented.');
}
}
function newEngine(): MarkdownEngine {
return new MarkdownEngine(new class implements MarkdownContributions {
readonly previewScripts: vscode.Uri[] = [];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册