Skip to content

Commit b8797aa

Browse files
committed
Update to version 0.2.1
1. changed to new plugin icon 2. fixed an error in the regex pattern 3. showOrcaOutline and replaceKeywords are changed to async functions to accelerate the processing speed 4. the parseOrcaFile function is optimized for handing very big orca output files (<50MB). The buffer structure is optimized. The progress of parsing will be showed as a message in VS Code 5. additional error message is added.
1 parent d7c1535 commit b8797aa

File tree

5 files changed

+128
-86
lines changed

5 files changed

+128
-86
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
2323
## [0.2.0] - 2023-10-15
2424

2525
- This version removed the previous `generate_patterns.py` script and the `headings.md` file. The list of regular expressions in `patterns.json` file is now more unversal and the matched text is displayed in the `ORCA FILE OUTLINE` view. Most of the keywords in the ORCA output file are in full capital letters, which is not very user friendly. The matched text is now converted to title case before being displayed in the `ORCA FILE OUTLINE` view. There is a list of keywords in the `keywords.json` file, which will be used to replace some of the converted matched text to its correct form. The list of keywords will be updated in future small releases.
26+
27+
## [0.2.1] - 2023-10-16
28+
29+
- changed to new plugin icon
30+
- fixed an error in the regex pattern
31+
- showOrcaOutline and replaceKeywords are changed to async functions to accelerate the processing speed
32+
- the parseOrcaFile function is optimized for handing very big orca output files (<50MB). The buffer structure is optimized. The progress of parsing will be showed as a message in VS Code
33+
- additional error message is added
34+

README.md

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,26 @@ N/A
1212

1313
## Extension Settings
1414

15-
The current version (0.2.0) of this extension does not have any settings.
15+
The current version (0.2.1) of this extension does not have any settings.
1616

17-
## Known Issues
17+
## Issues and Important Notes
1818

19-
1. The TOC view will not automatically update when you save changes to the ORCA output file. You will need to manually run the command `Refresh Orca Outline` from the command palette. This will be fixed in a future release.
19+
- Due to the memory limit of VS Code for large files, the extension will not work properly for very large ORCA output files (>50MB) because VS code will disable the `activeEditor`. To parse very large ORCA output files and generate the TOC view, the extension will need to be run in a separate process. This will be implemented in a future release. Currently, the extension will work for ORCA output files that are less than 50MB in size. If you have very large ORCA output files, please consider splitting them into smaller chunks or remove the parts that are not needed (for example full print of the MOs).
2020

21-
## Release Notes
22-
23-
Users appreciate release notes as you update your extension.
24-
25-
### 0.0.1
26-
27-
Initial release of orcatoc. This is a very early release and is still under development.
28-
29-
---
30-
31-
### 0.0.2
21+
- If you don's see the `ORCA FILE OUTLINE` in the sidebar of `EXPLORER`, please make sure that the `OPEN EDITORS` drop down menu is expanded. This is a known issue and will be fixed in a future release.
3222

33-
Added support for automatically showing TOC view when opening an ORCA output file.
34-
35-
`headings.md` file added to the extension. This file contains a list of regular expressions that are used to parse the ORCA output file. The list of regular expressions will be updated in future releases.
36-
37-
`generate_patterns.py` script added to the extension. This script is used to parse the `headings.md` file and generate the `patterns.json` file. The `patterns.json` file is used by the extension to parse the ORCA output file.
38-
39-
---
40-
41-
### 0.1.0
23+
## Release Notes
4224

43-
Update of `patterns.json` file and `headings.md` file. Additional regular expressions added to the list used to parse the ORCA output file. Most frequently used keywords in the ORCA output file are now parsed. The list of regular expressions will be updated in future releases.
25+
For detailed release notes, please see [CHANGELOG.md](CHANGELOG.md).
4426

45-
### 0.2.0
27+
### 0.2.1
4628

47-
This version removed the previous `generate_patterns.py` script and the `headings.md` file. The list of regular expressions in `patterns.json` file is now more unversal and the matched text is displayed in the `ORCA FILE OUTLINE` view. Most of the keywords in the ORCA output file are in full capital letters, which is not very user friendly. The matched text is now converted to title case before being displayed in the `ORCA FILE OUTLINE` view. There is a list of keywords in the `keywords.json` file, which will be used to replace some of the converted matched text to its correct form. The list of keywords will be updated in future small releases.
29+
Bug fixes and optimizations.
4830

4931
## TODO
5032

5133
- [x] Automatically show TOC view when opening an ORCA output file
34+
- [X] Support for large ORCA output files (<50MB).
5235
- [ ] Automatically update TOC view when saving changes to an ORCA output file (additional command to manually refresh TOC view)
5336
- [ ] Add support for enabling/disabling TOC view for specific file types
5437
- [ ] Add support for controlling the showing level of TOC entries

