Enhance ACE Editor capabilities by integrating custom modes and themes specifically designed for Angular/TypeScript development

Overview:

In my Angular application, I have integrated the ACE editor () to allow users to write custom SQL statements. While there are existing modes and themes for SQL, I decided to create a customized mode and theme to suit my specific requirements.


Setup Process:

I followed a tutorial available at:

  • ng new ace-app (Angular 13.3.2)
  • npm install ace-builds (ACE-Builds 1.4.14)

component.ts

import * as ace from 'ace-builds';

...

public aceEditor: ace.Ace.Editor;

@ViewChild('editor') private editor!: ElementRef<HTMLElement>;

...

  ngAfterViewInit(): void {
    // I don't understand why we don't set the "basePath" to our installed package
    ace.config.set('basePath', 'https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f6979593db94839f9a9285b6c7d8c2d8c7c4">[email protected]</a>/src-noconflict');

    this.aceEditor = ace.edit(this.editor.nativeElement);

    if (this.aceEditor) {
      this.aceEditor.setOptions({
        mode: 'ace/mode/sql',
        theme: 'ace/theme/sqlserver',
      });
    }

component.html

<div #editor></div>

Outcome:

The ACE editor is functioning properly, but now I need to figure out how to incorporate a custom mode and theme.

https://i.sstatic.net/nnIVk.png


Challenges and Queries:

  • Is it necessary to set the basePath to an external URL when the package is already installed? (Answered in Edit 1)
  • Where should I integrate the custom mode.js and theme.js files?
  • How can I instruct ACE to utilize the custom mode.js and theme.js?

Edit 1:

I was able to remove the following line of code:

ace.config.set('basePath', 'https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="600103054d0215090c041320514e544e5152">[email protected]</a>/src-noconflict');

by directly importing the theme and mode with:

import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';

No other changes were required in the code.

Answer №1

While exploring various projects and problems, I discovered a effective method for implementing custom themes and modes for the ACE editor. It involves duplicating existing ones from

./node-modules/ace-builds/src-conflict
and moving them to ./src/assets/ace.

For instance:

Select an existing mode (and optionally theme) that closely matches your required syntax highlighting. In my case, I used mode-sql.js. After copying the files to ./src/assets/ace, I updated the import in my component.ts file from:

import 'ace-builds/src-noconflict/mode-sql';
import 'ace-builds/src-noconflict/theme-sqlserver';

To:

import '../../../../assets/ace/mode-sql.js';
import '../../../../assets/ace/theme-sqlserver.js';

Everything else remained as outlined in the original question. From there, you can proceed to modify the mode and theme names, adjust the rules, and style it according to your specifications.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to incorporate scope into the Transloco Translation API?

When using this.translocoService.translate('object.test');, how can I set the scope? My translation files are located in a folder named "MyFolder", so the scope will be MyFolder. The structure of my *.json files is as follows: { "demo": "te ...

Mastering Interpolation in React with TypeScript is essential for creating dynamic and interactive UI components. By leveraging the

Incorporating and distributing CSS objects through ChakraUI presents a simple need. Given that everything is inline, it seems the main issue revolves around "& > div". However, one of the TypeScript (TS) errors highlights an unexpected flagging of ...

Issue with noUnusedLocals flag detection within function* block

Compiler options: "noUnusedLocals": true, "noUnusedParameters": true, are not functioning properly within functions. An error is encountered in the following example: export class AllReduxSagas { [ts] Property 'someService' is declared bu ...

Cross-Origin Resource Sharing problem with identical URL

I encountered a CORS issue with my Angular 6 application running on port 4200 and using an API on port 3000. To address this, I implemented the following code snippet on the server side: app.use(function(req, res, next) { res.header("Access-Control-Allo ...

Incorporating Bootstrap 3 into an Angular 2 Application with Webpack

My Angular 2 project is utilizing the Webpack module bundler and I am looking to incorporate Bootstrap into the application using webpack. Bootstrap has been installed via npm, as reflected in my package.json file: "devDependencies": { "@angular/co ...

Encountering a "Missing Access" error on the Discord.js API when trying to register my slash commands

Three years ago, I created a small Discord bot in Typescript that is now present on over 80 guilds. Recently, I made the decision to update it from discord.js-v12.3.1-dev to discord.js-v13.6, while also integrating the popular slash commands feature. Howe ...

Guide to building a nested React component

My custom dropdown component requires 2 props: trigger (to activate the dropdown) list (content to display in the dropdown) Below is the implementation of my component: import { useLayer } from "react-laag"; import { ReactElement, useState } fr ...

Controlling the visibility of an element in Angular2 by toggling it based on an event triggered by a

Within my component, there is a child element: <fb-customer-list (inSearchMode)="listIsInSearchMode = event$"></fb-customer-list> This child element emits an event that contains a boolean value to indicate when it changes modes. In the paren ...

Angular 2 - Creating Your Own Validation Rules

Could someone please clarify the TypeScript syntax shown below for me? {[s: string]: boolean} This is the return type for a ValidatorFn in Angular 2. What exactly does the array: [s: string] represent? When creating my own custom ValidatorFn function, w ...

Error: Identifier 'LibraryManagedAttributes' is already in use

I am facing a similar issue to: React typescript (2312,14): Duplicate identifier 'LibraryManagedAttributes' and TypeScript error: Duplicate identifier 'LibraryManagedAttributes' Despite upgrading to the latest node/npm/yarn/typescript v ...

Using `rootDirs` in a monorepo setting results in unnecessary subfolders like `src` being generated in the `outDir`

I am in the process of planning a monorepo TypeScript project structured as follows: / (root) +--backend/ | +-src/ | \-tsconfig.json +--shared/ | \-src/ \--frontend/ \-src/ The tsconfig.json file looks like this: { "compil ...

The connection string provided is invalid or there was an issue locating the server or instance

After reinstalling my PC, I am facing issues with my SQL connection string and SQL Server 2012 Enterprise. The error messages I encounter are: "... (provider: SQL Network Interfaces, error: 25 - Connection string is not valid)" or "... (provider: SQL Ne ...

Leveraging Angular's ActivatedRoute without injecting it into a component

I'm attempting to create a helper function using ActivatedRoute to retrieve URL parameters for me. The traditional method of injecting ActivatedRoute into the component has been successful, as shown below: constructor( private route: ActivatedRou ...

Regular expressions that identify text located at the conclusion of a URL

Although the title may not be entirely appropriate, my goal is to create a regex that will remove any trailing '/' at the end of a URL under certain conditions. For example: http://stackoverflow.com/questions/ask/ to http://stackoverflow.com/qu ...

Typescript's async function failing to execute properly

I'm currently facing an issue with my code and I'm a bit puzzled as to where the problem lies. The console is displaying the correct data for this.allNominations, but it appears that the third for-loop is not being executed at all. As a result, t ...

Styling does not affect an Angular component that is injected into an iframe

I am facing an issue with styling in an iframe when trying to append my own angular component. Despite various attempts, I have been unsuccessful in getting the styling to apply to the component within the iframe. Upon loading the iframe, I use JavaScript ...

The module 'NgAutoCompleteModule' was declared unexpectedly by the 'AppModule'. To fix this issue, make sure to add a @Pipe/@Directive/@Component annotation

Currently, I am attempting to integrate an autocomplete feature into my Angular 2/4+ project. Despite trying various libraries, none of them seem to be working correctly. Each one presents me with a similar error message: Unexpected module 'NgAutoCom ...

Using Angular2's *ngIf directive to conditionally display content based on the length of

After referring to https://angular.io/docs/ts/latest/guide/displaying-data.html and a stack post on how to check for an empty object in an angular 2 template using *ngIf, I am still encountering a syntax error stating "self context undefined". If I remove ...

Ensuring the correct limitation of Records within a generic function

I am currently working on defining a generic TypeScript function that can accept a Record<number, boolean> and return the same value. The challenge I am facing is ensuring that the input type remains generic and is reflected accurately in the output. ...

Error: global not declared in the context of web3

I've been attempting to integrate Web3 into my Ionic v4 project for some time now. However, I keep encountering errors when I try to serve the project. Specifically, I receive an error message stating that Reference Error: global is not defined. Cre ...