aboutsummaryrefslogtreecommitdiff
path: root/plugin/src
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-14 02:53:33 +0000
committer_ov4 <ov4@ov4.org>2026-10-14 02:53:33 +0000
commit3ef7f8b778dce23af25965b379126b9dd95d1c27 (patch)
tree3e3700201b9a3a52bc0d78895d1e345e06fe0ead /plugin/src
parentd5851e995363e6f637a5f35cafe3ddaf8934705a (diff)
feat(plugin): indent try-catch blocks
Indent TRY and CATCH bodies, align CATCH and ENDTRY with their TRY, and trigger on-type formatting when either keyword is completed. Document the supported blocks and verify nesting, selection context and Enter indentation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'plugin/src')
-rw-r--r--plugin/src/extension.js4
-rw-r--r--plugin/src/indentation.js11
2 files changed, 8 insertions, 7 deletions
diff --git a/plugin/src/extension.js b/plugin/src/extension.js
index 70c8622..6bd1255 100644
--- a/plugin/src/extension.js
+++ b/plugin/src/extension.js
@@ -49,11 +49,11 @@ function activate(context) {
}),
vscode.languages.registerOnTypeFormattingEditProvider(languageId, {
provideOnTypeFormattingEdits(document, position, char) {
- if (char !== '\n' && !/^\s*(?:ELSE|ENDIF|ENDWHILE|UNTIL|NEXT|ENDFUNCTION|ENDPROCEDURE|ENDTYPE)\b/.test(
+ if (char !== '\n' && !/^\s*(?:ELSE|ENDIF|ENDWHILE|UNTIL|NEXT|ENDFUNCTION|ENDPROCEDURE|ENDTYPE|CATCH|ENDTRY)\b/.test(
codeOnly(document.lineAt(position.line).text))) return [];
return formatLines(document, position.line, position.line, char === '\n');
}
- }, '\n', 'E', 'F', 'L', 'T', 'N')
+ }, '\n', 'E', 'F', 'L', 'T', 'N', 'H', 'Y')
);
refreshBrackets();
}
diff --git a/plugin/src/indentation.js b/plugin/src/indentation.js
index c8af770..b7fca78 100644
--- a/plugin/src/indentation.js
+++ b/plugin/src/indentation.js
@@ -3,7 +3,7 @@
const { codeOnly } = require('./lexical');
const closers = {
ENDIF: 'IF', ENDWHILE: 'WHILE', UNTIL: 'REPEAT', NEXT: 'FOR',
- ENDFUNCTION: 'FUNCTION', ENDPROCEDURE: 'PROCEDURE', ENDTYPE: 'TYPE'
+ ENDFUNCTION: 'FUNCTION', ENDPROCEDURE: 'PROCEDURE', ENDTYPE: 'TYPE', ENDTRY: 'TRY'
};
function lineDepths(lines) {
@@ -12,13 +12,14 @@ function lineDepths(lines) {
return lines.map(line => {
const code = codeOnly(line).trim();
const keyword = /^([A-Za-z][A-Za-z0-9_]*)\b/.exec(code)?.[1];
- if (closers[keyword] || keyword === 'ELSE') {
- const kind = keyword === 'ELSE' ? 'IF' : closers[keyword];
+ const branch = keyword === 'ELSE' ? 'IF' : keyword === 'CATCH' ? 'TRY' : null;
+ if (closers[keyword] || branch) {
+ const kind = branch || closers[keyword];
const index = stack.findLastIndex(block => block.kind === kind);
if (index >= 0) {
stack.length = index;
const current = depth();
- if (keyword === 'ELSE') stack.push({ kind: 'IF', active: true });
+ if (branch) stack.push({ kind, active: true });
return current;
}
// Incomplete code should still format without negative indentation.
@@ -32,7 +33,7 @@ function lineDepths(lines) {
} else if (keyword === 'IF' || keyword === 'WHILE') {
stack.push({ kind: keyword, active: new RegExp(
keyword === 'IF' ? '\\bTHEN\\b' : '\\bDO\\b').test(code) });
- } else if (['FOR', 'REPEAT', 'FUNCTION', 'PROCEDURE'].includes(keyword)) {
+ } else if (['FOR', 'REPEAT', 'FUNCTION', 'PROCEDURE', 'TRY'].includes(keyword)) {
stack.push({ kind: keyword, active: true });
} else if (/^TYPE\s+[A-Za-z][A-Za-z0-9_]*$/.test(code)) {
stack.push({ kind: 'TYPE', active: true });