irongit

A Regex file extension that makes it way easier to edit large regex.

buttons show

huncholanehuncholaneauthored
parent 51f134bcommit 95b4832c0bf4a54df0cd61383476b87574124d39Browse files

5 files changed, +129 -20

+18-2src/extension.ts
@@ -1,9 +1,25 @@
11 import * as vscode from "vscode";
22 import { output } from "./output";
3+import { editorsContainRegexFile } from "./utils";
4+import { regexButtons } from "./regexButtons";
35
46 export function activate(context: vscode.ExtensionContext) {
57 output.activate();
6- output.log("Starting File Regex extension");
8+ regexButtons.activate(context);
9+
10+ vscode.window.onDidChangeActiveTextEditor((editor) => {
11+ if (editor && editor.document.uri.scheme === "file") {
12+ if (editor.document.languageId === "regex") {
13+ output.log("Regex file opened");
14+ }
15+ }
16+ if (!editorsContainRegexFile()) {
17+ console.log("No regex file opened");
18+ }
19+ });
720 }
821
9-export function deactivate() {}
22+export function deactivate() {
23+ output.log("Stopping File Regex extension");
24+ output.deactivate();
25+}
+5-0src/global.ts
@@ -3,3 +3,8 @@ import * as vscode from "vscode";
33 export function getConfig(): vscode.WorkspaceConfiguration {
44 return vscode.workspace.getConfiguration("regex-file");
55 }
6+
7+export function setConfig(key: string, value: any) {
8+ const config = getConfig();
9+ return config.update(key, value, true);
10+}
+9-2src/output.ts
@@ -4,8 +4,10 @@ class Output {
44 outputChannel: vscode.OutputChannel | undefined;
55
66 activate() {
7- this.outputChannel = vscode.window.createOutputChannel("Regex File");
8- this.show();
7+ if (!this.outputChannel) {
8+ this.outputChannel = vscode.window.createOutputChannel("Regex File");
9+ this.show();
10+ }
911 }
1012
1113 show() {
@@ -28,6 +30,11 @@ class Output {
2830 this.outputChannel?.appendLine(message);
2931 console.log(message);
3032 }
33+
34+ deactivate() {
35+ this.hide();
36+ this.dispose();
37+ }
3138 }
3239
3340 export const output = new Output();
+87-16src/regexButtons.ts
@@ -2,37 +2,108 @@ import * as vscode from "vscode";
22 import { getConfig } from "./global";
33 import { output } from "./output";
44
5-const FLAG_CHARS = ["g", "i", "m", "s", "u", "y", "x"];
5+type FlagChar = "g" | "i" | "m" | "s" | "u" | "y" | "x";
6+type FlagState = "on" | "off";
7+type FlagDict = { [key in FlagChar]: Flag };
8+type Flag = {
9+ char: FlagChar;
10+ tooltip: string;
11+ button?: vscode.StatusBarItem;
12+ state?: FlagState;
13+};
14+
15+const FLAG_ICONS = {
16+ on: "$(check)",
17+ off: "$(x)",
18+};
19+
20+const FLAG_COLORS = {
21+ on: "#00FF00",
22+ off: "#FF0000",
23+};
24+
25+const FLAG_CHARS: Flag[] = [
26+ { char: "g", tooltip: "Global search: find all matches in the string" },
27+ {
28+ char: "i",
29+ tooltip:
30+ "Case-insensitive search: match both uppercase and lowercase characters",
31+ },
32+ {
33+ char: "m",
34+ tooltip: "Multi-line search: ^ and $ match the start and end of each line",
35+ },
36+ { char: "s", tooltip: "Dot matches newline: . matches newline characters" },
37+ { char: "u", tooltip: "Unicode: enable full Unicode matching" },
38+ {
39+ char: "y",
40+ tooltip:
41+ "Sticky search: start at the last index where the previous match ended",
42+ },
43+ {
44+ char: "x",
45+ tooltip:
46+ "Extended: allow whitespace and comments within the pattern (non-standard in JavaScript)",
47+ },
48+];
649
750 class RegexButtons {
8- flagButtons: {
9- [key: string]: {
10- state: "on" | "off";
11- button: vscode.StatusBarItem;
12- };
13- } = {};
51+ context: vscode.ExtensionContext | undefined;
52+ flags: FlagDict;
1453
15- constructor() {}
54+ constructor() {
55+ this.flags = FLAG_CHARS.reduce((acc, flag) => {
56+ flag.state = "off";
57+ acc[flag.char] = flag;
58+ return acc;
59+ }, {} as { [key in FlagChar]: Flag });
60+ }
1661
1762 activate(context: vscode.ExtensionContext) {
18- this.createButtons(context);
19- this.updateFlagsFromConfig();
63+ this.context = context;
64+ this.createButtons();
65+ }
66+
67+ getFlags() {
68+ return getConfig().get("flags") as string;
2069 }
2170
22- updateFlagsFromConfig() {
23- output.log("Updating flags");
71+ toggleFlag(flag: Flag) {
72+ output.log(`Toggling flag ${flag.char}`);
73+ flag.state = flag.state === "on" ? "off" : "on";
74+ this.decorateFlag(flag);
2475 }
2576
26- updateFlagsFromUI() {
27- output.log("Updating flags from UI");
77+ decorateFlag(flag: Flag) {
78+ if (flag.button && flag.state) {
79+ flag.button.text = `${FLAG_ICONS[flag.state]} ${flag.char.toUpperCase()}`;
80+ flag.button.color = FLAG_COLORS[flag.state];
81+ }
2882 }
2983
30- createButton(flag: string) {
84+ createButton(flag: Flag) {
3185 output.log(`Creating button for ${flag}`);
86+ flag.button = vscode.window.createStatusBarItem(
87+ vscode.StatusBarAlignment.Left
88+ );
89+ this.decorateFlag(flag);
90+ flag.button.command = `regex.toggleFlag${flag.char.toUpperCase()}`;
91+ let disposable = vscode.commands.registerCommand(
92+ `regex.toggleFlag${flag.char.toUpperCase()}`,
93+ () => {
94+ this.toggleFlag(flag);
95+ }
96+ );
97+ flag.button.show();
98+ this.context?.subscriptions.push(flag.button);
99+ this.context?.subscriptions.push(disposable);
32100 }
33101
34- createButtons(context: vscode.ExtensionContext) {
102+ createButtons() {
35103 output.log("Creating buttons");
104+ for (const flag of FLAG_CHARS) {
105+ this.createButton(flag);
106+ }
36107 }
37108
38109 disposeButtons() {
+10-0src/utils.ts
@@ -0,0 +1,10 @@
1+import * as vscode from "vscode";
2+
3+export function editorsContainRegexFile() {
4+ const editors = vscode.window.visibleTextEditors;
5+ return editors.some(
6+ (editor) =>
7+ editor.document.languageId === "regex" &&
8+ editor.document.uri.scheme === "file"
9+ );
10+}