@making-sense/antlr-editor
v2.5.0
Published
ANTLR Typescript editor
Readme
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.
✨ Key Features
- 🔧 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
📦 Installation
yarn add @making-sense/antlr-editorFor VTL 2.1 Support
yarn add @making-sense/antlr-editor @making-sense/vtl-2-1-antlr-tools-ts @making-sense/vtl-2-1-monaco-tools-ts🚀 Quick Start
Basic Usage
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 (
<AntlrEditor
script={script}
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}
/>
);
};Advanced Usage with Error Handling
import { AntlrEditor, cleanupProviders } from "@making-sense/antlr-editor";
const AdvancedEditor = () => {
const [script, setScript] = useState("");
// Manual cleanup for advanced scenarios
useEffect(() => {
return () => {
cleanupProviders();
};
}, []);
return (
<AntlrEditor
script={script}
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}
/>
);
};📋 API Reference
AntlrEditor Props
| 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<string, () => void> | - | 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<any> | fetch | Custom fetch function |
Tools Configuration
The tools prop requires an ANTLR4 configuration object:
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
}Variables for Autocomplete
const variables = {
"var1": { "type": "STRING", "role": "IDENTIFIER" },
"var2": { "type": "INTEGER", "role": "MEASURE" },
"var3": { "type": "NUMBER", "role": "DIMENSION" }
};Keyboard Shortcuts
const shortcuts = {
"ctrl+s, meta+s": () => handleSave(),
"ctrl+enter, meta+enter": () => handleRun(),
"ctrl+z, meta+z": () => handleUndo(),
"ctrl+y, meta+y": () => handleRedo()
};🛠️ Best Practices
1. Container Sizing
Always ensure the editor container has a defined height:
// ✅ Good
<div style={{ height: "400px" }}>
<AntlrEditor height="100%" />
</div>
// ❌ Avoid
<div>
<AntlrEditor height="auto" />
</div>2. Error Handling
The editor handles Monaco disposal errors automatically, but you can add custom error handling:
const handleErrors = (errors) => {
// Handle validation errors
setValidationErrors(errors);
};
<AntlrEditor
onListErrors={handleErrors}
// ... other props
/>3. Performance Optimization
For large scripts or frequent updates, consider debouncing:
const [script, setScript] = useState("");
const [debouncedScript, setDebouncedScript] = useState("");
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedScript(script);
}, 300);
return () => clearTimeout(timer);
}, [script]);
<AntlrEditor
script={debouncedScript}
setScript={setScript}
// ... other props
/>4. Theme Management
Support both light and dark themes:
const { isDarkMode } = useTheme();
<AntlrEditor
theme={isDarkMode ? "vs-dark" : "vs-light"}
// ... other props
/>5. Custom Fetch for Authentication
const customFetcher = (url) => {
return fetch(url, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
};
<AntlrEditor
customFetcher={customFetcher}
variablesInputURLs={["https://api.example.com/variables"]}
// ... other props
/>🔧 Development
Storybook
yarn storybookTest App
# Clone and setup
git clone https://github.com/Making-Sense-Info/ANTLR-Editor
cd ANTLR-Editor
yarn
# Start test app in watch mode
yarn start-test-app
# Link to external project
yarn link-in-app test-appTesting
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
Common Issues
"InstantiationService has been disposed" errors
- The editor handles these automatically
- If you still see them, ensure you're using the latest version
Editor not resizing properly
- Make sure the container has a defined height
- Check that the
heightprop is set correctly
Memory leaks
- The editor includes automatic cleanup
- For manual cleanup, use
cleanupProviders()
Cursor position lost during resize
- This is now handled automatically
- The editor maintains state during layout changes
Debug Mode
Enable debug logging:
// In browser console
localStorage.setItem("debug", "antlr-editor:*");🌐 Browser Support
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
📄 License
Same as the main ANTLR Editor package.
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
📚 Examples
Check out the Storybook stories for comprehensive examples:
- Basic editor setup
- Resizing and layout tests
- Error handling scenarios
- Custom theming and styling
