Skip to content

Commit bc30181

Browse files
committed
Add command and keyboard shortcut to prettify the current document
1 parent 6d3f8aa commit bc30181

8 files changed

Lines changed: 120 additions & 16 deletions

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Makes tables more readable for humans. Compatible with the Markdown writer plugi
1111
- Save space by not right-padding the last column if the table has no border.
1212
- Support empty columns inside tables.
1313
- Support column alignment options with ":".
14-
- CLI support to format files.
14+
- CLI support to prettify files.
1515

1616
![feature X](assets/animation.gif)
1717

@@ -20,7 +20,7 @@ Makes tables more readable for humans. Compatible with the Markdown writer plugi
2020
Formatting files or checking if they're already formatted is possible from the command line. This requires `node` and `npm`.
2121

2222
The extension has to be downloaded and compiled:
23-
- Download the extension from git or locate your VSCode installed extension path.
23+
- Locate your VSCode installed extension path or download the extension from Github.
2424
- Go to the extension directory.
2525
- Run `npm install`.
2626
- Run `npm run compile`.
@@ -31,18 +31,20 @@ The tipical location of the installed extension (your actual version might diffe
3131
- Linux ~/.vscode/extensions/darkriszty.markdown-table-prettify-3.0.0
3232

3333
Available features from the command line:
34-
- To format a file: `npm run --silent prettify-md < input.md`.
35-
- To format a file and save the output: `npm run --silent prettify-md < input.md > output.md`.
34+
- To prettify a file: `npm run --silent prettify-md < input.md`.
35+
- To prettify a file and save the output: `npm run --silent prettify-md < input.md > output.md`.
3636
- To check whether a file is prettyfied or not: `npm run --silent check-md < input.md`. This will fail with an exception and return code `1` if the file is not prettyfied.
3737

3838
> Note: the `--silent` switch sets the npm log level to silent, which is useful to hide the executed file name and concentrate on the actual output.
3939
4040
## Extension Settings
4141

42-
The extension is available for markdown language mode. It can either format a selected table (`Format Selection`) or the entire document (`Format Document`).
42+
The extension is available for markdown language mode. It can either prettify a selected table (`Format Selection`) or the entire document (`Format Document`).
43+
A VSCode command called `Prettify markdown tables` is also available to format format the currently opened document.
4344

4445
Configurable settings:
4546
- The maximum texth length of a selection/entire document to consider for formatting. Defaults to 1M chars. There is no limit when running from the command line.
47+
- Keyboard shortcut to prettify the currently opened markdown document. Default: CTRL+ALT+M (CMD+ALT+M on Mac).
4648

4749
## Known Issues
4850

package.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,19 @@
3838
"description": "The maximum text length to apply formatting to."
3939
}
4040
}
41-
}
41+
},
42+
"commands": [{
43+
"command": "markdownTablePrettify.prettifyTables",
44+
"title": "Prettify markdown tables"
45+
}],
46+
"keybindings": [
47+
{
48+
"command": "markdownTablePrettify.prettifyTables",
49+
"key": "ctrl+alt+m",
50+
"mac": "cmd+alt+m",
51+
"when": "editorTextFocus && editorLangId == markdown && !editorReadonly && !inCompositeEditor"
52+
}
53+
]
4254
},
4355
"capabilities": {
4456
"documentFormattingProvider": "true"

src/extension/extension.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
'use strict';
22
import * as vscode from 'vscode';
3-
import { getDocumentRangePrettyfier, getDocumentPrettyfier } from './prettyfierFactory';
3+
import { getDocumentRangePrettyfier, getDocumentPrettyfier, getDocumentPrettyfierCommand } from './prettyfierFactory';
44

55
// This method is called when the extension is activated.
66
// The extension is activated the very first time the command is executed.
77
export function activate(context: vscode.ExtensionContext): void {
88
const MD_MODE: vscode.DocumentFilter = { language: "markdown" };
9+
const command = "markdownTablePrettify.prettifyTables";
910

1011
context.subscriptions.push(
1112
vscode.languages.registerDocumentRangeFormattingEditProvider(MD_MODE, getDocumentRangePrettyfier()),
12-
vscode.languages.registerDocumentFormattingEditProvider(MD_MODE, getDocumentPrettyfier())
13+
vscode.languages.registerDocumentFormattingEditProvider(MD_MODE, getDocumentPrettyfier()),
14+
vscode.commands.registerTextEditorCommand(command, textEditor => getDocumentPrettyfierCommand().prettifyDocument(textEditor))
1315
);
1416
}
1517

src/extension/prettyfierFactory.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode';
22
import { ConfigSizeLimitChecker } from '../prettyfiers/sizeLimit/configSizeLimitCheker';
33
import { TableDocumentPrettyfier } from './tableDocumentPrettyfier';
4+
import { TableDocumentPrettyfierCommand } from './tableDocumentPrettyfierCommand';
45
import { TableFinder } from '../tableFinding/tableFinder';
56
import { TableDocumentRangePrettyfier } from "./tableDocumentRangePrettyfier";
67
import { ILogger } from '../diagnostics/logger';
@@ -41,6 +42,19 @@ export function getDocumentPrettyfier(strict: boolean = true): vscode.DocumentFo
4142
);
4243
}
4344