extension.js

Lines changed: 105 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class OrcaOutlineProvider {
5050
});
5151
} else {
5252
// If there's no element, return the top-level matches
53+
console.log(typeof this._matches, this._matches);
5354
return this._matches.map(match => {
5455
return {
5556
label: `${match.title} (Line ${match.line + 1})`,
@@ -82,28 +83,48 @@ class OrcaOutlineProvider {
8283

8384
let orcaOutlineProvider = new OrcaOutlineProvider([]);
8485

85-
function showOrcaOutline() {
86+
async function showOrcaOutline() { // Make the function asynchronous
8687
const activeEditor = vscode.window.activeTextEditor;
8788
if (!activeEditor) {
88-
vscode.window.showErrorMessage("No active document found. Please open a file first.");
89+
// Check if there's a file with .out extension in the workspace
90+
if (vscode.workspace.textDocuments.some(doc => doc.uri.scheme === 'file' && doc.fileName.endsWith('.out'))) {
91+
vscode.window.showErrorMessage("The file might be too large to open! VS Code is unable to operate with files larger than 50MB in active editor. Please consider breaking the file into smaller chunks.");
92+
} else {
93+
// If there's no file with .out extension in the workspace, show an error message, and Open File button to open the Open File dialog
94+
vscode.window.showErrorMessage("No active document found. Please open a file first.", "Open File").then((value) => {
95+
if (value === "Open File") {
96+
vscode.commands.executeCommand("workbench.action.files.openFile");
97+
}
98+
});
99+
}
89100
return;
90101
}
91102

92103
const document = activeEditor.document;
93-
if (document.languageId !== 'orcaOut' || !document.fileName.endsWith('.out')) {
94-
// Check if the active document is an ORCA file (.out)
95-
vscode.window.showErrorMessage("The active document is not an ORCA file.");
96-
return;
97-
}
104+
try {
105+
if (document.languageId !== 'orcaOut' || !document.fileName.endsWith('.out')) {
106+
// Check if the active document is an ORCA file (.out)
107+
vscode.window.showErrorMessage("The active document is not an ORCA file.");
108+
return;
109+
}
98110

99-
const matches = parseOrcaFile(document, document.uri.fsPath); // Pass the file path to the function
100-
orcaOutlineProvider.update(matches, document.uri.fsPath); // Update the global instance of the provider
111+
// Maybe handle non-UTF-8 characters here, normalize or clean up the document text
101112

102-
//console.log(matches); // This will print matches in the debug console
103-
//orcaOutlineProvider.update(matches, document.uri.fsPath);
113+
const matches = await parseOrcaFile(document, document.uri.fsPath); // Wait for the promise to resolve
104114

105-
}
115+
// Apply keyword replacements to the matches
116+
await replaceKeywords(matches); // Wait for the promise to resolve
117+
118+
orcaOutlineProvider.update(matches, document.uri.fsPath); // Update the global instance of the provider
106119

120+
// The keyword replacement seems to be commented out, but if you decide to use it again, make sure to await it as well
121+
// await replaceKeywords(matches);
122+
// orcaOutlineProvider.update(matches, document.uri.fsPath);
123+
124+
} catch (error) {
125+
vscode.window.showErrorMessage(`Error processing the file: ${error.message}`);
126+
}
127+
}
107128

108129
function activate(context) {
109130
context.subscriptions.push(vscode.commands.registerCommand('extension.showOrcaOutline', showOrcaOutline));
@@ -131,62 +152,91 @@ function toTitleCase(str) {
131152
});
132153
}
133154

155+
134156
function parseOrcaFile(document, filePath) {
135157
let matches = [];
136-
let stack = [{ children: matches }]; // A default root node for ease of algorithm
137-
138-
// First, get all the matches in order.
139-
let allMatches = [];
140-
orcaPatterns.forEach(pattern => {
141-
let match;
142-
while (match = pattern.regex.exec(document.getText())) {
143-
const line = document.positionAt(match.index).line;
144-
let title = match[1] || pattern.title;
145-
title = toTitleCase(title.trim());
146-
for (let keyword in keywordReplacements) {
147-
if (title.includes(keyword)) {
148-
title = title.replace(keyword, keywordReplacements[keyword]);
158+
let stack = [{ children: matches }];
159+
160+
return vscode.window.withProgress({
161+
location: vscode.ProgressLocation.Notification,
162+
title: "Parsing ORCA File",
163+
cancellable: true
164+
}, (progress, token) => {
165+
return new Promise((resolve, reject) => {
166+
let buffer = document.getText();
167+
168+
let allMatches = [];
169+
let totalPatterns = orcaPatterns.length;
170+
orcaPatterns.forEach((pattern, index) => {
171+
let match;
172+
while (match = pattern.regex.exec(buffer)) {
173+
const line = document.positionAt(match.index).line;
174+
let title = match[1] || pattern.title;
175+
title = toTitleCase(title.trim());
176+
177+
// Replace keywords in the title
178+
//for (let keyword in keywordReplacements) {
179+
// if (title.includes(keyword)) {
180+
// title = title.replace(keyword, keywordReplacements[keyword]);
181+
// }
182+
// }
183+
184+
allMatches.push({
185+
line: line,
186+
title: title,
187+
level: pattern.level,
188+
children: [],
189+
command: {
190+
command: 'vscode.open',
191+
arguments: [vscode.Uri.file(filePath), {
192+
selection: new vscode.Range(line, 0, line, 0)
193+
}],
194+
title: 'Open File'
195+
},
196+
tooltip: `${pattern.title} (Line ${line + 1})`
197+
});
149198
}
150-
}
151-
allMatches.push({
152-
line: line,
153-
title: title,
154-
level: pattern.level,
155-
children: [],
156-
command: {
157-
command: 'vscode.open',
158-
arguments: [vscode.Uri.file(filePath), {
159-
selection: new vscode.Range(line, 0, line, 0)
160-
}],
161-
title: 'Open File'
162-
},
163-
tooltip: `${pattern.title} (Line ${line + 1})`
164-
});
165-
}
166-
});
167199

168-
// Sort allMatches by line number
169-
allMatches.sort((a, b) => a.line - b.line);
200+
progress.report({ message: `Processing Pattern ${index + 1} of ${totalPatterns}`, increment: (100 / totalPatterns) });
201+
202+
if (token.isCancellationRequested) {
203+
reject("Operation was cancelled by the user.");
204+
}
205+
});
170206

171-
// Populate the tree based on sorted matches
172-
allMatches.forEach(matchItem => {
173-
// Pop items from the stack until we reach the parent of the current matchItem
174-
while (stack.length > matchItem.level) {
175-
stack.pop();
176-
}
207+
allMatches.sort((a, b) => a.line - b.line);
177208

178-
// Add the current matchItem as a child to the top item on the stack
179-
stack[stack.length - 1].children.push(matchItem);
209+
allMatches.forEach(matchItem => {
210+
while (stack.length > matchItem.level) {
211+
stack.pop();
212+
}
180213

181-
// Push the current matchItem onto the stack to become the new potential parent
182-
stack.push(matchItem);
214+
stack[stack.length - 1].children.push(matchItem);
215+
stack.push(matchItem);
216+
});
183217

218+
resolve(matches);
219+
});
184220
});
221+
}
185222

186223

187-
return matches;
224+
225+
226+
async function replaceKeywords(matches) {
227+
for (let match of matches) {
228+
for (let keyword in keywordReplacements) {
229+
if (match.title.includes(keyword)) {
230+
match.title = match.title.replace(keyword, keywordReplacements[keyword]);
231+
}
232+
}
233+
if (match.children) {
234+
await replaceKeywords(match.children); // Recursive replacement for child nodes
235+
}
236+
}
188237
}
189238

239+
190240
module.exports = {
191241
activate,
192242
deactivate

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "orcatoc",
33
"displayName": "orca_toc",
44
"description": "Provides an outline for ORCA files in the VS Code sidebar.",
5-
"version": "0.2.0",
5+
"version": "0.2.1",
66
"engines": {
77
"vscode": "^1.82.0"
88
},
@@ -25,8 +25,8 @@
2525
"explorer": [
2626
{
2727
"id": "orcaFileOutline",
28-
"name": "ORCA File Outline",
29-
"when": "resourceExtname == .out"
28+
"name": "ORCA FILE OUTLINE",
29+
"when": "resourceExtname =~ /.out$/"
3030
}
3131
]
3232
},
@@ -59,5 +59,5 @@
5959
},
6060
"license": "GPL-3.0",
6161
"publisher": "liqunKang",
62-
"icon": "images/orca_TOC.png"
62+
"icon": "images/orca_TOC_new.png"
6363
}

patterns.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"level": 2
99
},
1010
{
11-
"regex": "^\\-+\\n\\s+([^\\n\\s]+)\\n\\-+",
11+
"regex": "^\\-+\\n\\s+([^\\n]+)\\n\\-+",
1212
"level": 3
1313
},
1414
{

0 commit comments

Comments
 (0)