You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
By clicking “Sign up for GitHub”, you agree to our
terms of service
and
privacy statement
. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
I try to use this addon:
https://codemirror.net/demo/loadmode.html
The idea is to put all folder languages in my assets dir, and give formatted url etc ...
How can i access to this variable
https://github.com/codemirror/CodeMirror/blob/29e338b8c1f27ade4502839877df7afd49584479/demo/loadmode.html#L65
with ngx-codemirror ?
Another problem: CodeMirror.autoLoadMode(instance, mode) must be called but
this.codeMirror.codeMirror.autoLoadMode is not a function
After reading code of loadmode.js:
https://github.com/codemirror/CodeMirror/blob/29e338b8c1f27ade4502839877df7afd49584479/addon/mode/loadmode.js#L58
The function seems to not be declared properly on codeMirror instance
its imported down further, those are just
@types
being imported at the top
https://github.com/TypeCtrl/ngx-codemirror/blob/d5cafceb528b8b95643bd0fa3a7ff858a5c63582/src/lib/codemirror.component.ts#L98
You might make sure you've included your plugin correctly from the first step of use
https://github.com/TypeCtrl/ngx-codemirror#use
or make sure the codemirror instance has been created when your code runs
console.log(this.codeMirror.codeMirror)
, instance is ok. Viewer is ok, but when addons are loaded, no functions are inherited
Same problem with the meta mod:
Just for information, I use angular 6
After a lot of debugging, it seems
require
creates a scoped instance of CodeMirror.
Addons have to find a global instance of CodeMirror in plain mode to correctly work.
fromTextArea
doesn't return all CodeMirror object (this is why i did not find the addons functions).
My final solution is to mix global instance and this component.
For this i need to declare in angular.json all the scripts to import:
"scripts": [
"node_modules/codemirror/lib/codemirror.js",
"node_modules/codemirror/mode/meta.js",
"node_modules/codemirror/addon/mode/loadmode.js"
If we use fromTextArea from scoped instance, the setOption function will not work.
In ngx-codemirror component replace:
declare var require: any; // remove this
const { fromTextArea } = require('codemirror');
this.codeMirror = fromTextArea(this.ref.nativeElement, this._options);
declare var CodeMirror: any; // replaced by "var require..."
this.codeMirror = CodeMirror.fromTextArea(this.ref.nativeElement, this._options);
In my internal component i use declare var CodeMirror: any to access all functions (ref is the childView of ngx-codemirror component)
ngAfterViewInit() {
CodeMirror.modeURL = this.modeUrl
const mode = CodeMirror.findModeByFileName(this.file.name).mode // this function is loaded by meta addon
CodeMirror.autoLoadMode(this.ref.codeMirror, mode) // this function is loaded by loadmode addon
this.ref.codeMirror.setOption('mode', mode)
Importing addons like modes as described in the README works perfectly. Here's my main.ts
file:
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
// Import your required language in main.ts or at the root of your application
// see https://codemirror.net/mode/index.html
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/htmlmixed/htmlmixed';
import 'codemirror/addon/edit/matchbrackets';
import 'codemirror/addon/edit/closetag';
import 'codemirror/addon/selection/active-line';
if (environment.production) {
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
and here's my options object to enable the above addons:
editorOptions = {
lineNumbers: true,
autoCloseTags: true,
styleActiveLine: true,
theme: 'monokai',
mode: 'text/html',
// define Emmet output profile
profile: 'xhtml'
Btw, thank you a lot @scttcper for this awesome ngx wrapper for codemirror! 🙌
Cheers!
@scttcper This is what i do for the time being.
But if you replace the 2 lines of code, it should work for everyone:
declare var CodeMirror: any; // replaced by "var require..."
this.codeMirror = CodeMirror.fromTextArea(this.ref.nativeElement, this._options);
If people want to use other addons like me, they will only have to load the libraries via the Angular scripts tag above, for others it will work the same way.
I am attempting to do something similar except in my case is to dynamically define the mode and load it on the fly based on a matrix of user provided data... @johaven could you provide a StackBlitz showing what you did to get loadmode functional? because I am hitting a brick wall trying to deduce this thread.
"scripts": [
"node_modules/codemirror/lib/codemirror.js",
"node_modules/codemirror/mode/meta.js",
"node_modules/codemirror/addon/mode/loadmode.js",
"node_modules/codemirror/addon/mode/overlay.js"
codemirror.component.ts diff I declare this modified component in my module.
Usage example
import {AfterViewInit, Component, Input, OnInit, ViewChild, ViewEncapsulation} from '@angular/core'
import {HttpClient} from '@angular/common/http'
declare var CodeMirror: any
@Component({
selector: 'app-files-viewer-text',
encapsulation: ViewEncapsulation.None,
styles: [`
.CodeMirror {
height: 100%
`],
template: `
<div [style.height.px]="currentHeight">
<ngx-codemirror #CodeMirror [(ngModel)]="content" [options]=options></ngx-codemirror>
</div>`
export class FilesViewerTextComponent implements OnInit, AfterViewInit {
@ViewChild('CodeMirror') ref: any
@Input() currentHeight: number
@Input() file: any
@Input() fileUrl: string
private readonly modeUrl = '/static/assets/codemirror/mode/%N/%N.js'
public content: string
public options: any = {lineNumbers: true, readOnly: true, theme: 'material', mode: 'null'}
private mode: string = null
constructor(private http: HttpClient) {
CodeMirror.modeURL = this.modeUrl
ngOnInit() {
const detectedMode = CodeMirror.findModeByFileName(this.file.name)
if (detectedMode) {
this.mode = detectedMode.mode
this.http.get(this.fileUrl, {responseType: 'text'}).subscribe((data: string) => this.content = data)
} else {
this.content = 'This file contains binary data that can not be read'
ngAfterViewInit() {
if (this.mode) {
CodeMirror.autoLoadMode(this.ref.codeMirror, this.mode)
this.ref.codeMirror.setOption('mode', this.mode)