Getting Started With Ace Editor
Here is a quick, handy guide for getting started with Ace editor.
Join the DZone community and get the full member experience.
Join For FreeGetting Started With Ace Editor
Ace is a high-performance code editor for the web. Ace is written in JavaScript and you can embed it into your web pages should you need code editing capabilities. It cannot match the performance of native text editors like Sublime but it’s fast enough for occasional code editing. We used it as a JavaScript editor in Xenarius, our mobile app builder, and now I’m going to explain how you can use Ace in your own project.
Start by cloning the ace repository. You will need 4 files from it.
- ace.js – it’s the main file of the Ace library,
- ext-language_tools.js – provides the text autocomplete feature,
- theme-chrome.js – defines editor styles,
- mode-javascript.js and worker-javascript.js –contain JavaScript validator and highlighter.
Add these files to your project and link the *ace.js* file in your HTML page. Other files will be loaded automatically.
In case you’re using Browserify or Webpack, Thorsten Lorenz made a Browserify-compatible version of Ace. You can find it on GitHub: https://github.com/thlorenz/brace
Once the files are loaded, create a <div>HTML element and initialize Ace in it.
var aceEditor = window.ace.edit(divElement);
Now, you can use the aceEditor
variable to access and configure Ace editor.
Configuring Ace
When you configure Ace, keep in mind that some Ace options should be set for a specific Ace instance, while others – for all instances at once.
aceEditor.setOptions({
enableBasicAutocompletion: true, // the editor completes the statement when you hit Ctrl + Space
enableLiveAutocompletion: true, // the editor completes the statement while you are typing
showPrintMargin: false, // hides the vertical limiting strip
maxLines: Infinity,
fontSize: "100%" // ensures that the editor fits in the environment
});
// defines the style of the editor
aceEditor.setTheme("ace/theme/chrome");
// hides line numbers (widens the area occupied by error and warning messages)
aceEditor.renderer.setOption("showLineNumbers", false);
// ensures proper autocomplete, validation and highlighting of JavaScript code
aceEditor.getSession().setMode("ace/mode/javascript_expression");
Shared Ace for the Inline Mode
In the inline mode, the Ace editor gets activated each time you click a text. And it is always the same instance of the editor as it was the first time. Furthermore, all inline elements will use the same instance.
Initialized in the beginning, this instance resides in a special parking place waiting for a user to call the editor. When it happens, the instance gets relocated to the appropriate place in the DOM, and gets back after the user closes the editor. A shared instance can be accessed using a closure reminiscent of the singleton design pattern.
var getSharedAce = function() {
var sharedAce;
return () => {
if(!sharedAce) {
var $sharedAceHolder = $("<div id='shared-ace-holder'>").hide().appendTo(document.body);
sharedAce = createAce($sharedAceHolder);
}
return sharedAce;
};
} ();
KnockoutJS Integration Specifics
If you’re using KnockoutJS in your app, you may face a caveat. Ace is bound to the model with a custom binding handler. Its update
method relocates the instance to the parking place and back, and subscribes/unsubscribes from the text change event. Note that Ace subscribes to this event on its own, which means that calling ace.off("change")
without specifying the handler leads to rendering issues.
Custom Autocomplete Rules
In our product, we use Ace when editing inline expressions, not actual JavaScript files. Unfortunately, standard error-checking, highlight and autocomplete libraries don’t fit that purpose well. For example, Ace would show an error if there is no semicolon at the end of the line, while our expressions are perfectly valid without it. We had to dig into error-checker and highlighter to solve these problems.
We wanted the autocompleter to show expression context variables. To this end, we needed to populate its dictionary with custom keywords. If you need to use custom autocomplete rules in Ace like we do, add a custom completer to the language_tools ace extension (found in ace/ext/language_tools.js). But there is a limitation: all Ace instances use a single completer. To work around this limitation, we cache rule sets and choose the appropriate one in the completer using a closure.
var ace = window["ace"],
langTools = ace.require("ace/ext/language_tools"),
contextCompleter = {
getCompletions(editor, session, pos, prefix, callback) {
var dataHolder = AppPlayer.findInArray(dataHolders, holder => holder.editor === editor);
callback(null, dataHolder && dataHolder.data);
}
};
langTools.addCompleter(contextCompleter);
Thus, you can use different autocomplete rule sets inside different operations while having only one Ace instance and a single completer. The screenshot below shows autocomplete popup with our custom variables we added into it.
Autocomplete and Syntax Highlighting in JavaScript Mode
You can find the dictionary of highlighted keywords in the mode-javascript.js file in the keywordMapper
variable. Autocomplete uses the same dictionary as well.
We started by removing unsupported keywords from the list. Also, we introduced a special mode for JavaScript statements. This mode disables several rules, like the requirement that every expression should end with a semicolon. To implement this mode, we created new "-mode" and "-worker" files, based on the existing "javascript-mode.js" and "worker-javascript.js" files. We’ve just removed checks that aren’t necessary for our product. If you’re making your own Ace mode, don’t forget to change the mode name at the end of the mode file:
ace.define("ace/mode/your-name-here", ...
The screenshot below shows that Ace no longer shows a warning about a missing semicolon.
Not too complex, is it?
Opinions expressed by DZone contributors are their own.
Comments