Skip to content

Commit 8032e6b

Browse files
Merge pull request #154 from pedrohenrique-ql/feature/141-support-many-rgx-files
feat: support many .rgx files (#141)
2 parents 06deec0 + a0c9ca1 commit 8032e6b

File tree

16 files changed

+274
-130
lines changed

16 files changed

+274
-130
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## [0.7.0] - In Progress
44

5+
- Added support to create and test multiple regex test files.
56
- Created a new language grammar for `.rgx` files, allowing the use of syntax highlighting.
67

78
## [v0.6.1] - 20/05/2025

src/services/regex-match/FileParser.ts renamed to src/controllers/regex-test/FileParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import RegexMatchFormatError from '@/exceptions/RegexMatchFormatError';
12
import { CodeRegex } from '@/providers/code-lenses/TestRegexCodeLensProvider';
23

3-
import RegexMatchFormatError from '../../exceptions/RegexMatchFormatError';
44
import RegexTest from './RegexTest';
55

66
export const TEST_AREA_DELIMITER = '---';
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import {
2+
commands,
3+
Disposable,
4+
ExtensionContext,
5+
languages,
6+
TextDocument,
7+
TextDocumentChangeEvent,
8+
TextEditor,
9+
Uri,
10+
window,
11+
workspace,
12+
} from 'vscode';
13+
14+
import RegexTestFile from '@/controllers/regex-test/RegexTestFile';
15+
import { REGEX_MATCH_LANGUAGE_ID } from '@/extension';
16+
import ApplyRegexCodeLensProvider from '@/providers/code-lenses/ApplyRegexCodeLensProvider';
17+
import { CodeRegex } from '@/providers/code-lenses/TestRegexCodeLensProvider';
18+
import { disposeAll } from '@/utils/dispose';
19+
20+
import DiagnosticProvider from '../../providers/DiagnosticProvider';
21+
import FileCreator from './FileCreator';
22+
23+
export const REGEX_TEST_FILE_PATH = '/regex-test-file/RegexMatch.rgx';
24+
25+
class RegexTestController implements Disposable {
26+
private readonly rgxFiles = new Map<string, RegexTestFile>();
27+
private readonly defaultRegexTestFileUri: Uri;
28+
29+
private readonly diagnosticProvider: DiagnosticProvider;
30+
private applyRegexCodeLensProvider: ApplyRegexCodeLensProvider;
31+
32+
private disposables: Disposable[] = [];
33+
private codeRegex?: CodeRegex;
34+
35+
constructor(extensionPath: ExtensionContext['extensionPath'], diagnosticProvider: DiagnosticProvider) {
36+
this.diagnosticProvider = diagnosticProvider;
37+
this.defaultRegexTestFileUri = Uri.file(`${extensionPath}${REGEX_TEST_FILE_PATH}`);
38+
39+
this.applyRegexCodeLensProvider = new ApplyRegexCodeLensProvider();
40+
this.disposables = this.registerDisposables();
41+
42+
this.checkOpenRgxFiles();
43+
}
44+
45+
registerDisposables(): Disposable[] {
46+
const closeTextDocumentDisposable = workspace.onDidCloseTextDocument((document) =>
47+
this.onCloseTextDocument(document),
48+
);
49+
50+
const changeVisibleEditorsDisposable = window.onDidChangeVisibleTextEditors((event) =>
51+
this.onChangeVisibleTextEditors(event),
52+
);
53+
54+
const onChangeTextDocumentDisposable = workspace.onDidChangeTextDocument((event) =>
55+
this.onChangeTextDocument(event),
56+
);
57+
58+
const openRegexTextCommand = commands.registerCommand('regex-match.openRegexMatchWindow', (codeRegex?: CodeRegex) =>
59+
this.openDefaultRegexTestWindow(codeRegex),
60+
);
61+
62+
const applyRegexDisposable = languages.registerCodeLensProvider(
63+
{ pattern: this.defaultRegexTestFileUri.path, scheme: 'file' },
64+
this.applyRegexCodeLensProvider,
65+
);
66+
67+
return [
68+
closeTextDocumentDisposable,
69+
changeVisibleEditorsDisposable,
70+
onChangeTextDocumentDisposable,
71+
openRegexTextCommand,
72+
applyRegexDisposable,
73+
];
74+
}
75+
76+
addRegexTestFile(documentUri: Uri) {
77+
const isDefaultTestFile = this.isDefaultRegexTestFile(documentUri.toString());
78+
79+
const regexTestFile = new RegexTestFile(documentUri, this.diagnosticProvider, {
80+
isDefaultTestFile,
81+
applyRegexCodeLensProvider: isDefaultTestFile ? this.applyRegexCodeLensProvider : undefined,
82+
isOpeningWithCodeRegex: !!this.codeRegex,
83+
});
84+
85+
this.rgxFiles.set(documentUri.toString(), regexTestFile);
86+
}
87+
88+
onCloseTextDocument(document: TextDocument) {
89+
const documentUri = document.uri.toString();
90+
91+
if (this.rgxFiles.has(documentUri)) {
92+
const regexTestFile = this.rgxFiles.get(documentUri);
93+
regexTestFile?.dispose();
94+
this.rgxFiles.delete(documentUri);
95+
}
96+
}
97+
98+
onChangeVisibleTextEditors(textEditors: readonly TextEditor[]) {
99+
const visibleRgxEditors = textEditors.filter((editor) => editor.document.languageId === REGEX_MATCH_LANGUAGE_ID);
100+
101+
for (const editor of visibleRgxEditors) {
102+
const documentUriString = editor.document.uri.toString();
103+
104+
if (!this.rgxFiles.has(documentUriString)) {
105+
this.addRegexTestFile(editor.document.uri);
106+
}
107+
}
108+
109+
for (const [uriString, regexTestFile] of this.rgxFiles) {
110+
const regexMatchEditor = textEditors.find((editor) => editor.document.uri.toString() === uriString);
111+
112+
if (!regexMatchEditor) {
113+
regexTestFile.dispose();
114+
this.rgxFiles.delete(uriString);
115+
}
116+
}
117+
}
118+
119+
onChangeTextDocument(event: TextDocumentChangeEvent) {
120+
const activeEditor = window.activeTextEditor;
121+
const eventDocument = event.document;
122+
123+
const regexTestFile = this.rgxFiles.get(eventDocument.uri.toString());
124+
125+
const isToUpdateFile = regexTestFile && event.contentChanges.length > 0 && eventDocument === activeEditor?.document;
126+
127+
if (isToUpdateFile) {
128+
regexTestFile.handleTextDocumentChange(activeEditor, this.codeRegex);
129+
this.codeRegex = undefined;
130+
}
131+
}
132+
133+
private checkOpenRgxFiles() {
134+
const regexMatchEditor = window.visibleTextEditors.filter(
135+
(editor) => editor.document.languageId === REGEX_MATCH_LANGUAGE_ID,
136+
);
137+
138+
for (const editor of regexMatchEditor) {
139+
const documentUriString = editor.document.uri.toString();
140+
141+
if (!this.rgxFiles.has(documentUriString)) {
142+
this.addRegexTestFile(editor.document.uri);
143+
}
144+
}
145+
}
146+
147+
async openDefaultRegexTestWindow(codeRegex?: CodeRegex) {
148+
this.codeRegex = codeRegex;
149+
await FileCreator.openRegexTestFile(this.defaultRegexTestFileUri, codeRegex?.pattern);
150+
}
151+
152+
isDefaultRegexTestFile(documentUriString: string) {
153+
return this.defaultRegexTestFileUri.toString() === documentUriString;
154+
}
155+
156+
dispose() {
157+
disposeAll(this.disposables);
158+
disposeAll(Array.from(this.rgxFiles.values()));
159+
this.rgxFiles.clear();
160+
}
161+
}
162+
163+
export default RegexTestController;

0 commit comments

Comments
 (0)