ANTLR Typescript editor
npm install @making-sense/antlr-editor



A robust TypeScript editor component built on Monaco Editor with ANTLR4 integration. Features enhanced error handling, automatic resource cleanup, and stable resizing capabilities.
- ๐ง Robust Error Handling: Automatically handles Monaco disposal errors without user intervention
- ๐ Stable Resizing: Editor maintains cursor position and selection during layout changes
- ๐งน Automatic Cleanup: Prevents memory leaks with intelligent resource management
- โก Performance Optimized: Minimal remounts and efficient provider management
- ๐จ Monaco Integration: Full Monaco Editor features with syntax highlighting and autocomplete
- ๐ ANTLR4 Support: Built-in support for ANTLR4 grammars and tools
``bash`
yarn add @making-sense/antlr-editor
`bash`
yarn add @making-sense/antlr-editor @making-sense/vtl-2-1-antlr-tools-ts @making-sense/vtl-2-1-monaco-tools-ts
`typescript
import { AntlrEditor } from "@making-sense/antlr-editor";
import * as VTLTools from "@making-sense/vtl-2-1-antlr-tools-ts";
import { getSuggestionsFromRange, monarchDefinition } from "@making-sense/vtl-2-1-monaco-tools-ts";
const customTools = { ...VTLTools, getSuggestionsFromRange, monarchDefinition };
const MyEditor = () => {
const [script, setScript] = useState("");
return (
setScript={setScript}
tools={customTools}
height="400px"
width="100%"
theme="vs-dark"
shortcuts={{
"ctrl+s, meta+s": () => console.log("Save"),
"ctrl+enter, meta+enter": () => console.log("Run")
}}
displayFooter={true}
/>
);
};
`
`typescript
import { AntlrEditor, cleanupProviders } from "@making-sense/antlr-editor";
const AdvancedEditor = () => {
const [script, setScript] = useState("");
// Manual cleanup for advanced scenarios
useEffect(() => {
return () => {
cleanupProviders();
};
}, []);
return (
setScript={setScript}
tools={customTools}
height="100%"
width="100%"
theme="vs-dark"
options={{
lineNumbers: "on",
minimap: { enabled: true },
readOnly: false
}}
shortcuts={{
"ctrl+s, meta+s": handleSave,
"ctrl+enter, meta+enter": handleRun
}}
onListErrors={(errors) => {
console.log("Validation errors:", errors);
}}
displayFooter={true}
/>
);
};
`
| Prop | Type | Default | Description |
| -------------------- | ---------------------------------------------------- | ----------- | ------------------------------------------ |
| script | string | '' | The script content to display |setScript
| | (value: string) => void | - | Callback for script changes |tools
| | Tools | - | Required - ANTLR4 tools configuration |height
| | string | '50vh' | Editor height (CSS value) |width
| | string | '100%' | Editor width (CSS value) |theme
| | string | 'vs-dark' | Monaco theme (vs-dark, vs-light, etc.) |options
| | Monaco.editor.IStandaloneEditorConstructionOptions | {} | Monaco editor options |shortcuts
| | Record | - | Keyboard shortcuts |FooterComponent
| | React.FC<{ cursor: CursorType }> | - | Custom footer component |displayFooter
| | boolean | true | Whether to show footer |onListErrors
| | (errors: Error[]) => void | - | Error callback |variables
| | Variables | {} | Variables for autocomplete |variablesInputURLs
| | string[] | [] | URLs to fetch variables from |customFetcher
| | (url: string) => Promise | fetch | Custom fetch function |
The tools prop requires an ANTLR4 configuration object:
`typescript`
interface Tools {
id: string; // Language identifier
initialRule: string; // Starting rule name
grammar: string; // Grammar definition
Lexer: Antlr4Lexer; // ANTLR4 Lexer class
Parser: Antlr4Parser; // ANTLR4 Parser class
monarchDefinition?: any; // Monaco syntax highlighting
getSuggestionsFromRange?: any; // Custom suggestions
}
`typescript`
const variables = {
"var1": { "type": "STRING", "role": "IDENTIFIER" },
"var2": { "type": "INTEGER", "role": "MEASURE" },
"var3": { "type": "NUMBER", "role": "DIMENSION" }
};
`typescript`
const shortcuts = {
"ctrl+s, meta+s": () => handleSave(),
"ctrl+enter, meta+enter": () => handleRun(),
"ctrl+z, meta+z": () => handleUndo(),
"ctrl+y, meta+y": () => handleRedo()
};
Always ensure the editor container has a defined height:
`typescript
// โ
Good
// โ Avoid
$3
The editor handles Monaco disposal errors automatically, but you can add custom error handling:
`typescript
const handleErrors = (errors) => {
// Handle validation errors
setValidationErrors(errors);
}; onListErrors={handleErrors}
// ... other props
/>
`$3
For large scripts or frequent updates, consider debouncing:
`typescript
const [script, setScript] = useState("");
const [debouncedScript, setDebouncedScript] = useState("");useEffect(() => {
const timer = setTimeout(() => {
setDebouncedScript(script);
}, 300);
return () => clearTimeout(timer);
}, [script]);
script={debouncedScript}
setScript={setScript}
// ... other props
/>
`$3
Support both light and dark themes:
`typescript
const { isDarkMode } = useTheme(); theme={isDarkMode ? "vs-dark" : "vs-light"}
// ... other props
/>
`$3
`typescript
const customFetcher = (url) => {
return fetch(url, {
headers: {
'Authorization': Bearer ${token},
'Content-Type': 'application/json'
}
});
}; customFetcher={customFetcher}
variablesInputURLs={["https://api.example.com/variables"]}
// ... other props
/>
`๐ง Development
$3
`bash
yarn storybook
`$3
`bash
Clone and setup
git clone https://github.com/Making-Sense-Info/ANTLR-Editor
cd ANTLR-Editor
yarnStart test app in watch mode
yarn start-test-appLink to external project
yarn link-in-app test-app
`$3
Open
test-enhanced-editor.html in your browser to test:- Editor resizing without remounting
- Layout changes and stability
- Error handling and recovery
- Cursor position preservation
๐ Troubleshooting
$3
1. "InstantiationService has been disposed" errors
- The editor handles these automatically
- If you still see them, ensure you're using the latest version
2. Editor not resizing properly
- Make sure the container has a defined height
- Check that the
height prop is set correctly3. Memory leaks
- The editor includes automatic cleanup
- For manual cleanup, use
cleanupProviders()4. Cursor position lost during resize
- This is now handled automatically
- The editor maintains state during layout changes
$3
Enable debug logging:
`javascript
// In browser console
localStorage.setItem("debug", "antlr-editor:*");
``- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
Same as the main ANTLR Editor package.
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
Check out the Storybook stories for comprehensive examples:
- Basic editor setup
- Resizing and layout tests
- Error handling scenarios
- Custom theming and styling