irongit

vscode extension to make comments on the right of text line up

format works a little

huncholanehuncholaneauthored
parent b10a89fcommit 5da38eff9f398ffe5ce5afd0b9548cbac9b19341Browse files

4 files changed, +150 -23

+9-2package.json
@@ -14,8 +14,15 @@
1414 "contributes": {
1515 "commands": [
1616 {
17- "command": "comment-aligner.helloWorld",
18- "title": "Hello World"
17+ "command": "comment-aligner.format",
18+ "title": "Format Comments"
19+ }
20+ ],
21+ "keybindings": [
22+ {
23+ "command": "comment-aligner.format",
24+ "key": "alt+a alt+c",
25+ "when": "editorTextFocus"
1926 }
2027 ]
2128 },
+11-21src/extension.ts
@@ -1,26 +1,16 @@
1-// The module 'vscode' contains the VS Code extensibility API
2-// Import the module and reference it with the alias vscode in your code below
3-import * as vscode from 'vscode';
1+import * as vscode from "vscode";
2+import formatter from "./formatter";
43
5-// This method is called when your extension is activated
6-// Your extension is activated the very first time the command is executed
74 export function activate(context: vscode.ExtensionContext) {
8-
9- // Use the console to output diagnostic information (console.log) and errors (console.error)
10- // This line of code will only be executed once when your extension is activated
11- console.log('Congratulations, your extension "comment-aligner" is now active!');
12-
13- // The command has been defined in the package.json file
14- // Now provide the implementation of the command with registerCommand
15- // The commandId parameter must match the command field in package.json
16- const disposable = vscode.commands.registerCommand('comment-aligner.helloWorld', () => {
17- // The code you place here will be executed every time your command is executed
18- // Display a message box to the user
19- vscode.window.showInformationMessage('Hello World from comment-aligner!');
20- });
21-
22- context.subscriptions.push(disposable);
5+ let formatterCommand = vscode.commands.registerCommand(
6+ "comment-aligner.format",
7+ () => {
8+ const editor = vscode.window.activeTextEditor;
9+ if (editor) {
10+ formatter.run(editor);
11+ }
12+ }
13+ );
2314 }
2415
25-// This method is called when your extension is deactivated
2616 export function deactivate() {}
+91-0src/formatter.ts
@@ -0,0 +1,91 @@
1+import * as vscode from "vscode";
2+import { getCommentDelimiter } from "./utils";
3+
4+class Line {
5+ text: string;
6+ range: vscode.Range;
7+ constructor(text: string, range: vscode.Range) {
8+ this.text = text;
9+ this.range = range;
10+ }
11+
12+ format(largest_length: number, delimiter: string) {
13+ const textSplit = this.text.split(delimiter);
14+ if (textSplit.length === 1) {
15+ console.log(`No delimiter found in ${this.text}. Skipping`);
16+ return this.text;
17+ }
18+ if (textSplit[0].trim() === "") {
19+ console.log(`No text before ${delimiter}. Skipping ${this.text}`);
20+ return this.text;
21+ }
22+ const spaces = " ".repeat(
23+ largest_length - this.text.split(delimiter)[0].length
24+ );
25+ console.log(`Adding ${spaces} to ${this.text}`);
26+ return textSplit[0] + spaces + delimiter + textSplit[1];
27+ }
28+
29+ updateEdit(
30+ edit: vscode.TextEditorEdit,
31+ largest_length: number,
32+ delimiter: string
33+ ) {
34+ edit.replace(this.range, this.format(largest_length, delimiter));
35+ }
36+}
37+
38+class Block {
39+ largest_length = 0;
40+ lines: Line[] = [];
41+
42+ addLine(text: string, range: vscode.Range, delimiter: string) {
43+ const length = text.split(delimiter)[0].length;
44+ if (length > this.largest_length) {
45+ this.largest_length = length;
46+ }
47+ this.lines.push(new Line(text, range));
48+ }
49+
50+ updateEdit(edit: vscode.TextEditorEdit, delimiter: string) {
51+ this.lines.forEach((line) => {
52+ line.updateEdit(edit, this.largest_length, delimiter);
53+ });
54+ }
55+}
56+
57+class Formatter {
58+ blocks: Block[] = [];
59+
60+ run(editor: vscode.TextEditor) {
61+ const doc = editor.document;
62+ const text = doc.getText();
63+ const lines = text.split("\n");
64+ console.log(`Formatting ${lines.length} lines`);
65+ let block: Block | null = null;
66+ const commentDelimiter = getCommentDelimiter(editor);
67+
68+ lines.forEach((lineText, index) => {
69+ const line = doc.lineAt(index);
70+ if (line.text.includes(commentDelimiter)) {
71+ if (!block) {
72+ block = new Block();
73+ this.blocks.push(block);
74+ }
75+ block.addLine(lineText, line.range, commentDelimiter);
76+ } else {
77+ block = null;
78+ }
79+ });
80+
81+ editor.edit((edit) => {
82+ this.blocks.forEach((block) => {
83+ block.updateEdit(edit, commentDelimiter);
84+ });
85+ });
86+ this.blocks = [];
87+ }
88+}
89+
90+const formatter = new Formatter();
91+export default formatter;
+39-0src/utils.ts
@@ -9,3 +9,42 @@ export function setConfig(key: string, value: any) {
99 .getConfiguration("comment-aligner")
1010 .update(key, value, true);
1111 }
12+
13+export function getCommentDelimiter(editor: vscode.TextEditor) {
14+ switch (editor.document.languageId) {
15+ case "javascript":
16+ return "//";
17+ case "typescript":
18+ return "//";
19+ case "javascriptreact":
20+ return "//";
21+ case "typescriptreact":
22+ return "//";
23+ case "html":
24+ return "<!--";
25+ case "xml":
26+ return "<!--";
27+ case "css":
28+ return "/*";
29+ case "scss":
30+ return "/*";
31+ case "less":
32+ return "/*";
33+ case "json":
34+ return "//";
35+ case "python":
36+ return "#";
37+ case "ruby":
38+ return "#";
39+ case "shellscript":
40+ return "#";
41+ case "powershell":
42+ return "#";
43+ case "properties":
44+ return "#";
45+ case "plaintext":
46+ return "#";
47+ default:
48+ throw new Error("Unsupported language");
49+ }
50+}