45+
export function getDocumentPrettyfierCommand(): TableDocumentPrettyfierCommand {
46+
const loggers = getLoggers();
47+
const sizeLimitCheker = getSizeLimitChecker(loggers);
48+
49+
return new TableDocumentPrettyfierCommand(
50+
new MultiTablePrettyfier(
51+
new TableFinder(new TableValidator(new SelectionInterpreter(true))),
52+
getSingleTablePrettyfier(loggers, sizeLimitCheker),
53+
sizeLimitCheker
54+
)
55+
);
56+
}
57+
4458
function getSingleTablePrettyfier(loggers: ILogger[], sizeLimitCheker: ConfigSizeLimitChecker): SingleTablePrettyfier {
4559
return new SingleTablePrettyfier(
4660
new TableFactory(
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as vscode from "vscode";
2+
import { MultiTablePrettyfier } from "../prettyfiers/multiTablePrettyfier";
3+
4+
export class TableDocumentPrettyfierCommand {
5+
6+
constructor(
7+
private readonly _multiTablePrettyfier: MultiTablePrettyfier
8+
) { }
9+
10+
public prettifyDocument(editor: vscode.TextEditor) {
11+
if (editor.document.languageId !== "markdown") {
12+
return;
13+
}
14+
15+
const formattedDocument: string = this._multiTablePrettyfier.formatTables(editor.document.getText());
16+
17+
editor.edit(textEditorEdit => {
18+
textEditorEdit.replace(new vscode.Range(
19+
new vscode.Position(0, 0),
20+
new vscode.Position(editor.document.lineCount - 1, Number.MAX_SAFE_INTEGER)
21+
), formattedDocument);
22+
});
23+
}
24+
}

test/unitTests/extension/tableDocumentPrettyfier.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ suite("TableDocumentPrettyfier tests", () => {
2222

2323
const result = sut.provideDocumentFormattingEdits(document, null, null);
2424

25-
assert.equal(result.length, 1);
26-
assert.equal(result[0].newText, expectedResult);
27-
assert.equal(result[0].range.start.line, 0);
28-
assert.equal(result[0].range.start.character, 0);
29-
assert.equal(result[0].range.end.line, 9);
30-
assert.equal(result[0].range.end.character, Number.MAX_SAFE_INTEGER);
25+
assert.strictEqual(result.length, 1);
26+
assert.strictEqual(result[0].newText, expectedResult);
27+
assert.strictEqual(result[0].range.start.line, 0);
28+
assert.strictEqual(result[0].range.start.character, 0);
29+
assert.strictEqual(result[0].range.end.line, 9);
30+
assert.strictEqual(result[0].range.end.character, Number.MAX_SAFE_INTEGER);
3131
_multiTablePrettyfier.verify(multiTablePrettyfier => multiTablePrettyfier.formatTables(It.isAny()), Times.once());
3232
});
3333

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as vscode from 'vscode';
2+
import { IMock, Mock, Times, It } from "typemoq";
3+
import { TableDocumentPrettyfierCommand } from "../../../src/extension/tableDocumentPrettyfierCommand";
4+
import { MarkdownTextDocumentStub } from "../../stubs/markdownTextDocumentStub";
5+
import { MultiTablePrettyfier } from "../../../src/prettyfiers/multiTablePrettyfier";
6+
7+
suite("TableDocumentPrettyfierCommand tests", () => {
8+
9+
let _multiTablePrettyfier: IMock<MultiTablePrettyfier>;
10+
11+
setup(() => {
12+
_multiTablePrettyfier = Mock.ofType<MultiTablePrettyfier>();
13+
});
14+
15+
test("prettifyDocument() calls MultiTablePrettyfier and edit()", () => {
16+
const sut = createSut();
17+
const input = Array(10).fill("hello world").join("\n");
18+
const expectedResult = Array(10).fill("expected result").join("\n");
19+
const textEditor = Mock.ofType<vscode.TextEditor>();
20+
const document = new MarkdownTextDocumentStub(input);
21+
textEditor.setup(e => e.document).returns(() => document);
22+
// Note: due to a limitation of the MarkdownTextDocumentStub with OS line endings, we use `It.isAny()` instead of `input`.
23+
_multiTablePrettyfier.setup(multiTablePrettyfier => multiTablePrettyfier.formatTables(It.isAny())).returns(() => expectedResult)
24+
25+
sut.prettifyDocument(textEditor.object);
26+
27+
textEditor.verify(e => e.edit(It.isAny()), Times.once());
28+
_multiTablePrettyfier.verify(multiTablePrettyfier => multiTablePrettyfier.formatTables(It.isAny()), Times.once());
29+
});
30+
31+
test("prettifyDocument() for non-markdown documents doesn't do anything", () => {
32+
const sut = createSut();
33+
const input = Array(10).fill("hello world").join("\n");
34+
const expectedResult = Array(10).fill("expected result").join("\n");
35+
const textEditor = Mock.ofType<vscode.TextEditor>();
36+
const document = new MarkdownTextDocumentStub(input);
37+
document.languageId = "text";
38+
textEditor.setup(e => e.document).returns(() => document);
39+
_multiTablePrettyfier.setup(multiTablePrettyfier => multiTablePrettyfier.formatTables(It.isAny())).returns(() => expectedResult)
40+
41+
sut.prettifyDocument(textEditor.object);
42+
43+
textEditor.verify(e => e.edit(It.isAny()), Times.never());
44+
_multiTablePrettyfier.verify(multiTablePrettyfier => multiTablePrettyfier.formatTables(It.isAny()), Times.never());
45+
});
46+
47+
function createSut(): TableDocumentPrettyfierCommand {
48+
return new TableDocumentPrettyfierCommand(_multiTablePrettyfier.object);
49+
}
50+
});

test/unitTests/extension/tableDocumentRangePrettyfier.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ suite("TableDocumentRangePrettyfier tests", () => {
2222

2323
const result = sut.provideDocumentRangeFormattingEdits(document, range, null, null);
2424

25-
assert.equal(result.length, 1);
26-
assert.equal(result[0].range, range);
25+
assert.strictEqual(result.length, 1);
26+
assert.strictEqual(result[0].range, range);
2727
_singleTablePrettyfier.verify(_ => _.prettifyTable(It.isAny(), It.isAny()), Times.once());
2828
});
2929

0 commit comments

Comments
 (0)