|
|
@ -1,11 +1,11 @@
|
|
|
|
import {Component, ViewChild} from '@angular/core';
|
|
|
|
import {Component, ViewChild} from '@angular/core';
|
|
|
|
import {CodeExecutionService} from 'src/app/services/codeExecution.service';
|
|
|
|
import {CodeExecutionService} from 'src/app/services/codeExecution.service';
|
|
|
|
import { Compartment } from '@codemirror/state';
|
|
|
|
|
|
|
|
import {CodeMirrorComponent} from '@sandkasten/codemirror6-editor';
|
|
|
|
import {CodeMirrorComponent} from '@sandkasten/codemirror6-editor';
|
|
|
|
import {LanguageDescription} from '@codemirror/language';
|
|
|
|
import {LanguageDescription} from '@codemirror/language';
|
|
|
|
import {CODE_DEFAULTS, LANGUAGES} from '../languages';
|
|
|
|
import {CODE_DEFAULTS, LANGUAGES} from '../languages';
|
|
|
|
import {SafeHTMLPipe} from '../../safe-html.pipe';
|
|
|
|
import {SafeHTMLPipe} from '../../safe-html.pipe';
|
|
|
|
import {ReactiveFormsModule, FormsModule} from '@angular/forms';
|
|
|
|
import {ReactiveFormsModule, FormsModule} from '@angular/forms';
|
|
|
|
|
|
|
|
import {Extension, EditorState, Compartment} from '@codemirror/state';
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
keymap,
|
|
|
|
keymap,
|
|
|
|
highlightSpecialChars,
|
|
|
|
highlightSpecialChars,
|
|
|
@ -17,17 +17,18 @@ import {
|
|
|
|
lineNumbers,
|
|
|
|
lineNumbers,
|
|
|
|
highlightActiveLineGutter,
|
|
|
|
highlightActiveLineGutter,
|
|
|
|
gutter,
|
|
|
|
gutter,
|
|
|
|
|
|
|
|
EditorView,
|
|
|
|
} from '@codemirror/view';
|
|
|
|
} from '@codemirror/view';
|
|
|
|
import { Extension, EditorState } from '@codemirror/state';
|
|
|
|
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
defaultHighlightStyle,
|
|
|
|
defaultHighlightStyle,
|
|
|
|
syntaxHighlighting,
|
|
|
|
syntaxHighlighting,
|
|
|
|
indentOnInput,
|
|
|
|
indentOnInput,
|
|
|
|
bracketMatching,
|
|
|
|
bracketMatching,
|
|
|
|
foldGutter,
|
|
|
|
foldGutter,
|
|
|
|
|
|
|
|
indentUnit,
|
|
|
|
foldKeymap,
|
|
|
|
foldKeymap,
|
|
|
|
} from '@codemirror/language';
|
|
|
|
} from '@codemirror/language';
|
|
|
|
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
|
|
|
|
import {defaultKeymap, history, historyKeymap, indentWithTab} from '@codemirror/commands';
|
|
|
|
import {searchKeymap, highlightSelectionMatches} from '@codemirror/search';
|
|
|
|
import {searchKeymap, highlightSelectionMatches} from '@codemirror/search';
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
autocompletion,
|
|
|
|
autocompletion,
|
|
|
@ -37,6 +38,9 @@ import {
|
|
|
|
} from '@codemirror/autocomplete';
|
|
|
|
} from '@codemirror/autocomplete';
|
|
|
|
import {lintKeymap} from '@codemirror/lint';
|
|
|
|
import {lintKeymap} from '@codemirror/lint';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const DEFAULT_INDENT_UNIT = 4;
|
|
|
|
|
|
|
|
|
|
|
|
const basicSetup: Extension = (() => [
|
|
|
|
const basicSetup: Extension = (() => [
|
|
|
|
highlightActiveLineGutter(),
|
|
|
|
highlightActiveLineGutter(),
|
|
|
|
highlightSpecialChars(),
|
|
|
|
highlightSpecialChars(),
|
|
|
@ -62,6 +66,7 @@ const basicSetup: Extension = (() => [
|
|
|
|
...foldKeymap,
|
|
|
|
...foldKeymap,
|
|
|
|
...completionKeymap,
|
|
|
|
...completionKeymap,
|
|
|
|
...lintKeymap,
|
|
|
|
...lintKeymap,
|
|
|
|
|
|
|
|
indentWithTab,
|
|
|
|
]),
|
|
|
|
]),
|
|
|
|
])();
|
|
|
|
])();
|
|
|
|
|
|
|
|
|
|
|
@ -88,11 +93,11 @@ export class EditorComponent {
|
|
|
|
get selectedLanguage(): LanguageDescription {
|
|
|
|
get selectedLanguage(): LanguageDescription {
|
|
|
|
return this._selectedLanguage;
|
|
|
|
return this._selectedLanguage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set selectedLanguage(value: LanguageDescription) {
|
|
|
|
set selectedLanguage(value: LanguageDescription) {
|
|
|
|
this._selectedLanguage = value;
|
|
|
|
this._selectedLanguage = value;
|
|
|
|
if (value.name in CODE_DEFAULTS) {
|
|
|
|
if (value.name in CODE_DEFAULTS) {
|
|
|
|
this.editorContent =
|
|
|
|
this.editorContent = CODE_DEFAULTS[value.name as keyof typeof CODE_DEFAULTS];
|
|
|
|
CODE_DEFAULTS[value.name as keyof typeof CODE_DEFAULTS];
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.selectedLanguage.load().then((language) => {
|
|
|
|
this.selectedLanguage.load().then((language) => {
|
|
|
|
this.codemirror.editor?.dispatch({
|
|
|
|
this.codemirror.editor?.dispatch({
|
|
|
@ -100,10 +105,12 @@ export class EditorComponent {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private _linesNumbers: boolean = true;
|
|
|
|
private _linesNumbers: boolean = true;
|
|
|
|
get linesNumbers() {
|
|
|
|
get linesNumbers() {
|
|
|
|
return this._linesNumbers;
|
|
|
|
return this._linesNumbers;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set linesNumbers(lines: boolean) {
|
|
|
|
set linesNumbers(lines: boolean) {
|
|
|
|
this._linesNumbers = lines;
|
|
|
|
this._linesNumbers = lines;
|
|
|
|
this.codemirror.editor?.dispatch({
|
|
|
|
this.codemirror.editor?.dispatch({
|
|
|
@ -113,9 +120,33 @@ export class EditorComponent {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private _indentUnit = DEFAULT_INDENT_UNIT;
|
|
|
|
|
|
|
|
get indentUnit() {
|
|
|
|
|
|
|
|
return this._indentUnit;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set indentUnit(unit: number) {
|
|
|
|
|
|
|
|
this._indentUnit = unit;
|
|
|
|
|
|
|
|
this.codemirror.editor?.dispatch({
|
|
|
|
|
|
|
|
effects: this.indentUnitCompartment.reconfigure(
|
|
|
|
|
|
|
|
unit ? indentUnit.of(" ".repeat(unit)) : indentUnit.of(" ".repeat(DEFAULT_INDENT_UNIT))),
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private _lineWrapping = true;
|
|
|
|
|
|
|
|
get lineWrapping() {
|
|
|
|
|
|
|
|
return this._lineWrapping;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set lineWrapping(wrap: boolean) {
|
|
|
|
|
|
|
|
this._lineWrapping = wrap;
|
|
|
|
|
|
|
|
this.codemirror.editor?.dispatch({
|
|
|
|
|
|
|
|
effects: this.lineWrappingCompartment.reconfigure(wrap ? EditorView.lineWrapping : []),
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Contenu de l'éditeur que l'on passera au serveur
|
|
|
|
// Contenu de l'éditeur que l'on passera au serveur
|
|
|
|
editorContent: string =
|
|
|
|
editorContent: string = CODE_DEFAULTS[this.selectedLanguage.name as keyof typeof CODE_DEFAULTS];
|
|
|
|
CODE_DEFAULTS[this.selectedLanguage.name as keyof typeof CODE_DEFAULTS];
|
|
|
|
|
|
|
|
resultContent: string = '';
|
|
|
|
resultContent: string = '';
|
|
|
|
|
|
|
|
|
|
|
|
// Message d'erreur
|
|
|
|
// Message d'erreur
|
|
|
@ -125,13 +156,19 @@ export class EditorComponent {
|
|
|
|
|
|
|
|
|
|
|
|
private readonly languageCompartment = new Compartment();
|
|
|
|
private readonly languageCompartment = new Compartment();
|
|
|
|
private readonly gutterCompartment = new Compartment();
|
|
|
|
private readonly gutterCompartment = new Compartment();
|
|
|
|
|
|
|
|
private readonly indentUnitCompartment = new Compartment();
|
|
|
|
|
|
|
|
private readonly lineWrappingCompartment = new Compartment();
|
|
|
|
|
|
|
|
|
|
|
|
protected readonly extensions: Extension[] = [
|
|
|
|
protected readonly extensions: Extension[] = [
|
|
|
|
basicSetup,
|
|
|
|
basicSetup,
|
|
|
|
this.gutterCompartment.of(lineNumbers()),
|
|
|
|
this.gutterCompartment.of(lineNumbers()),
|
|
|
|
this.languageCompartment.of(this.selectedLanguage.support!),
|
|
|
|
this.languageCompartment.of(this.selectedLanguage.support!),
|
|
|
|
|
|
|
|
this.indentUnitCompartment.of(indentUnit.of(" ".repeat(this._indentUnit))),
|
|
|
|
|
|
|
|
this.lineWrappingCompartment.of(EditorView.lineWrapping),
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
constructor(private codeExecutionService: CodeExecutionService) {}
|
|
|
|
constructor(private codeExecutionService: CodeExecutionService) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Efface le contenu de l'éditeur
|
|
|
|
// Efface le contenu de l'éditeur
|
|
|
|
clear(): void {
|
|
|
|
clear(): void {
|
|
|
|