lexgui 0.1.42 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/codeeditor.js +366 -242
- package/build/lexgui.css +120 -70
- package/build/lexgui.js +876 -700
- package/build/lexgui.module.js +694 -513
- package/changelog.md +15 -2
- package/demo.js +9 -3
- package/examples/code_editor.html +3 -0
- package/examples/previews/side_bar.png +0 -0
- package/examples/previews/timeline.png +0 -0
- package/examples/side_bar.html +2 -2
- package/package.json +1 -1
|
@@ -88,7 +88,7 @@ class CodeSelection {
|
|
|
88
88
|
{
|
|
89
89
|
swapElements( this, 'fromX', 'toX' );
|
|
90
90
|
swapElements( this, 'fromY', 'toY' );
|
|
91
|
-
}
|
|
91
|
+
}
|
|
92
92
|
else if( this.sameLine() && this.fromX > this.toX )
|
|
93
93
|
{
|
|
94
94
|
swapElements( this, 'fromX', 'toX' );
|
|
@@ -96,7 +96,7 @@ class CodeSelection {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
selectInline( cursor, x, y, width, isSearchResult ) {
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
this.chars = width / this.editor.charWidth;
|
|
101
101
|
this.fromX = x;
|
|
102
102
|
this.toX = x + this.chars;
|
|
@@ -104,7 +104,7 @@ class CodeSelection {
|
|
|
104
104
|
|
|
105
105
|
var domEl = document.createElement( 'div' );
|
|
106
106
|
domEl.className = this.className;
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
domEl._top = y * this.editor.lineHeight;
|
|
109
109
|
domEl.style.top = domEl._top + "px";
|
|
110
110
|
domEl._left = x * this.editor.charWidth;
|
|
@@ -164,9 +164,9 @@ class ScrollBar {
|
|
|
164
164
|
this.root = document.createElement( 'div' );
|
|
165
165
|
this.root.className = "lexcodescrollbar";
|
|
166
166
|
|
|
167
|
-
if( type & ScrollBar.SCROLLBAR_VERTICAL )
|
|
167
|
+
if( type & ScrollBar.SCROLLBAR_VERTICAL )
|
|
168
168
|
this.root.classList.add( 'vertical' );
|
|
169
|
-
else if( type & ScrollBar.SCROLLBAR_HORIZONTAL )
|
|
169
|
+
else if( type & ScrollBar.SCROLLBAR_HORIZONTAL )
|
|
170
170
|
this.root.classList.add( 'horizontal' );
|
|
171
171
|
|
|
172
172
|
this.thumb = document.createElement( 'div' );
|
|
@@ -176,11 +176,11 @@ class ScrollBar {
|
|
|
176
176
|
this.root.appendChild( this.thumb );
|
|
177
177
|
|
|
178
178
|
this.thumb.addEventListener( "mousedown", inner_mousedown );
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
this.lastPosition = new LX.vec2( 0, 0 );
|
|
181
181
|
|
|
182
182
|
let that = this;
|
|
183
|
-
|
|
183
|
+
|
|
184
184
|
function inner_mousedown( e )
|
|
185
185
|
{
|
|
186
186
|
var doc = editor.root.ownerDocument;
|
|
@@ -194,7 +194,7 @@ class ScrollBar {
|
|
|
194
194
|
function inner_mousemove( e )
|
|
195
195
|
{
|
|
196
196
|
var dt = that.lastPosition.sub( new LX.vec2( e.x, e.y ) );
|
|
197
|
-
if( that.type & ScrollBar.SCROLLBAR_VERTICAL )
|
|
197
|
+
if( that.type & ScrollBar.SCROLLBAR_VERTICAL )
|
|
198
198
|
editor.updateVerticalScrollFromScrollBar( dt.y )
|
|
199
199
|
else
|
|
200
200
|
editor.updateHorizontalScrollFromScrollBar( dt.x )
|
|
@@ -250,7 +250,7 @@ class CodeEditor {
|
|
|
250
250
|
window.editor = this;
|
|
251
251
|
|
|
252
252
|
CodeEditor.__instances.push( this );
|
|
253
|
-
|
|
253
|
+
|
|
254
254
|
// File explorer
|
|
255
255
|
if( options.fileExplorer ?? false )
|
|
256
256
|
{
|
|
@@ -269,35 +269,35 @@ class CodeEditor {
|
|
|
269
269
|
'skipVisibility': true,
|
|
270
270
|
'children': []
|
|
271
271
|
};
|
|
272
|
-
|
|
273
|
-
this.explorer = panel.addTree( null, sceneData, {
|
|
272
|
+
|
|
273
|
+
this.explorer = panel.addTree( null, sceneData, {
|
|
274
274
|
filter: false,
|
|
275
275
|
rename: false,
|
|
276
276
|
skip_default_icon: true,
|
|
277
|
-
onevent: (event) => {
|
|
277
|
+
onevent: (event) => {
|
|
278
278
|
switch(event.type) {
|
|
279
279
|
// case LX.TreeEvent.NODE_SELECTED:
|
|
280
280
|
// if( !this.tabs.tabDOMs[ event.node.id ] ) break;
|
|
281
281
|
case LX.TreeEvent.NODE_DBLCLICKED:
|
|
282
282
|
this.loadTab( event.node.id );
|
|
283
283
|
break;
|
|
284
|
-
case LX.TreeEvent.NODE_DELETED:
|
|
284
|
+
case LX.TreeEvent.NODE_DELETED:
|
|
285
285
|
this.tabs.delete( event.node.id );
|
|
286
286
|
delete this.loadedTabs[ event.node.id ];
|
|
287
287
|
break;
|
|
288
|
-
// case LX.TreeEvent.NODE_CONTEXTMENU:
|
|
288
|
+
// case LX.TreeEvent.NODE_CONTEXTMENU:
|
|
289
289
|
// LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.value, m => {
|
|
290
|
-
//
|
|
290
|
+
//
|
|
291
291
|
// });
|
|
292
292
|
// break;
|
|
293
|
-
// case LX.TreeEvent.NODE_DRAGGED:
|
|
294
|
-
// console.log(event.node.id + " is now child of " + event.value.id);
|
|
293
|
+
// case LX.TreeEvent.NODE_DRAGGED:
|
|
294
|
+
// console.log(event.node.id + " is now child of " + event.value.id);
|
|
295
295
|
// break;
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
-
});
|
|
298
|
+
});
|
|
299
299
|
|
|
300
|
-
this.addExplorerItem = function( item )
|
|
300
|
+
this.addExplorerItem = function( item )
|
|
301
301
|
{
|
|
302
302
|
if( !this.explorer.data.children.find( (value, index) => value.id === item.id ) )
|
|
303
303
|
this.explorer.data.children.push( item );
|
|
@@ -347,7 +347,7 @@ class CodeEditor {
|
|
|
347
347
|
this.root.addEventListener( 'focus', this.processFocus.bind( this, true ) );
|
|
348
348
|
this.root.addEventListener( 'focusout', this.processFocus.bind( this, false ) );
|
|
349
349
|
}
|
|
350
|
-
|
|
350
|
+
|
|
351
351
|
this.root.addEventListener( 'mousedown', this.processMouse.bind(this) );
|
|
352
352
|
this.root.addEventListener( 'mouseup', this.processMouse.bind(this) );
|
|
353
353
|
this.root.addEventListener( 'mousemove', this.processMouse.bind(this) );
|
|
@@ -403,8 +403,8 @@ class CodeEditor {
|
|
|
403
403
|
if( this.visibleLinesViewport.y < (this.code.lines.length - 1) )
|
|
404
404
|
{
|
|
405
405
|
const totalLinesInViewport = ((this.codeScroller.offsetHeight - 36) / this.lineHeight)|0;
|
|
406
|
-
const scrollDownBoundary =
|
|
407
|
-
( Math.max( this.visibleLinesViewport.y - totalLinesInViewport, 0 ) - 1 ) * this.lineHeight;
|
|
406
|
+
const scrollDownBoundary =
|
|
407
|
+
( Math.max( this.visibleLinesViewport.y - totalLinesInViewport, 0 ) - 1 ) * this.lineHeight;
|
|
408
408
|
|
|
409
409
|
if( scrollTop >= scrollDownBoundary )
|
|
410
410
|
this.processLines( CodeEditor.UPDATE_VISIBLE_LINES );
|
|
@@ -468,7 +468,7 @@ class CodeEditor {
|
|
|
468
468
|
{
|
|
469
469
|
var box = document.createElement( 'div' );
|
|
470
470
|
box.className = "searchbox";
|
|
471
|
-
|
|
471
|
+
|
|
472
472
|
var searchPanel = new LX.Panel();
|
|
473
473
|
box.appendChild( searchPanel.root );
|
|
474
474
|
|
|
@@ -491,7 +491,7 @@ class CodeEditor {
|
|
|
491
491
|
{
|
|
492
492
|
var box = document.createElement( 'div' );
|
|
493
493
|
box.className = "searchbox gotoline";
|
|
494
|
-
|
|
494
|
+
|
|
495
495
|
var searchPanel = new LX.Panel();
|
|
496
496
|
box.appendChild( searchPanel.root );
|
|
497
497
|
|
|
@@ -513,7 +513,7 @@ class CodeEditor {
|
|
|
513
513
|
{
|
|
514
514
|
this.codeSizer = document.createElement( 'div' );
|
|
515
515
|
this.codeSizer.className = "code-sizer";
|
|
516
|
-
|
|
516
|
+
|
|
517
517
|
// Append all childs
|
|
518
518
|
while( this.codeScroller.firstChild )
|
|
519
519
|
this.codeSizer.appendChild( this.codeScroller.firstChild );
|
|
@@ -555,7 +555,7 @@ class CodeEditor {
|
|
|
555
555
|
};
|
|
556
556
|
|
|
557
557
|
this.stringKeys = { // adding @ because some words are always true in (e.g. constructor..)
|
|
558
|
-
"@\"": "\"",
|
|
558
|
+
"@\"": "\"",
|
|
559
559
|
"@'": "'"
|
|
560
560
|
};
|
|
561
561
|
|
|
@@ -565,8 +565,10 @@ class CodeEditor {
|
|
|
565
565
|
this.languages = {
|
|
566
566
|
'Plain Text': { ext: 'txt', blockComments: false, singleLineComments: false },
|
|
567
567
|
'JavaScript': { ext: 'js' },
|
|
568
|
-
'C
|
|
568
|
+
'C': { ext: [ 'c', 'h' ] },
|
|
569
|
+
'C++': { ext: [ 'cpp', 'hpp' ] },
|
|
569
570
|
'CSS': { ext: 'css' },
|
|
571
|
+
'CMake': { ext: 'cmake', singleLineCommentToken: '#', blockComments: false, ignoreCase: true },
|
|
570
572
|
'GLSL': { ext: 'glsl' },
|
|
571
573
|
'WGSL': { ext: 'wgsl' },
|
|
572
574
|
'JSON': { ext: 'json', blockComments: false, singleLineComments: false },
|
|
@@ -579,7 +581,7 @@ class CodeEditor {
|
|
|
579
581
|
};
|
|
580
582
|
|
|
581
583
|
this.specialKeys = [
|
|
582
|
-
'Backspace', 'Enter', 'ArrowUp', 'ArrowDown',
|
|
584
|
+
'Backspace', 'Enter', 'ArrowUp', 'ArrowDown',
|
|
583
585
|
'ArrowRight', 'ArrowLeft', 'Delete', 'Home',
|
|
584
586
|
'End', 'Tab', 'Escape'
|
|
585
587
|
];
|
|
@@ -593,10 +595,10 @@ class CodeEditor {
|
|
|
593
595
|
for( let lang in CodeEditor.keywords ) CodeEditor.keywords[lang] = CodeEditor.keywords[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
594
596
|
for( let lang in CodeEditor.utils ) CodeEditor.utils[lang] = CodeEditor.utils[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
595
597
|
for( let lang in CodeEditor.types ) CodeEditor.types[lang] = CodeEditor.types[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
596
|
-
for( let lang in CodeEditor.
|
|
598
|
+
for( let lang in CodeEditor.builtIn ) CodeEditor.builtIn[lang] = CodeEditor.builtIn[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
597
599
|
for( let lang in CodeEditor.statementsAndDeclarations ) CodeEditor.statementsAndDeclarations[lang] = CodeEditor.statementsAndDeclarations[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
598
600
|
for( let lang in CodeEditor.symbols ) CodeEditor.symbols[lang] = CodeEditor.symbols[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
599
|
-
|
|
601
|
+
|
|
600
602
|
CodeEditor._staticReady = true;
|
|
601
603
|
}
|
|
602
604
|
|
|
@@ -619,7 +621,7 @@ class CodeEditor {
|
|
|
619
621
|
if( cursor.selection ) {
|
|
620
622
|
this.deleteSelection( cursor );
|
|
621
623
|
// Remove entire line when selecting with triple click
|
|
622
|
-
if( this._tripleClickSelection )
|
|
624
|
+
if( this._tripleClickSelection )
|
|
623
625
|
{
|
|
624
626
|
this.actions['Backspace'].callback( ln, cursor, e );
|
|
625
627
|
this.lineDown( cursor, true );
|
|
@@ -632,7 +634,7 @@ class CodeEditor {
|
|
|
632
634
|
|
|
633
635
|
var deleteFromPosition = cursor.position - 1;
|
|
634
636
|
var numCharsDeleted = 1;
|
|
635
|
-
|
|
637
|
+
|
|
636
638
|
// Delete full word
|
|
637
639
|
if( e.shiftKey )
|
|
638
640
|
{
|
|
@@ -652,7 +654,7 @@ class CodeEditor {
|
|
|
652
654
|
|
|
653
655
|
if( this.useAutoComplete )
|
|
654
656
|
this.showAutoCompleteBox( 'foo', cursor );
|
|
655
|
-
}
|
|
657
|
+
}
|
|
656
658
|
else if( this.code.lines[ ln - 1 ] != undefined ) {
|
|
657
659
|
|
|
658
660
|
this.lineUp( cursor );
|
|
@@ -669,7 +671,7 @@ class CodeEditor {
|
|
|
669
671
|
this.action( 'Delete', false, ( ln, cursor, e ) => {
|
|
670
672
|
|
|
671
673
|
this._addUndoStep( cursor );
|
|
672
|
-
|
|
674
|
+
|
|
673
675
|
if( cursor.selection ) {
|
|
674
676
|
// Use 'Backspace' as it's the same callback...
|
|
675
677
|
this.actions['Backspace'].callback( ln, cursor, e );
|
|
@@ -680,7 +682,7 @@ class CodeEditor {
|
|
|
680
682
|
if( letter ) {
|
|
681
683
|
this.code.lines[ ln ] = sliceChars( this.code.lines[ ln ], cursor.position );
|
|
682
684
|
this.processLine( ln );
|
|
683
|
-
}
|
|
685
|
+
}
|
|
684
686
|
else if( this.code.lines[ ln + 1 ] != undefined ) {
|
|
685
687
|
this.code.lines[ ln ] += this.code.lines[ ln + 1 ];
|
|
686
688
|
this.code.lines.splice( ln + 1, 1 );
|
|
@@ -690,7 +692,7 @@ class CodeEditor {
|
|
|
690
692
|
});
|
|
691
693
|
|
|
692
694
|
this.action( 'Tab', true, ( ln, cursor, e ) => {
|
|
693
|
-
|
|
695
|
+
|
|
694
696
|
if( this._skipTabs )
|
|
695
697
|
{
|
|
696
698
|
this._skipTabs--;
|
|
@@ -718,7 +720,7 @@ class CodeEditor {
|
|
|
718
720
|
}, "shiftKey");
|
|
719
721
|
|
|
720
722
|
this.action( 'Home', false, ( ln, cursor, e ) => {
|
|
721
|
-
|
|
723
|
+
|
|
722
724
|
let idx = firstNonspaceIndex( this.code.lines[ ln ] );
|
|
723
725
|
|
|
724
726
|
// We already are in the first non space index...
|
|
@@ -738,7 +740,7 @@ class CodeEditor {
|
|
|
738
740
|
if( e.shiftKey && !e.cancelShift )
|
|
739
741
|
{
|
|
740
742
|
// Get last selection range
|
|
741
|
-
if( cursor.selection )
|
|
743
|
+
if( cursor.selection )
|
|
742
744
|
lastX += cursor.selection.chars;
|
|
743
745
|
|
|
744
746
|
if( !cursor.selection )
|
|
@@ -756,9 +758,9 @@ class CodeEditor {
|
|
|
756
758
|
});
|
|
757
759
|
|
|
758
760
|
this.action( 'End', false, ( ln, cursor, e ) => {
|
|
759
|
-
|
|
761
|
+
|
|
760
762
|
if( ( e.shiftKey || e._shiftKey ) && !e.cancelShift ) {
|
|
761
|
-
|
|
763
|
+
|
|
762
764
|
var string = this.code.lines[ ln ].substring( cursor.position );
|
|
763
765
|
if( !cursor.selection )
|
|
764
766
|
this.startSelection( cursor );
|
|
@@ -767,7 +769,7 @@ class CodeEditor {
|
|
|
767
769
|
else
|
|
768
770
|
{
|
|
769
771
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT, cursor );
|
|
770
|
-
this.cursorToString( cursor, this.code.lines[ ln ] );
|
|
772
|
+
this.cursorToString( cursor, this.code.lines[ ln ] );
|
|
771
773
|
this._processSelection( cursor, e );
|
|
772
774
|
}
|
|
773
775
|
} else if( !e.keepSelection )
|
|
@@ -839,7 +841,7 @@ class CodeEditor {
|
|
|
839
841
|
if( !letter ) {
|
|
840
842
|
this.cursorToPosition( cursor, this.code.lines[ cursor.line ].length );
|
|
841
843
|
}
|
|
842
|
-
|
|
844
|
+
|
|
843
845
|
this._processSelection( cursor, e, false );
|
|
844
846
|
|
|
845
847
|
} else {
|
|
@@ -849,7 +851,7 @@ class CodeEditor {
|
|
|
849
851
|
var letter = this.getCharAtPos( cursor );
|
|
850
852
|
if( !letter ) this.actions['End'].callback( cursor.line, cursor, e );
|
|
851
853
|
}
|
|
852
|
-
}
|
|
854
|
+
}
|
|
853
855
|
// Move up autocomplete selection
|
|
854
856
|
else
|
|
855
857
|
{
|
|
@@ -880,7 +882,7 @@ class CodeEditor {
|
|
|
880
882
|
if( e.shiftKey ) {
|
|
881
883
|
this._processSelection( cursor, e );
|
|
882
884
|
}
|
|
883
|
-
}
|
|
885
|
+
}
|
|
884
886
|
// Move down autocomplete selection
|
|
885
887
|
else
|
|
886
888
|
{
|
|
@@ -916,7 +918,7 @@ class CodeEditor {
|
|
|
916
918
|
// Selections...
|
|
917
919
|
if( e.shiftKey ) {
|
|
918
920
|
if( !cursor.selection )
|
|
919
|
-
this.startSelection( cursor );
|
|
921
|
+
this.startSelection( cursor );
|
|
920
922
|
}
|
|
921
923
|
else
|
|
922
924
|
this.endSelection();
|
|
@@ -950,9 +952,9 @@ class CodeEditor {
|
|
|
950
952
|
}
|
|
951
953
|
}
|
|
952
954
|
else if( cursor.line > 0 ) {
|
|
953
|
-
|
|
955
|
+
|
|
954
956
|
if( e.shiftKey && !cursor.selection ) this.startSelection( cursor );
|
|
955
|
-
|
|
957
|
+
|
|
956
958
|
this.lineUp( cursor );
|
|
957
959
|
|
|
958
960
|
e.cancelShift = e.keepSelection = true;
|
|
@@ -967,7 +969,7 @@ class CodeEditor {
|
|
|
967
969
|
this.action( 'ArrowRight', false, ( ln, cursor, e ) => {
|
|
968
970
|
|
|
969
971
|
// Nothing to do..
|
|
970
|
-
if( cursor.line == this.code.lines.length - 1 &&
|
|
972
|
+
if( cursor.line == this.code.lines.length - 1 &&
|
|
971
973
|
cursor.position == this.code.lines[ cursor.line ].length )
|
|
972
974
|
return;
|
|
973
975
|
|
|
@@ -1031,14 +1033,14 @@ class CodeEditor {
|
|
|
1031
1033
|
}
|
|
1032
1034
|
}
|
|
1033
1035
|
else if( this.code.lines[ cursor.line + 1 ] !== undefined ) {
|
|
1034
|
-
|
|
1036
|
+
|
|
1035
1037
|
if( e.shiftKey ) {
|
|
1036
1038
|
if( !cursor.selection ) this.startSelection( cursor );
|
|
1037
1039
|
}
|
|
1038
1040
|
else this.endSelection();
|
|
1039
1041
|
|
|
1040
1042
|
this.lineDown( cursor, true );
|
|
1041
|
-
|
|
1043
|
+
|
|
1042
1044
|
if( e.shiftKey ) this._processSelection( cursor, e, false );
|
|
1043
1045
|
|
|
1044
1046
|
this.hideAutoCompleteBox();
|
|
@@ -1047,10 +1049,10 @@ class CodeEditor {
|
|
|
1047
1049
|
});
|
|
1048
1050
|
|
|
1049
1051
|
// Default code tab
|
|
1050
|
-
|
|
1052
|
+
|
|
1051
1053
|
this.loadedTabs = { };
|
|
1052
1054
|
this.openedTabs = { };
|
|
1053
|
-
|
|
1055
|
+
|
|
1054
1056
|
if( options.allowAddScripts ?? true )
|
|
1055
1057
|
{
|
|
1056
1058
|
this.addTab("+", false, "New File");
|
|
@@ -1072,7 +1074,7 @@ class CodeEditor {
|
|
|
1072
1074
|
display: "swap"
|
|
1073
1075
|
}
|
|
1074
1076
|
);
|
|
1075
|
-
|
|
1077
|
+
|
|
1076
1078
|
// Add to the document.fonts (FontFaceSet)
|
|
1077
1079
|
document.fonts.add( commitMono );
|
|
1078
1080
|
|
|
@@ -1093,7 +1095,7 @@ class CodeEditor {
|
|
|
1093
1095
|
|
|
1094
1096
|
// This received key inputs from the entire document...
|
|
1095
1097
|
onKeyPressed( e ) {
|
|
1096
|
-
|
|
1098
|
+
|
|
1097
1099
|
// Toggle visibility of the file explorer
|
|
1098
1100
|
if( e.key == 'b' && e.ctrlKey && this.explorer )
|
|
1099
1101
|
{
|
|
@@ -1162,7 +1164,7 @@ class CodeEditor {
|
|
|
1162
1164
|
|
|
1163
1165
|
// Add first line
|
|
1164
1166
|
this.code.lines[ lidx ] = [
|
|
1165
|
-
this.code.lines[ lidx ].slice( 0, cursor.position ),
|
|
1167
|
+
this.code.lines[ lidx ].slice( 0, cursor.position ),
|
|
1166
1168
|
first_line
|
|
1167
1169
|
].join('');
|
|
1168
1170
|
|
|
@@ -1189,8 +1191,8 @@ class CodeEditor {
|
|
|
1189
1191
|
else
|
|
1190
1192
|
{
|
|
1191
1193
|
this.code.lines[ lidx ] = [
|
|
1192
|
-
this.code.lines[ lidx ].slice( 0, cursor.position ),
|
|
1193
|
-
new_lines[ 0 ],
|
|
1194
|
+
this.code.lines[ lidx ].slice( 0, cursor.position ),
|
|
1195
|
+
new_lines[ 0 ],
|
|
1194
1196
|
this.code.lines[ lidx ].slice( cursor.position )
|
|
1195
1197
|
].join('');
|
|
1196
1198
|
|
|
@@ -1249,7 +1251,7 @@ class CodeEditor {
|
|
|
1249
1251
|
{
|
|
1250
1252
|
const fr = new FileReader();
|
|
1251
1253
|
fr.readAsText( file );
|
|
1252
|
-
fr.onload = e => {
|
|
1254
|
+
fr.onload = e => {
|
|
1253
1255
|
const text = e.currentTarget.result;
|
|
1254
1256
|
inner_add_tab( text, file.name );
|
|
1255
1257
|
};
|
|
@@ -1267,7 +1269,7 @@ class CodeEditor {
|
|
|
1267
1269
|
|
|
1268
1270
|
return;
|
|
1269
1271
|
}
|
|
1270
|
-
|
|
1272
|
+
|
|
1271
1273
|
let cursor = document.createElement( 'div' );
|
|
1272
1274
|
cursor.name = "cursor" + this.cursors.childElementCount;
|
|
1273
1275
|
cursor.className = "cursor";
|
|
@@ -1284,7 +1286,7 @@ class CodeEditor {
|
|
|
1284
1286
|
|
|
1285
1287
|
Object.defineProperty( cursor, 'line', {
|
|
1286
1288
|
get: (v) => { return cursor._line },
|
|
1287
|
-
set: (v) => {
|
|
1289
|
+
set: (v) => {
|
|
1288
1290
|
cursor._line = v;
|
|
1289
1291
|
if( cursor.isMain ) this._setActiveLine( v );
|
|
1290
1292
|
}
|
|
@@ -1292,7 +1294,7 @@ class CodeEditor {
|
|
|
1292
1294
|
|
|
1293
1295
|
Object.defineProperty( cursor, 'position', {
|
|
1294
1296
|
get: (v) => { return cursor._position },
|
|
1295
|
-
set: (v) => {
|
|
1297
|
+
set: (v) => {
|
|
1296
1298
|
cursor._position = v;
|
|
1297
1299
|
if( cursor.isMain ) this._updateDataInfoPanel( "@cursor-pos", "Col " + ( v + 1 ) );
|
|
1298
1300
|
}
|
|
@@ -1351,7 +1353,7 @@ class CodeEditor {
|
|
|
1351
1353
|
}
|
|
1352
1354
|
}
|
|
1353
1355
|
|
|
1354
|
-
if( deleteRedo )
|
|
1356
|
+
if( deleteRedo )
|
|
1355
1357
|
{
|
|
1356
1358
|
// Remove all redo steps
|
|
1357
1359
|
this.code.redoSteps.length = 0;
|
|
@@ -1459,7 +1461,8 @@ class CodeEditor {
|
|
|
1459
1461
|
{
|
|
1460
1462
|
iconEl = document.createElement( 'i' );
|
|
1461
1463
|
iconEl.className = icon;
|
|
1462
|
-
} else
|
|
1464
|
+
} else
|
|
1465
|
+
{
|
|
1463
1466
|
iconEl = document.createElement( 'img' );
|
|
1464
1467
|
iconEl.src = "https://raw.githubusercontent.com/jxarco/lexgui.js/master/" + icon;
|
|
1465
1468
|
}
|
|
@@ -1477,21 +1480,38 @@ class CodeEditor {
|
|
|
1477
1480
|
}
|
|
1478
1481
|
|
|
1479
1482
|
_changeLanguageFromExtension( ext ) {
|
|
1480
|
-
|
|
1483
|
+
|
|
1481
1484
|
if( !ext )
|
|
1482
|
-
|
|
1485
|
+
{
|
|
1486
|
+
return this._changeLanguage( this.code.language );
|
|
1487
|
+
}
|
|
1483
1488
|
|
|
1484
1489
|
for( let l in this.languages )
|
|
1485
1490
|
{
|
|
1486
|
-
|
|
1487
|
-
|
|
1491
|
+
const langExtension = this.languages[ l ].ext;
|
|
1492
|
+
|
|
1493
|
+
if( langExtension.constructor == Array )
|
|
1494
|
+
{
|
|
1495
|
+
if( langExtension.indexOf( ext ) > -1 )
|
|
1496
|
+
{
|
|
1497
|
+
return this._changeLanguage( l );
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
else
|
|
1501
|
+
{
|
|
1502
|
+
if( langExtension == ext )
|
|
1503
|
+
{
|
|
1504
|
+
return this._changeLanguage( l );
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1488
1508
|
}
|
|
1489
1509
|
|
|
1490
1510
|
this._changeLanguage( 'Plain Text' );
|
|
1491
1511
|
}
|
|
1492
1512
|
|
|
1493
1513
|
_createPanelInfo() {
|
|
1494
|
-
|
|
1514
|
+
|
|
1495
1515
|
if( !this.skipCodeInfo )
|
|
1496
1516
|
{
|
|
1497
1517
|
let panel = new LX.Panel({ className: "lexcodetabinfo", width: "calc(100%)", height: "auto" });
|
|
@@ -1543,12 +1563,36 @@ class CodeEditor {
|
|
|
1543
1563
|
_getFileIcon( name, extension ) {
|
|
1544
1564
|
|
|
1545
1565
|
const isNewTabButton = name ? ( name === '+' ) : false;
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1566
|
+
|
|
1567
|
+
if( !extension )
|
|
1568
|
+
{
|
|
1569
|
+
extension = LX.getExtension( name );
|
|
1570
|
+
}
|
|
1571
|
+
else
|
|
1572
|
+
{
|
|
1573
|
+
const possibleExtensions = [].concat( extension );
|
|
1574
|
+
|
|
1575
|
+
if( name )
|
|
1576
|
+
{
|
|
1577
|
+
const fileExtension = LX.getExtension( name );
|
|
1578
|
+
const idx = possibleExtensions.indexOf( fileExtension );
|
|
1579
|
+
|
|
1580
|
+
if( idx > -1)
|
|
1581
|
+
{
|
|
1582
|
+
extension = possibleExtensions[ idx ];
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
else
|
|
1586
|
+
{
|
|
1587
|
+
extension = possibleExtensions[ 0 ];
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
return extension == "html" ? "fa-solid fa-code orange" :
|
|
1592
|
+
extension == "css" ? "fa-solid fa-hashtag dodgerblue" :
|
|
1593
|
+
extension == "xml" ? "fa-solid fa-rss orange" :
|
|
1594
|
+
extension == "bat" ? "fa-brands fa-windows lightblue" :
|
|
1595
|
+
[ 'js', 'py', 'json', 'cpp', 'hpp', 'rs', 'md' ].indexOf( extension ) > -1 ? "images/" + extension + ".png" :
|
|
1552
1596
|
!isNewTabButton ? "fa-solid fa-align-left gray" : undefined;
|
|
1553
1597
|
}
|
|
1554
1598
|
|
|
@@ -1573,10 +1617,10 @@ class CodeEditor {
|
|
|
1573
1617
|
this._removeSecondaryCursors();
|
|
1574
1618
|
var cursor = this._getCurrentCursor( true );
|
|
1575
1619
|
|
|
1576
|
-
this.saveCursor( cursor, this.code.cursorState );
|
|
1620
|
+
this.saveCursor( cursor, this.code.cursorState );
|
|
1577
1621
|
|
|
1578
1622
|
this.code = this.loadedTabs[ name ];
|
|
1579
|
-
this.restoreCursor( cursor, this.code.cursorState );
|
|
1623
|
+
this.restoreCursor( cursor, this.code.cursorState );
|
|
1580
1624
|
|
|
1581
1625
|
this.endSelection();
|
|
1582
1626
|
this._updateDataInfoPanel( "@tab-name", name );
|
|
@@ -1592,7 +1636,7 @@ class CodeEditor {
|
|
|
1592
1636
|
}
|
|
1593
1637
|
|
|
1594
1638
|
_onContextMenuTab( isNewTabButton, event, name, ) {
|
|
1595
|
-
|
|
1639
|
+
|
|
1596
1640
|
if( isNewTabButton )
|
|
1597
1641
|
return;
|
|
1598
1642
|
|
|
@@ -1604,7 +1648,7 @@ class CodeEditor {
|
|
|
1604
1648
|
}
|
|
1605
1649
|
|
|
1606
1650
|
addTab( name, selected, title, options = {} ) {
|
|
1607
|
-
|
|
1651
|
+
|
|
1608
1652
|
// If already loaded, set new name...
|
|
1609
1653
|
const repeats = Object.keys( editor.loadedTabs ).slice( 1 ).reduce( ( v, key ) => {
|
|
1610
1654
|
const noRepeatName = key.replace( /[_\d+]/g, '');
|
|
@@ -1647,7 +1691,7 @@ class CodeEditor {
|
|
|
1647
1691
|
|
|
1648
1692
|
this.loadedTabs[ name ] = code;
|
|
1649
1693
|
this.openedTabs[ name ] = code;
|
|
1650
|
-
|
|
1694
|
+
|
|
1651
1695
|
const tabIcon = this._getFileIcon( name );
|
|
1652
1696
|
|
|
1653
1697
|
if( this.explorer && !isNewTabButton )
|
|
@@ -1656,23 +1700,23 @@ class CodeEditor {
|
|
|
1656
1700
|
this.explorer.frefresh( name );
|
|
1657
1701
|
}
|
|
1658
1702
|
|
|
1659
|
-
this.tabs.add( name, code, {
|
|
1660
|
-
selected: selected,
|
|
1661
|
-
fixed: isNewTabButton,
|
|
1662
|
-
title: code.title,
|
|
1663
|
-
icon: tabIcon,
|
|
1703
|
+
this.tabs.add( name, code, {
|
|
1704
|
+
selected: selected,
|
|
1705
|
+
fixed: isNewTabButton,
|
|
1706
|
+
title: code.title,
|
|
1707
|
+
icon: tabIcon,
|
|
1664
1708
|
onSelect: this._onSelectTab.bind( this, isNewTabButton ),
|
|
1665
1709
|
onContextMenu: this._onContextMenuTab.bind( this, isNewTabButton )
|
|
1666
1710
|
} );
|
|
1667
1711
|
|
|
1668
1712
|
// Move into the sizer..
|
|
1669
1713
|
this.codeSizer.appendChild( code );
|
|
1670
|
-
|
|
1714
|
+
|
|
1671
1715
|
this.endSelection();
|
|
1672
1716
|
|
|
1673
1717
|
if( selected )
|
|
1674
1718
|
{
|
|
1675
|
-
this.code = code;
|
|
1719
|
+
this.code = code;
|
|
1676
1720
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT | CodeEditor.CURSOR_TOP );
|
|
1677
1721
|
this.processLines();
|
|
1678
1722
|
}
|
|
@@ -1726,26 +1770,26 @@ class CodeEditor {
|
|
|
1726
1770
|
}
|
|
1727
1771
|
|
|
1728
1772
|
this.openedTabs[ name ] = code;
|
|
1729
|
-
|
|
1773
|
+
|
|
1730
1774
|
const isNewTabButton = ( name === '+' );
|
|
1731
1775
|
const tabIcon = this._getFileIcon( name );
|
|
1732
1776
|
|
|
1733
|
-
this.tabs.add(name, code, {
|
|
1734
|
-
selected: true,
|
|
1735
|
-
fixed: isNewTabButton,
|
|
1736
|
-
title: code.title,
|
|
1737
|
-
icon: tabIcon,
|
|
1777
|
+
this.tabs.add(name, code, {
|
|
1778
|
+
selected: true,
|
|
1779
|
+
fixed: isNewTabButton,
|
|
1780
|
+
title: code.title,
|
|
1781
|
+
icon: tabIcon,
|
|
1738
1782
|
onSelect: this._onSelectTab.bind( this, isNewTabButton ),
|
|
1739
1783
|
onContextMenu: this._onContextMenuTab.bind( this, isNewTabButton )
|
|
1740
1784
|
});
|
|
1741
1785
|
|
|
1742
1786
|
// Move into the sizer..
|
|
1743
1787
|
this.codeSizer.appendChild( code );
|
|
1744
|
-
|
|
1788
|
+
|
|
1745
1789
|
this.endSelection();
|
|
1746
1790
|
|
|
1747
1791
|
// Select as current...
|
|
1748
|
-
this.code = code;
|
|
1792
|
+
this.code = code;
|
|
1749
1793
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT | CodeEditor.CURSOR_TOP );
|
|
1750
1794
|
this.processLines();
|
|
1751
1795
|
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
@@ -1799,7 +1843,7 @@ class CodeEditor {
|
|
|
1799
1843
|
|
|
1800
1844
|
if( cursor.selection )
|
|
1801
1845
|
{
|
|
1802
|
-
this.canOpenContextMenu |= (cursor.line >= cursor.selection.fromY && cursor.line <= cursor.selection.toY
|
|
1846
|
+
this.canOpenContextMenu |= (cursor.line >= cursor.selection.fromY && cursor.line <= cursor.selection.toY
|
|
1803
1847
|
&& cursor.position >= cursor.selection.fromX && cursor.position <= cursor.selection.toX);
|
|
1804
1848
|
if( this.canOpenContextMenu )
|
|
1805
1849
|
return;
|
|
@@ -1811,7 +1855,7 @@ class CodeEditor {
|
|
|
1811
1855
|
this.endSelection();
|
|
1812
1856
|
this.processClick( e );
|
|
1813
1857
|
}
|
|
1814
|
-
|
|
1858
|
+
|
|
1815
1859
|
else if( e.type == 'mouseup' )
|
|
1816
1860
|
{
|
|
1817
1861
|
this._onMouseUp( e );
|
|
@@ -1859,11 +1903,11 @@ class CodeEditor {
|
|
|
1859
1903
|
m.add( "Cut", () => { this._cutContent( cursor ); } );
|
|
1860
1904
|
m.add( "Paste", () => { this._pasteContent( cursor ); } );
|
|
1861
1905
|
m.add( "" );
|
|
1862
|
-
m.add( "Format/JSON", () => {
|
|
1906
|
+
m.add( "Format/JSON", () => {
|
|
1863
1907
|
let json = this.toJSONFormat( this.getText() );
|
|
1864
1908
|
if( !json )
|
|
1865
1909
|
return;
|
|
1866
|
-
this.code.lines = json.split( "\n" );
|
|
1910
|
+
this.code.lines = json.split( "\n" );
|
|
1867
1911
|
this.processLines();
|
|
1868
1912
|
} );
|
|
1869
1913
|
}
|
|
@@ -1911,7 +1955,7 @@ class CodeEditor {
|
|
|
1911
1955
|
this.cursorToLine( cursor, ln, true );
|
|
1912
1956
|
this.cursorToPosition( cursor, string.length );
|
|
1913
1957
|
}
|
|
1914
|
-
|
|
1958
|
+
|
|
1915
1959
|
// Add new cursor
|
|
1916
1960
|
else
|
|
1917
1961
|
{
|
|
@@ -1957,7 +2001,7 @@ class CodeEditor {
|
|
|
1957
2001
|
let ccw = true;
|
|
1958
2002
|
|
|
1959
2003
|
// Check if we must change ccw or not ... (not with mouse)
|
|
1960
|
-
if( !isMouseEvent && cursor.line >= cursor.selection.fromY &&
|
|
2004
|
+
if( !isMouseEvent && cursor.line >= cursor.selection.fromY &&
|
|
1961
2005
|
(cursor.line == cursor.selection.fromY ? cursor.position >= cursor.selection.fromX : true) )
|
|
1962
2006
|
{
|
|
1963
2007
|
ccw = ( e && this._lastSelectionKeyDir && ( e.key == 'ArrowRight' || e.key == 'ArrowDown' || e.key == 'End' ) );
|
|
@@ -2020,7 +2064,7 @@ class CodeEditor {
|
|
|
2020
2064
|
|
|
2021
2065
|
// Compute new width and selection margins
|
|
2022
2066
|
let string;
|
|
2023
|
-
|
|
2067
|
+
|
|
2024
2068
|
if(sId == 0) // First line 2 cases (single line, multiline)
|
|
2025
2069
|
{
|
|
2026
2070
|
const reverse = fromX > toX;
|
|
@@ -2034,7 +2078,7 @@ class CodeEditor {
|
|
|
2034
2078
|
string = (i == toY) ? this.code.lines[ i ].substring( 0, toX ) : this.code.lines[ i ]; // Last line, any multiple line...
|
|
2035
2079
|
if( isVisible ) domEl.style.left = this.xPadding;
|
|
2036
2080
|
}
|
|
2037
|
-
|
|
2081
|
+
|
|
2038
2082
|
const stringWidth = this.measureString( string );
|
|
2039
2083
|
cursor.selection.chars += stringWidth / this.charWidth;
|
|
2040
2084
|
|
|
@@ -2071,7 +2115,7 @@ class CodeEditor {
|
|
|
2071
2115
|
|
|
2072
2116
|
// Compute new width and selection margins
|
|
2073
2117
|
let string;
|
|
2074
|
-
|
|
2118
|
+
|
|
2075
2119
|
if( sId == 0 )
|
|
2076
2120
|
{
|
|
2077
2121
|
string = this.code.lines[ i ].substr(toX);
|
|
@@ -2083,10 +2127,10 @@ class CodeEditor {
|
|
|
2083
2127
|
string = (i == fromY) ? this.code.lines[ i ].substring(0, fromX) : this.code.lines[ i ]; // Last line, any multiple line...
|
|
2084
2128
|
if( isVisible ) domEl.style.left = this.xPadding;
|
|
2085
2129
|
}
|
|
2086
|
-
|
|
2130
|
+
|
|
2087
2131
|
const stringWidth = this.measureString( string );
|
|
2088
2132
|
cursor.selection.chars += stringWidth / this.charWidth;
|
|
2089
|
-
|
|
2133
|
+
|
|
2090
2134
|
if( isVisible )
|
|
2091
2135
|
{
|
|
2092
2136
|
domEl.style.width = (stringWidth || 8) + "px";
|
|
@@ -2098,10 +2142,10 @@ class CodeEditor {
|
|
|
2098
2142
|
}
|
|
2099
2143
|
|
|
2100
2144
|
async processKey( e ) {
|
|
2101
|
-
|
|
2145
|
+
|
|
2102
2146
|
const numCursors = this.cursors.childElementCount;
|
|
2103
2147
|
|
|
2104
|
-
if( !this.code || e.srcElement.constructor != HTMLDivElement )
|
|
2148
|
+
if( !this.code || e.srcElement.constructor != HTMLDivElement )
|
|
2105
2149
|
return;
|
|
2106
2150
|
|
|
2107
2151
|
const key = e.key ?? e.detail.key;
|
|
@@ -2306,7 +2350,7 @@ class CodeEditor {
|
|
|
2306
2350
|
return;
|
|
2307
2351
|
}
|
|
2308
2352
|
}
|
|
2309
|
-
|
|
2353
|
+
|
|
2310
2354
|
// Apply binded actions...
|
|
2311
2355
|
|
|
2312
2356
|
for( const actKey in this.actions ) {
|
|
@@ -2338,11 +2382,11 @@ class CodeEditor {
|
|
|
2338
2382
|
const enclosableKeys = [ "\"", "'", "(", "{" ];
|
|
2339
2383
|
if( enclosableKeys.indexOf( key ) > -1 )
|
|
2340
2384
|
{
|
|
2341
|
-
if( this._encloseSelectedWordWithKey( key, lidx, cursor ) )
|
|
2385
|
+
if( this._encloseSelectedWordWithKey( key, lidx, cursor ) )
|
|
2342
2386
|
return;
|
|
2343
2387
|
}
|
|
2344
2388
|
|
|
2345
|
-
// Until this point, if there was a selection, we need
|
|
2389
|
+
// Until this point, if there was a selection, we need
|
|
2346
2390
|
// to delete the content..
|
|
2347
2391
|
|
|
2348
2392
|
if( cursor.selection )
|
|
@@ -2359,8 +2403,8 @@ class CodeEditor {
|
|
|
2359
2403
|
if( !sameKeyNext )
|
|
2360
2404
|
{
|
|
2361
2405
|
this.code.lines[ lidx ] = [
|
|
2362
|
-
this.code.lines[ lidx ].slice( 0, cursor.position ),
|
|
2363
|
-
key,
|
|
2406
|
+
this.code.lines[ lidx ].slice( 0, cursor.position ),
|
|
2407
|
+
key,
|
|
2364
2408
|
this.code.lines[ lidx ].slice( cursor.position )
|
|
2365
2409
|
].join('');
|
|
2366
2410
|
}
|
|
@@ -2368,7 +2412,7 @@ class CodeEditor {
|
|
|
2368
2412
|
this.cursorToRight( key, cursor );
|
|
2369
2413
|
|
|
2370
2414
|
// Some custom cases for auto key pair (), {}, "", '', ...
|
|
2371
|
-
|
|
2415
|
+
|
|
2372
2416
|
const keyMustPair = (this.pairKeys[ key ] !== undefined);
|
|
2373
2417
|
if( keyMustPair && !this.wasKeyPaired )
|
|
2374
2418
|
{
|
|
@@ -2429,7 +2473,7 @@ class CodeEditor {
|
|
|
2429
2473
|
text_to_copy = "\n" + this.code.lines[ cursor.line ];
|
|
2430
2474
|
}
|
|
2431
2475
|
else {
|
|
2432
|
-
|
|
2476
|
+
|
|
2433
2477
|
// Some selections don't depend on mouse up..
|
|
2434
2478
|
if( cursor.selection ) cursor.selection.invertIfNecessary();
|
|
2435
2479
|
|
|
@@ -2438,11 +2482,11 @@ class CodeEditor {
|
|
|
2438
2482
|
|
|
2439
2483
|
// Get linear start index
|
|
2440
2484
|
let index = 0;
|
|
2441
|
-
|
|
2485
|
+
|
|
2442
2486
|
for( let i = 0; i <= cursor.selection.fromY; i++ )
|
|
2443
2487
|
index += ( i == cursor.selection.fromY ? cursor.selection.fromX : this.code.lines[ i ].length );
|
|
2444
2488
|
|
|
2445
|
-
index += cursor.selection.fromY * separator.length;
|
|
2489
|
+
index += cursor.selection.fromY * separator.length;
|
|
2446
2490
|
const num_chars = cursor.selection.chars + ( cursor.selection.toY - cursor.selection.fromY ) * separator.length;
|
|
2447
2491
|
const text = code.substr( index, num_chars );
|
|
2448
2492
|
const lines = text.split( separator );
|
|
@@ -2468,7 +2512,7 @@ class CodeEditor {
|
|
|
2468
2512
|
this.lineUp( cursor );
|
|
2469
2513
|
}
|
|
2470
2514
|
else {
|
|
2471
|
-
|
|
2515
|
+
|
|
2472
2516
|
// Some selections don't depend on mouse up..
|
|
2473
2517
|
if( cursor.selection ) cursor.selection.invertIfNecessary();
|
|
2474
2518
|
|
|
@@ -2477,11 +2521,11 @@ class CodeEditor {
|
|
|
2477
2521
|
|
|
2478
2522
|
// Get linear start index
|
|
2479
2523
|
let index = 0;
|
|
2480
|
-
|
|
2524
|
+
|
|
2481
2525
|
for(let i = 0; i <= cursor.selection.fromY; i++)
|
|
2482
2526
|
index += (i == cursor.selection.fromY ? cursor.selection.fromX : this.code.lines[ i ].length);
|
|
2483
2527
|
|
|
2484
|
-
index += cursor.selection.fromY * separator.length;
|
|
2528
|
+
index += cursor.selection.fromY * separator.length;
|
|
2485
2529
|
const num_chars = cursor.selection.chars + (cursor.selection.toY - cursor.selection.fromY) * separator.length;
|
|
2486
2530
|
const text = code.substr(index, num_chars);
|
|
2487
2531
|
const lines = text.split(separator);
|
|
@@ -2494,7 +2538,7 @@ class CodeEditor {
|
|
|
2494
2538
|
}
|
|
2495
2539
|
|
|
2496
2540
|
_duplicateLine( lidx, cursor ) {
|
|
2497
|
-
|
|
2541
|
+
|
|
2498
2542
|
this.endSelection();
|
|
2499
2543
|
this._addUndoStep( cursor, true );
|
|
2500
2544
|
this.code.lines.splice( lidx, 0, this.code.lines[ lidx ] );
|
|
@@ -2651,20 +2695,20 @@ class CodeEditor {
|
|
|
2651
2695
|
}
|
|
2652
2696
|
|
|
2653
2697
|
processLines( mode ) {
|
|
2654
|
-
|
|
2698
|
+
|
|
2655
2699
|
var code_html = "";
|
|
2656
2700
|
this._blockCommentCache.length = 0;
|
|
2657
|
-
|
|
2701
|
+
|
|
2658
2702
|
// Reset all lines content
|
|
2659
2703
|
this.code.innerHTML = "";
|
|
2660
|
-
|
|
2704
|
+
|
|
2661
2705
|
// Get info about lines in viewport
|
|
2662
2706
|
const lastScrollTop = this.getScrollTop();
|
|
2663
|
-
this.firstLineInViewport = ( mode ?? CodeEditor.KEEP_VISIBLE_LINES ) & CodeEditor.UPDATE_VISIBLE_LINES ?
|
|
2707
|
+
this.firstLineInViewport = ( mode ?? CodeEditor.KEEP_VISIBLE_LINES ) & CodeEditor.UPDATE_VISIBLE_LINES ?
|
|
2664
2708
|
( (lastScrollTop / this.lineHeight)|0 ) : this.firstLineInViewport;
|
|
2665
2709
|
const totalLinesInViewport = ((this.codeScroller.offsetHeight - 36) / this.lineHeight)|0;
|
|
2666
|
-
this.visibleLinesViewport = new LX.vec2(
|
|
2667
|
-
Math.max( this.firstLineInViewport - this.lineScrollMargin.x, 0 ),
|
|
2710
|
+
this.visibleLinesViewport = new LX.vec2(
|
|
2711
|
+
Math.max( this.firstLineInViewport - this.lineScrollMargin.x, 0 ),
|
|
2668
2712
|
Math.min( this.firstLineInViewport + totalLinesInViewport + this.lineScrollMargin.y, this.code.lines.length )
|
|
2669
2713
|
);
|
|
2670
2714
|
|
|
@@ -2674,15 +2718,15 @@ class CodeEditor {
|
|
|
2674
2718
|
if( diff <= this.lineScrollMargin.y )
|
|
2675
2719
|
this.visibleLinesViewport.y += diff;
|
|
2676
2720
|
}
|
|
2677
|
-
|
|
2721
|
+
|
|
2678
2722
|
// Process visible lines
|
|
2679
2723
|
for( let i = this.visibleLinesViewport.x; i < this.visibleLinesViewport.y; ++i )
|
|
2680
2724
|
{
|
|
2681
2725
|
code_html += this.processLine( i, true );
|
|
2682
2726
|
}
|
|
2683
|
-
|
|
2727
|
+
|
|
2684
2728
|
this.code.innerHTML = code_html;
|
|
2685
|
-
|
|
2729
|
+
|
|
2686
2730
|
// Update scroll data
|
|
2687
2731
|
this.codeScroller.scrollTop = lastScrollTop;
|
|
2688
2732
|
this.code.style.top = ( this.visibleLinesViewport.x * this.lineHeight ) + "px";
|
|
@@ -2720,10 +2764,10 @@ class CodeEditor {
|
|
|
2720
2764
|
}
|
|
2721
2765
|
|
|
2722
2766
|
// multi-line strings not supported by now
|
|
2723
|
-
delete this._buildingString;
|
|
2767
|
+
delete this._buildingString;
|
|
2724
2768
|
delete this._pendingString;
|
|
2725
2769
|
delete this._markdownHeader;
|
|
2726
|
-
|
|
2770
|
+
|
|
2727
2771
|
let linestring = this.code.lines[ linenum ];
|
|
2728
2772
|
|
|
2729
2773
|
// Single line
|
|
@@ -2758,14 +2802,14 @@ class CodeEditor {
|
|
|
2758
2802
|
it--;
|
|
2759
2803
|
prev = tokensToEvaluate[ it ];
|
|
2760
2804
|
}
|
|
2761
|
-
|
|
2805
|
+
|
|
2762
2806
|
it = i + 1;
|
|
2763
2807
|
let next = tokensToEvaluate[ it ];
|
|
2764
2808
|
while( next == ' ' || next == '"' ) {
|
|
2765
2809
|
it++;
|
|
2766
2810
|
next = tokensToEvaluate[ it ];
|
|
2767
2811
|
}
|
|
2768
|
-
|
|
2812
|
+
|
|
2769
2813
|
const token = tokensToEvaluate[ i ];
|
|
2770
2814
|
|
|
2771
2815
|
if( lang.blockComments ?? true )
|
|
@@ -2783,7 +2827,8 @@ class CodeEditor {
|
|
|
2783
2827
|
nextWithSpaces: tokensToEvaluate[ i + 1 ],
|
|
2784
2828
|
tokenIndex: i,
|
|
2785
2829
|
isFirstToken: (i == 0),
|
|
2786
|
-
isLastToken: (i == tokensToEvaluate.length - 1)
|
|
2830
|
+
isLastToken: (i == tokensToEvaluate.length - 1),
|
|
2831
|
+
tokens: tokensToEvaluate
|
|
2787
2832
|
} );
|
|
2788
2833
|
}
|
|
2789
2834
|
|
|
@@ -2805,10 +2850,10 @@ class CodeEditor {
|
|
|
2805
2850
|
const stringKeys = Object.values( this.stringKeys );
|
|
2806
2851
|
// Count times we started a string BEFORE the comment
|
|
2807
2852
|
var err = false;
|
|
2808
|
-
err |= stringKeys.some( function(v) {
|
|
2809
|
-
var re = new RegExp( v, "g" );
|
|
2853
|
+
err |= stringKeys.some( function(v) {
|
|
2854
|
+
var re = new RegExp( v, "g" );
|
|
2810
2855
|
var matches = (linestring.substring( 0, idx ).match( re ) || []);
|
|
2811
|
-
return (matches.length % 2) !== 0;
|
|
2856
|
+
return (matches.length % 2) !== 0;
|
|
2812
2857
|
} );
|
|
2813
2858
|
return err ? undefined : idx;
|
|
2814
2859
|
}
|
|
@@ -2891,9 +2936,21 @@ class CodeEditor {
|
|
|
2891
2936
|
return tokens;
|
|
2892
2937
|
}
|
|
2893
2938
|
|
|
2894
|
-
_mustHightlightWord( token, kindArray ) {
|
|
2939
|
+
_mustHightlightWord( token, kindArray, lang ) {
|
|
2940
|
+
|
|
2941
|
+
if( !lang )
|
|
2942
|
+
{
|
|
2943
|
+
lang = this.languages[ this.highlight ];
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
let t = token;
|
|
2947
|
+
|
|
2948
|
+
if( lang.ignoreCase )
|
|
2949
|
+
{
|
|
2950
|
+
t = t.toLowerCase();
|
|
2951
|
+
}
|
|
2895
2952
|
|
|
2896
|
-
return kindArray[this.highlight] && kindArray[this.highlight][
|
|
2953
|
+
return kindArray[ this.highlight ] && kindArray[ this.highlight ][ t ] != undefined;
|
|
2897
2954
|
}
|
|
2898
2955
|
|
|
2899
2956
|
_evaluateToken( ctxData ) {
|
|
@@ -2911,10 +2968,10 @@ class CodeEditor {
|
|
|
2911
2968
|
|
|
2912
2969
|
var usePreviousTokenToCheckString = false;
|
|
2913
2970
|
|
|
2914
|
-
if(
|
|
2971
|
+
if( [ 'cpp', 'c' ].indexOf( highlight ) > -1 && prev && prev.includes( '#' ) ) // preprocessor code..
|
|
2915
2972
|
{
|
|
2916
2973
|
customStringKeys['@<'] = '>';
|
|
2917
|
-
}
|
|
2974
|
+
}
|
|
2918
2975
|
else if( highlight == 'markdown' && ( ctxData.prevWithSpaces == '[' || ctxData.nextWithSpaces == ']' ) )
|
|
2919
2976
|
{
|
|
2920
2977
|
// console.warn(prev, token, next)
|
|
@@ -2935,43 +2992,43 @@ class CodeEditor {
|
|
|
2935
2992
|
if( this._buildingString != undefined )
|
|
2936
2993
|
{
|
|
2937
2994
|
checkIfStringEnded( usePreviousTokenToCheckString ? ctxData.nextWithSpaces : token );
|
|
2938
|
-
}
|
|
2995
|
+
}
|
|
2939
2996
|
else if( customStringKeys[ '@' + ( usePreviousTokenToCheckString ? ctxData.prevWithSpaces : token ) ] )
|
|
2940
|
-
{
|
|
2997
|
+
{
|
|
2941
2998
|
// Start new string
|
|
2942
2999
|
this._buildingString = ( usePreviousTokenToCheckString ? ctxData.prevWithSpaces : token );
|
|
2943
3000
|
|
|
2944
3001
|
// Check if string ended in same token using next...
|
|
2945
|
-
if( usePreviousTokenToCheckString )
|
|
3002
|
+
if( usePreviousTokenToCheckString )
|
|
2946
3003
|
{
|
|
2947
3004
|
checkIfStringEnded( ctxData.nextWithSpaces );
|
|
2948
3005
|
}
|
|
2949
3006
|
}
|
|
2950
3007
|
}
|
|
2951
|
-
|
|
3008
|
+
|
|
2952
3009
|
const usesBlockComments = lang.blockComments ?? true;
|
|
2953
3010
|
const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
|
|
2954
3011
|
const singleLineCommentToken = lang.singleLineCommentToken ?? this.defaultSingleLineCommentToken;
|
|
2955
|
-
|
|
3012
|
+
|
|
2956
3013
|
let token_classname = "";
|
|
2957
3014
|
let discardToken = false;
|
|
2958
3015
|
|
|
2959
3016
|
if( this._buildingBlockComment != undefined )
|
|
2960
3017
|
token_classname = "cm-com";
|
|
2961
|
-
|
|
3018
|
+
|
|
2962
3019
|
else if( this._buildingString != undefined )
|
|
2963
3020
|
discardToken = this._appendStringToken( token );
|
|
2964
|
-
|
|
2965
|
-
else if(
|
|
3021
|
+
|
|
3022
|
+
else if( this._isKeyword( ctxData, lang ) )
|
|
2966
3023
|
token_classname = "cm-kwd";
|
|
2967
3024
|
|
|
2968
|
-
else if( this._mustHightlightWord( token, CodeEditor.
|
|
3025
|
+
else if( this._mustHightlightWord( token, CodeEditor.builtIn, lang ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
2969
3026
|
token_classname = "cm-bln";
|
|
2970
3027
|
|
|
2971
|
-
else if( this._mustHightlightWord( token, CodeEditor.statementsAndDeclarations ) )
|
|
3028
|
+
else if( this._mustHightlightWord( token, CodeEditor.statementsAndDeclarations, lang ) )
|
|
2972
3029
|
token_classname = "cm-std";
|
|
2973
3030
|
|
|
2974
|
-
else if( this._mustHightlightWord( token, CodeEditor.symbols ) )
|
|
3031
|
+
else if( this._mustHightlightWord( token, CodeEditor.symbols, lang ) )
|
|
2975
3032
|
token_classname = "cm-sym";
|
|
2976
3033
|
|
|
2977
3034
|
else if( token.substr( 0, singleLineCommentToken.length ) == singleLineCommentToken )
|
|
@@ -2980,16 +3037,16 @@ class CodeEditor {
|
|
|
2980
3037
|
else if( this._isNumber( token ) || this._isNumber( token.replace(/[px]|[em]|%/g,'') ) )
|
|
2981
3038
|
token_classname = "cm-dec";
|
|
2982
3039
|
|
|
2983
|
-
else if( this._isCSSClass(
|
|
3040
|
+
else if( this._isCSSClass( ctxData ) )
|
|
2984
3041
|
token_classname = "cm-kwd";
|
|
2985
3042
|
|
|
2986
|
-
else if ( this._isType(
|
|
3043
|
+
else if ( this._isType( ctxData, lang ) )
|
|
2987
3044
|
token_classname = "cm-typ";
|
|
2988
3045
|
|
|
2989
3046
|
else if ( highlight == 'batch' && ( token == '@' || prev == ':' || prev == '@' ) )
|
|
2990
3047
|
token_classname = "cm-kwd";
|
|
2991
3048
|
|
|
2992
|
-
else if ( [ 'cpp', 'wgsl', 'glsl' ].indexOf( highlight ) > -1 && token.includes( '#' ) ) // C++ preprocessor
|
|
3049
|
+
else if ( [ 'cpp', 'c', 'wgsl', 'glsl' ].indexOf( highlight ) > -1 && token.includes( '#' ) ) // C++ preprocessor
|
|
2993
3050
|
token_classname = "cm-ppc";
|
|
2994
3051
|
|
|
2995
3052
|
else if ( highlight == 'cpp' && prev == '<' && (next == '>' || next == '*') ) // Defining template type in C++
|
|
@@ -3003,7 +3060,7 @@ class CodeEditor {
|
|
|
3003
3060
|
|
|
3004
3061
|
else if ( highlight == 'css' && prev == undefined && next == ':' ) // CSS attribute
|
|
3005
3062
|
token_classname = "cm-typ";
|
|
3006
|
-
|
|
3063
|
+
|
|
3007
3064
|
else if ( this._markdownHeader || ( highlight == 'markdown' && isFirstToken && token.replaceAll('#', '').length != token.length ) ) // Header
|
|
3008
3065
|
{
|
|
3009
3066
|
token_classname = "cm-kwd";
|
|
@@ -3014,7 +3071,7 @@ class CodeEditor {
|
|
|
3014
3071
|
token_classname = "cm-mtd";
|
|
3015
3072
|
|
|
3016
3073
|
|
|
3017
|
-
if( usesBlockComments && this._buildingBlockComment != undefined
|
|
3074
|
+
if( usesBlockComments && this._buildingBlockComment != undefined
|
|
3018
3075
|
&& token.substr( 0, blockCommentsTokens[ 1 ].length ) == blockCommentsTokens[ 1 ] )
|
|
3019
3076
|
{
|
|
3020
3077
|
this._blockCommentCache.push( new LX.vec2( this._buildingBlockComment, this._currentLineNumber ) );
|
|
@@ -3033,14 +3090,18 @@ class CodeEditor {
|
|
|
3033
3090
|
this._buildingString = this._stringEnded ? undefined : this._buildingString;
|
|
3034
3091
|
|
|
3035
3092
|
if( discardToken )
|
|
3093
|
+
{
|
|
3036
3094
|
return "";
|
|
3095
|
+
}
|
|
3037
3096
|
|
|
3038
3097
|
token = token.replace( "<", "<" );
|
|
3039
3098
|
token = token.replace( ">", ">" );
|
|
3040
3099
|
|
|
3041
3100
|
// No highlighting, no need to put it inside another span..
|
|
3042
3101
|
if( !token_classname.length )
|
|
3102
|
+
{
|
|
3043
3103
|
return token;
|
|
3104
|
+
}
|
|
3044
3105
|
|
|
3045
3106
|
return "<span class='" + highlight + " " + token_classname + "'>" + token + "</span>";
|
|
3046
3107
|
}
|
|
@@ -3075,7 +3136,10 @@ class CodeEditor {
|
|
|
3075
3136
|
if( tagEndIndex < 0 ) // Not found..
|
|
3076
3137
|
return;
|
|
3077
3138
|
|
|
3078
|
-
|
|
3139
|
+
if( ( tagStartIndex < tokenStartIndex ) && ( tagEndIndex >= ( tokenStartIndex + token.length ) ) && !this._mustHightlightWord( token, CodeEditor.symbols ) )
|
|
3140
|
+
{
|
|
3141
|
+
return [ tagStartIndex, tagEndIndex ];
|
|
3142
|
+
}
|
|
3079
3143
|
}
|
|
3080
3144
|
|
|
3081
3145
|
_inBlockCommentSection( line ) {
|
|
@@ -3083,52 +3147,104 @@ class CodeEditor {
|
|
|
3083
3147
|
for( var section of this._blockCommentCache )
|
|
3084
3148
|
{
|
|
3085
3149
|
if( line >= section.x && line <= section.y )
|
|
3150
|
+
{
|
|
3086
3151
|
return true;
|
|
3152
|
+
}
|
|
3087
3153
|
}
|
|
3088
3154
|
|
|
3089
3155
|
return false;
|
|
3090
3156
|
}
|
|
3091
3157
|
|
|
3092
|
-
|
|
3158
|
+
_isKeyword( ctxData, lang ) {
|
|
3159
|
+
|
|
3160
|
+
const token = ctxData.token;
|
|
3161
|
+
const tokenIndex = ctxData.tokenIndex;
|
|
3162
|
+
const tokens = ctxData.tokens;
|
|
3163
|
+
|
|
3164
|
+
let isKwd = this._mustHightlightWord( token, CodeEditor.keywords ) || this.highlight == 'XML';
|
|
3165
|
+
|
|
3166
|
+
if( this.highlight == 'CMake' )
|
|
3167
|
+
{
|
|
3168
|
+
// Highlight $ symbol
|
|
3169
|
+
if( token == '$' && this._enclosedByTokens( tokens[ tokenIndex + 2 ], tokenIndex + 2, '{', '}' ) )
|
|
3170
|
+
{
|
|
3171
|
+
isKwd = true;
|
|
3172
|
+
}
|
|
3173
|
+
// Highlight what is between the { }
|
|
3174
|
+
else if( this._enclosedByTokens( token, tokenIndex, '{', '}' ) )
|
|
3175
|
+
{
|
|
3176
|
+
isKwd |= ( ctxData.tokens[ tokenIndex - 2 ] == '$' );
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
else if( lang.tags )
|
|
3180
|
+
{
|
|
3181
|
+
isKwd &= ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) != undefined );
|
|
3182
|
+
}
|
|
3183
|
+
|
|
3184
|
+
|
|
3185
|
+
return isKwd;
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
_isCSSClass( ctxData ) {
|
|
3189
|
+
|
|
3190
|
+
const token = ctxData.token;
|
|
3191
|
+
const prev = ctxData.prev;
|
|
3192
|
+
const next = ctxData.next;
|
|
3093
3193
|
|
|
3094
3194
|
if( this.highlight != 'CSS' )
|
|
3195
|
+
{
|
|
3095
3196
|
return false;
|
|
3197
|
+
}
|
|
3096
3198
|
|
|
3097
|
-
return ( prev == '.' || prev == '::'
|
|
3098
|
-
|| ( prev == ':' && next == '{' )
|
|
3199
|
+
return ( prev == '.' || prev == '::'
|
|
3200
|
+
|| ( prev == ':' && next == '{' )
|
|
3099
3201
|
|| ( token[ 0 ] == '#' && prev != ':' ) );
|
|
3100
3202
|
}
|
|
3101
3203
|
|
|
3102
3204
|
_isNumber( token ) {
|
|
3103
3205
|
|
|
3104
|
-
|
|
3206
|
+
const subToken = token.substring( 0, token.length - 1 );
|
|
3207
|
+
|
|
3208
|
+
if( this.highlight == 'C++' )
|
|
3105
3209
|
{
|
|
3106
3210
|
if( token.lastChar == 'f' )
|
|
3107
|
-
|
|
3211
|
+
{
|
|
3212
|
+
return this._isNumber( subToken )
|
|
3213
|
+
}
|
|
3108
3214
|
else if( token.lastChar == 'u' )
|
|
3109
|
-
|
|
3215
|
+
{
|
|
3216
|
+
return !(token.includes('.')) && this._isNumber( subToken );
|
|
3217
|
+
}
|
|
3110
3218
|
}
|
|
3111
|
-
|
|
3112
|
-
else if(this.highlight == 'WGSL')
|
|
3219
|
+
else if( this.highlight == 'WGSL' )
|
|
3113
3220
|
{
|
|
3114
3221
|
if( token.lastChar == 'u' )
|
|
3115
|
-
|
|
3222
|
+
{
|
|
3223
|
+
return !(token.includes('.')) && this._isNumber( subToken );
|
|
3224
|
+
}
|
|
3116
3225
|
}
|
|
3117
|
-
|
|
3118
|
-
else if(this.highlight == 'CSS')
|
|
3226
|
+
else if( this.highlight == 'CSS' )
|
|
3119
3227
|
{
|
|
3120
3228
|
if( token.lastChar == '%' )
|
|
3121
|
-
|
|
3229
|
+
{
|
|
3230
|
+
return this._isNumber( subToken )
|
|
3231
|
+
}
|
|
3122
3232
|
}
|
|
3123
|
-
|
|
3124
|
-
return token.length && token != ' ' && !Number.isNaN(+token);
|
|
3233
|
+
|
|
3234
|
+
return token.length && token != ' ' && !Number.isNaN( +token );
|
|
3125
3235
|
}
|
|
3126
3236
|
|
|
3127
|
-
_isType(
|
|
3128
|
-
|
|
3237
|
+
_isType( ctxData, lang ) {
|
|
3238
|
+
|
|
3239
|
+
const token = ctxData.token;
|
|
3240
|
+
const prev = ctxData.prev;
|
|
3241
|
+
const next = ctxData.next;
|
|
3242
|
+
|
|
3129
3243
|
// Common case
|
|
3130
|
-
if( this._mustHightlightWord( token, CodeEditor.types ) )
|
|
3244
|
+
if( this._mustHightlightWord( token, CodeEditor.types, lang ) )
|
|
3245
|
+
{
|
|
3131
3246
|
return true;
|
|
3247
|
+
}
|
|
3132
3248
|
|
|
3133
3249
|
if( this.highlight == 'JavaScript' )
|
|
3134
3250
|
{
|
|
@@ -3140,11 +3256,11 @@ class CodeEditor {
|
|
|
3140
3256
|
}
|
|
3141
3257
|
else if ( this.highlight == 'WGSL' )
|
|
3142
3258
|
{
|
|
3143
|
-
const not_kwd = !this._mustHightlightWord( token, CodeEditor.keywords );
|
|
3144
|
-
return (prev == 'struct' && next == '{') ||
|
|
3145
|
-
(not_kwd && prev == ':' && next == ';') ||
|
|
3146
|
-
( not_kwd &&
|
|
3147
|
-
( prev == ':' && next == ')' || prev == ':' && next == ',' || prev == '>' && next == '{'
|
|
3259
|
+
const not_kwd = !this._mustHightlightWord( token, CodeEditor.keywords, lang );
|
|
3260
|
+
return (prev == 'struct' && next == '{') ||
|
|
3261
|
+
(not_kwd && prev == ':' && next == ';') ||
|
|
3262
|
+
( not_kwd &&
|
|
3263
|
+
( prev == ':' && next == ')' || prev == ':' && next == ',' || prev == '>' && next == '{'
|
|
3148
3264
|
|| prev == '<' && next == ',' || prev == '<' && next == '>' || prev == '>' && token != ';' && !next ));
|
|
3149
3265
|
}
|
|
3150
3266
|
}
|
|
@@ -3153,13 +3269,13 @@ class CodeEditor {
|
|
|
3153
3269
|
|
|
3154
3270
|
if( !cursor.selection || (cursor.selection.fromY != cursor.selection.toY) )
|
|
3155
3271
|
return false;
|
|
3156
|
-
|
|
3272
|
+
|
|
3157
3273
|
cursor.selection.invertIfNecessary();
|
|
3158
3274
|
|
|
3159
3275
|
// Insert first..
|
|
3160
3276
|
this.code.lines[ lidx ] = [
|
|
3161
|
-
this.code.lines[ lidx ].slice(0, cursor.selection.fromX),
|
|
3162
|
-
key,
|
|
3277
|
+
this.code.lines[ lidx ].slice(0, cursor.selection.fromX),
|
|
3278
|
+
key,
|
|
3163
3279
|
this.code.lines[ lidx ].slice(cursor.selection.fromX)
|
|
3164
3280
|
].join('');
|
|
3165
3281
|
|
|
@@ -3178,14 +3294,14 @@ class CodeEditor {
|
|
|
3178
3294
|
|
|
3179
3295
|
// Insert the other
|
|
3180
3296
|
this.code.lines[ lidx ] = [
|
|
3181
|
-
this.code.lines[ lidx ].slice(0, cursor.position),
|
|
3182
|
-
key,
|
|
3297
|
+
this.code.lines[ lidx ].slice(0, cursor.position),
|
|
3298
|
+
key,
|
|
3183
3299
|
this.code.lines[ lidx ].slice(cursor.position)
|
|
3184
3300
|
].join('');
|
|
3185
3301
|
|
|
3186
3302
|
// Recompute and reposition current selection
|
|
3187
|
-
|
|
3188
|
-
cursor.selection.fromX++;
|
|
3303
|
+
|
|
3304
|
+
cursor.selection.fromX++;
|
|
3189
3305
|
cursor.selection.toX++;
|
|
3190
3306
|
|
|
3191
3307
|
this._processSelection( cursor );
|
|
@@ -3197,7 +3313,7 @@ class CodeEditor {
|
|
|
3197
3313
|
|
|
3198
3314
|
lineUp( cursor, resetLeft ) {
|
|
3199
3315
|
|
|
3200
|
-
if( this.code.lines[ cursor.line - 1 ] == undefined )
|
|
3316
|
+
if( this.code.lines[ cursor.line - 1 ] == undefined )
|
|
3201
3317
|
return false;
|
|
3202
3318
|
|
|
3203
3319
|
cursor.line--;
|
|
@@ -3208,10 +3324,10 @@ class CodeEditor {
|
|
|
3208
3324
|
}
|
|
3209
3325
|
|
|
3210
3326
|
lineDown( cursor, resetLeft ) {
|
|
3211
|
-
|
|
3212
|
-
if( this.code.lines[ cursor.line + 1 ] == undefined )
|
|
3327
|
+
|
|
3328
|
+
if( this.code.lines[ cursor.line + 1 ] == undefined )
|
|
3213
3329
|
return false;
|
|
3214
|
-
|
|
3330
|
+
|
|
3215
3331
|
cursor.line++;
|
|
3216
3332
|
|
|
3217
3333
|
this.cursorToBottom( cursor, resetLeft );
|
|
@@ -3250,8 +3366,8 @@ class CodeEditor {
|
|
|
3250
3366
|
|
|
3251
3367
|
deleteSelection( cursor ) {
|
|
3252
3368
|
|
|
3253
|
-
// I think it's not necessary but...
|
|
3254
|
-
if( this.disableEdition )
|
|
3369
|
+
// I think it's not necessary but...
|
|
3370
|
+
if( this.disableEdition )
|
|
3255
3371
|
return;
|
|
3256
3372
|
|
|
3257
3373
|
// Some selections don't depend on mouse up..
|
|
@@ -3265,14 +3381,14 @@ class CodeEditor {
|
|
|
3265
3381
|
for( let i = 0; i <= cursor.selection.fromY; i++ )
|
|
3266
3382
|
index += (i == cursor.selection.fromY ? cursor.selection.fromX : this.code.lines[ i ].length);
|
|
3267
3383
|
|
|
3268
|
-
index += cursor.selection.fromY * separator.length;
|
|
3384
|
+
index += cursor.selection.fromY * separator.length;
|
|
3269
3385
|
|
|
3270
3386
|
const num_chars = cursor.selection.chars + (cursor.selection.toY - cursor.selection.fromY) * separator.length;
|
|
3271
3387
|
const pre = code.slice( 0, index );
|
|
3272
3388
|
const post = code.slice( index + num_chars );
|
|
3273
3389
|
|
|
3274
3390
|
this.code.lines = ( pre + post ).split( separator );
|
|
3275
|
-
|
|
3391
|
+
|
|
3276
3392
|
this.cursorToLine( cursor, cursor.selection.fromY, true );
|
|
3277
3393
|
this.cursorToPosition( cursor, cursor.selection.fromX );
|
|
3278
3394
|
this.endSelection( cursor );
|
|
@@ -3370,7 +3486,7 @@ class CodeEditor {
|
|
|
3370
3486
|
cursor._top = Math.max(cursor._top, 0);
|
|
3371
3487
|
cursor.style.top = "calc(" + cursor._top + "px)";
|
|
3372
3488
|
this.restartBlink();
|
|
3373
|
-
|
|
3489
|
+
|
|
3374
3490
|
if( resetLeft )
|
|
3375
3491
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT, cursor );
|
|
3376
3492
|
|
|
@@ -3400,10 +3516,10 @@ class CodeEditor {
|
|
|
3400
3516
|
|
|
3401
3517
|
cursorToString( cursor, text, reverse ) {
|
|
3402
3518
|
|
|
3403
|
-
if( !text.length )
|
|
3519
|
+
if( !text.length )
|
|
3404
3520
|
return;
|
|
3405
3521
|
|
|
3406
|
-
for( let char of text )
|
|
3522
|
+
for( let char of text )
|
|
3407
3523
|
reverse ? this.cursorToLeft( char, cursor ) : this.cursorToRight( char, cursor );
|
|
3408
3524
|
}
|
|
3409
3525
|
|
|
@@ -3491,7 +3607,7 @@ class CodeEditor {
|
|
|
3491
3607
|
}
|
|
3492
3608
|
|
|
3493
3609
|
resetCursorPos( flag, cursor ) {
|
|
3494
|
-
|
|
3610
|
+
|
|
3495
3611
|
cursor = cursor ?? this._getCurrentCursor();
|
|
3496
3612
|
|
|
3497
3613
|
if( flag & CodeEditor.CURSOR_LEFT )
|
|
@@ -3510,14 +3626,14 @@ class CodeEditor {
|
|
|
3510
3626
|
}
|
|
3511
3627
|
|
|
3512
3628
|
_addSpaceTabs( cursor, n ) {
|
|
3513
|
-
|
|
3629
|
+
|
|
3514
3630
|
for( var i = 0; i < n; ++i ) {
|
|
3515
3631
|
this.actions[ 'Tab' ].callback( cursor.line, cursor, null );
|
|
3516
3632
|
}
|
|
3517
3633
|
}
|
|
3518
3634
|
|
|
3519
3635
|
_addSpaces( n ) {
|
|
3520
|
-
|
|
3636
|
+
|
|
3521
3637
|
for( var i = 0; i < n; ++i ) {
|
|
3522
3638
|
this.root.dispatchEvent( new CustomEvent( 'keydown', { 'detail': {
|
|
3523
3639
|
skip_undo: true,
|
|
@@ -3564,33 +3680,33 @@ class CodeEditor {
|
|
|
3564
3680
|
}
|
|
3565
3681
|
|
|
3566
3682
|
getScrollLeft() {
|
|
3567
|
-
|
|
3683
|
+
|
|
3568
3684
|
if( !this.codeScroller ) return 0;
|
|
3569
3685
|
return this.codeScroller.scrollLeft;
|
|
3570
3686
|
}
|
|
3571
3687
|
|
|
3572
3688
|
getScrollTop() {
|
|
3573
|
-
|
|
3689
|
+
|
|
3574
3690
|
if( !this.codeScroller ) return 0;
|
|
3575
3691
|
return this.codeScroller.scrollTop;
|
|
3576
3692
|
}
|
|
3577
3693
|
|
|
3578
3694
|
setScrollLeft( value ) {
|
|
3579
|
-
|
|
3695
|
+
|
|
3580
3696
|
if( !this.codeScroller ) return;
|
|
3581
3697
|
this.codeScroller.scrollLeft = value;
|
|
3582
3698
|
this.setScrollBarValue( 'horizontal', 0 );
|
|
3583
3699
|
}
|
|
3584
3700
|
|
|
3585
3701
|
setScrollTop( value ) {
|
|
3586
|
-
|
|
3702
|
+
|
|
3587
3703
|
if( !this.codeScroller ) return;
|
|
3588
3704
|
this.codeScroller.scrollTop = value;
|
|
3589
3705
|
this.setScrollBarValue( 'vertical' );
|
|
3590
3706
|
}
|
|
3591
3707
|
|
|
3592
3708
|
resize( pMaxLength ) {
|
|
3593
|
-
|
|
3709
|
+
|
|
3594
3710
|
setTimeout( () => {
|
|
3595
3711
|
|
|
3596
3712
|
// Update max viewport
|
|
@@ -3648,7 +3764,7 @@ class CodeEditor {
|
|
|
3648
3764
|
{
|
|
3649
3765
|
const scrollBarHeight = this.vScrollbar.thumb.parentElement.offsetHeight;
|
|
3650
3766
|
const scrollThumbHeight = this.vScrollbar.thumb.offsetHeight;
|
|
3651
|
-
|
|
3767
|
+
|
|
3652
3768
|
const scrollHeight = this.codeScroller.scrollHeight - this.codeScroller.clientHeight;
|
|
3653
3769
|
const currentScroll = this.codeScroller.scrollTop;
|
|
3654
3770
|
|
|
@@ -3687,13 +3803,13 @@ class CodeEditor {
|
|
|
3687
3803
|
const scrollWidth = this.codeScroller.scrollWidth - this.codeScroller.clientWidth;
|
|
3688
3804
|
const currentScroll = (this.hScrollbar.thumb._left * scrollWidth) / ( scrollBarWidth - scrollThumbWidth );
|
|
3689
3805
|
this.codeScroller.scrollLeft = currentScroll;
|
|
3690
|
-
|
|
3806
|
+
|
|
3691
3807
|
|
|
3692
3808
|
this._discardScroll = true;
|
|
3693
3809
|
}
|
|
3694
3810
|
|
|
3695
3811
|
updateVerticalScrollFromScrollBar( value ) {
|
|
3696
|
-
|
|
3812
|
+
|
|
3697
3813
|
value = this.vScrollbar.thumb._top - value;
|
|
3698
3814
|
|
|
3699
3815
|
// Move scrollbar thumb
|
|
@@ -3712,12 +3828,12 @@ class CodeEditor {
|
|
|
3712
3828
|
}
|
|
3713
3829
|
|
|
3714
3830
|
getCharAtPos( cursor, offset = 0 ) {
|
|
3715
|
-
|
|
3831
|
+
|
|
3716
3832
|
return this.code.lines[ cursor.line ][ cursor.position + offset ];
|
|
3717
3833
|
}
|
|
3718
3834
|
|
|
3719
3835
|
getWordAtPos( cursor, offset = 0 ) {
|
|
3720
|
-
|
|
3836
|
+
|
|
3721
3837
|
const col = cursor.line;
|
|
3722
3838
|
const words = this.code.lines[ col ];
|
|
3723
3839
|
|
|
@@ -3761,13 +3877,13 @@ class CodeEditor {
|
|
|
3761
3877
|
from--;
|
|
3762
3878
|
word = words.substring( from, to );
|
|
3763
3879
|
}
|
|
3764
|
-
}
|
|
3765
|
-
|
|
3880
|
+
}
|
|
3881
|
+
|
|
3766
3882
|
return [ word, from, to ];
|
|
3767
3883
|
}
|
|
3768
3884
|
|
|
3769
3885
|
_measureChar( char = "a", use_floating = false, get_bb = false ) {
|
|
3770
|
-
|
|
3886
|
+
|
|
3771
3887
|
var line = document.createElement( "pre" );
|
|
3772
3888
|
var text = document.createElement( "span" );
|
|
3773
3889
|
line.appendChild( text );
|
|
@@ -3831,7 +3947,7 @@ class CodeEditor {
|
|
|
3831
3947
|
}
|
|
3832
3948
|
|
|
3833
3949
|
showAutoCompleteBox( key, cursor ) {
|
|
3834
|
-
|
|
3950
|
+
|
|
3835
3951
|
if( !cursor.isMain )
|
|
3836
3952
|
return;
|
|
3837
3953
|
|
|
@@ -3846,8 +3962,8 @@ class CodeEditor {
|
|
|
3846
3962
|
let suggestions = [];
|
|
3847
3963
|
|
|
3848
3964
|
// Add language special keys...
|
|
3849
|
-
suggestions = suggestions.concat(
|
|
3850
|
-
Object.keys( CodeEditor.
|
|
3965
|
+
suggestions = suggestions.concat(
|
|
3966
|
+
Object.keys( CodeEditor.builtIn[ this.highlight ] ?? {} ),
|
|
3851
3967
|
Object.keys( CodeEditor.keywords[ this.highlight ] ?? {} ),
|
|
3852
3968
|
Object.keys( CodeEditor.statementsAndDeclarations[ this.highlight ] ?? {} ),
|
|
3853
3969
|
Object.keys( CodeEditor.types[ this.highlight ] ?? {} ),
|
|
@@ -3857,7 +3973,7 @@ class CodeEditor {
|
|
|
3857
3973
|
// Add words in current tab plus remove current word
|
|
3858
3974
|
// suggestions = suggestions.concat( Object.keys(this.code.tokens).filter( a => a != word ) );
|
|
3859
3975
|
|
|
3860
|
-
// Remove 1/2 char words and duplicates...
|
|
3976
|
+
// Remove 1/2 char words and duplicates...
|
|
3861
3977
|
suggestions = suggestions.filter( (value, index) => value.length > 2 && suggestions.indexOf(value) === index );
|
|
3862
3978
|
|
|
3863
3979
|
// Order...
|
|
@@ -3872,7 +3988,7 @@ class CodeEditor {
|
|
|
3872
3988
|
this.autocomplete.appendChild( pre );
|
|
3873
3989
|
|
|
3874
3990
|
var icon = document.createElement( 'a' );
|
|
3875
|
-
|
|
3991
|
+
|
|
3876
3992
|
if( this._mustHightlightWord( s, CodeEditor.utils ) )
|
|
3877
3993
|
icon.className = "fa fa-cube";
|
|
3878
3994
|
else if( this._mustHightlightWord( s, CodeEditor.types ) )
|
|
@@ -3884,7 +4000,7 @@ class CodeEditor {
|
|
|
3884
4000
|
|
|
3885
4001
|
pre.addEventListener( 'click', () => {
|
|
3886
4002
|
this.autoCompleteWord( s );
|
|
3887
|
-
} );
|
|
4003
|
+
} );
|
|
3888
4004
|
|
|
3889
4005
|
// Highlight the written part
|
|
3890
4006
|
const index = s.toLowerCase().indexOf( word.toLowerCase() );
|
|
@@ -3930,7 +4046,7 @@ class CodeEditor {
|
|
|
3930
4046
|
}
|
|
3931
4047
|
|
|
3932
4048
|
autoCompleteWord( suggestion ) {
|
|
3933
|
-
|
|
4049
|
+
|
|
3934
4050
|
if( !this.isAutoCompleteActive )
|
|
3935
4051
|
return;
|
|
3936
4052
|
|
|
@@ -3957,7 +4073,7 @@ class CodeEditor {
|
|
|
3957
4073
|
}
|
|
3958
4074
|
|
|
3959
4075
|
_getSelectedAutoComplete() {
|
|
3960
|
-
|
|
4076
|
+
|
|
3961
4077
|
if( !this.isAutoCompleteActive )
|
|
3962
4078
|
return;
|
|
3963
4079
|
|
|
@@ -3997,7 +4113,7 @@ class CodeEditor {
|
|
|
3997
4113
|
}
|
|
3998
4114
|
|
|
3999
4115
|
showSearchBox( clear ) {
|
|
4000
|
-
|
|
4116
|
+
|
|
4001
4117
|
this.hideSearchLineBox();
|
|
4002
4118
|
|
|
4003
4119
|
this.searchbox.classList.add( 'opened' );
|
|
@@ -4066,7 +4182,7 @@ class CodeEditor {
|
|
|
4066
4182
|
}
|
|
4067
4183
|
|
|
4068
4184
|
const getIndex = l => {
|
|
4069
|
-
|
|
4185
|
+
|
|
4070
4186
|
var string = this.code.lines[ l ];
|
|
4071
4187
|
|
|
4072
4188
|
if( reverse )
|
|
@@ -4120,10 +4236,10 @@ class CodeEditor {
|
|
|
4120
4236
|
};
|
|
4121
4237
|
return;
|
|
4122
4238
|
}
|
|
4123
|
-
|
|
4239
|
+
|
|
4124
4240
|
/*
|
|
4125
4241
|
Position idx is computed from last pos, which could be in same line,
|
|
4126
|
-
so we search in the substring (first_ocurrence, end). That's why we
|
|
4242
|
+
so we search in the substring (first_ocurrence, end). That's why we
|
|
4127
4243
|
have to add the length of the substring (0, first_ocurrence)
|
|
4128
4244
|
*/
|
|
4129
4245
|
|
|
@@ -4136,9 +4252,9 @@ class CodeEditor {
|
|
|
4136
4252
|
|
|
4137
4253
|
this._lastTextFound = text;
|
|
4138
4254
|
|
|
4139
|
-
this.codeScroller.scrollTo(
|
|
4140
|
-
Math.max( char * this.charWidth - this.codeScroller.clientWidth, 0 ),
|
|
4141
|
-
Math.max( line - 10, 0 ) * this.lineHeight
|
|
4255
|
+
this.codeScroller.scrollTo(
|
|
4256
|
+
Math.max( char * this.charWidth - this.codeScroller.clientWidth, 0 ),
|
|
4257
|
+
Math.max( line - 10, 0 ) * this.lineHeight
|
|
4142
4258
|
);
|
|
4143
4259
|
|
|
4144
4260
|
if( callback )
|
|
@@ -4162,7 +4278,7 @@ class CodeEditor {
|
|
|
4162
4278
|
}
|
|
4163
4279
|
|
|
4164
4280
|
showSearchLineBox() {
|
|
4165
|
-
|
|
4281
|
+
|
|
4166
4282
|
this.hideSearchBox();
|
|
4167
4283
|
|
|
4168
4284
|
this.searchlinebox.classList.add( 'opened' );
|
|
@@ -4326,7 +4442,7 @@ class CodeEditor {
|
|
|
4326
4442
|
|
|
4327
4443
|
delete this._currentLineString;
|
|
4328
4444
|
delete this._currentLineNumber;
|
|
4329
|
-
delete this._buildingString;
|
|
4445
|
+
delete this._buildingString;
|
|
4330
4446
|
delete this._pendingString;
|
|
4331
4447
|
delete this._buildingBlockComment;
|
|
4332
4448
|
delete this._markdownHeader;
|
|
@@ -4338,8 +4454,13 @@ CodeEditor.keywords = {
|
|
|
4338
4454
|
|
|
4339
4455
|
'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static', 'class', 'constructor', 'null', 'typeof', 'debugger', 'abstract',
|
|
4340
4456
|
'arguments', 'extends', 'instanceof', 'Infinity'],
|
|
4341
|
-
'C
|
|
4342
|
-
|
|
4457
|
+
'C': ['int', 'float', 'double', 'long', 'short', 'char', 'const', 'void', 'true', 'false', 'auto', 'struct', 'typedef', 'signed', 'volatile', 'unsigned', 'static', 'extern', 'enum', 'register',
|
|
4458
|
+
'union'],
|
|
4459
|
+
'C++': ['int', 'float', 'double', 'bool', 'long', 'short', 'char', 'wchar_t', 'const', 'static_cast', 'dynamic_cast', 'new', 'delete', 'void', 'true', 'false', 'auto', 'struct', 'typedef', 'nullptr',
|
|
4460
|
+
'NULL', 'signed', 'unsigned', 'namespace', 'enum', 'extern', 'union', 'sizeof', 'static'],
|
|
4461
|
+
'CMake': ['cmake_minimum_required', 'set', 'not', 'if', 'endif', 'exists', 'string', 'strequal', 'add_definitions', 'macro', 'endmacro', 'file', 'list', 'source_group', 'add_executable',
|
|
4462
|
+
'target_include_directories', 'set_target_properties', 'set_property', 'add_compile_options', 'add_link_options', 'include_directories', 'add_library', 'target_link_libraries',
|
|
4463
|
+
'target_link_options', 'add_subdirectory', 'add_compile_definitions', 'project', 'cache'],
|
|
4343
4464
|
'JSON': ['true', 'false'],
|
|
4344
4465
|
'GLSL': ['true', 'false', 'function', 'int', 'float', 'vec2', 'vec3', 'vec4', 'mat2x2', 'mat3x3', 'mat4x4', 'struct'],
|
|
4345
4466
|
'CSS': ['body', 'html', 'canvas', 'div', 'input', 'span', '.'],
|
|
@@ -4347,10 +4468,10 @@ CodeEditor.keywords = {
|
|
|
4347
4468
|
'sampler', 'sampler_comparison', 'texture_depth_2d', 'texture_depth_2d_array', 'texture_depth_cube', 'texture_depth_cube_array', 'texture_depth_multisampled_2d',
|
|
4348
4469
|
'texture_external', 'texture_1d', 'texture_2d', 'texture_2d_array', 'texture_3d', 'texture_cube', 'texture_cube_array', 'texture_storage_1d', 'texture_storage_2d',
|
|
4349
4470
|
'texture_storage_2d_array', 'texture_storage_3d', 'vec2u', 'vec3u', 'vec4u'],
|
|
4350
|
-
'Rust': ['as', 'const', 'crate', 'enum', 'extern', 'false', 'fn', 'impl', 'in', 'let', 'mod', 'move', 'mut', 'pub', 'ref', 'self', 'Self', 'static', 'struct', 'super', 'trait', 'true',
|
|
4471
|
+
'Rust': ['as', 'const', 'crate', 'enum', 'extern', 'false', 'fn', 'impl', 'in', 'let', 'mod', 'move', 'mut', 'pub', 'ref', 'self', 'Self', 'static', 'struct', 'super', 'trait', 'true',
|
|
4351
4472
|
'type', 'unsafe', 'use', 'where', 'abstract', 'become', 'box', 'final', 'macro', 'override', 'priv', 'typeof', 'unsized', 'virtual'],
|
|
4352
4473
|
'Python': ['False', 'def', 'None', 'True', 'in', 'is', 'and', 'lambda', 'nonlocal', 'not', 'or'],
|
|
4353
|
-
'Batch': ['set', 'SET', 'echo', 'ECHO', 'off', 'OFF', 'del', 'DEL', 'defined', 'DEFINED', 'setlocal', 'SETLOCAL', 'enabledelayedexpansion', 'ENABLEDELAYEDEXPANSION', 'driverquery',
|
|
4474
|
+
'Batch': ['set', 'SET', 'echo', 'ECHO', 'off', 'OFF', 'del', 'DEL', 'defined', 'DEFINED', 'setlocal', 'SETLOCAL', 'enabledelayedexpansion', 'ENABLEDELAYEDEXPANSION', 'driverquery',
|
|
4354
4475
|
'DRIVERQUERY', 'print', 'PRINT'],
|
|
4355
4476
|
'HTML': ['html', 'meta', 'title', 'link', 'script', 'body', 'DOCTYPE', 'head', 'br', 'i', 'a', 'li', 'img', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5'],
|
|
4356
4477
|
'Markdown': ['br', 'i', 'a', 'li', 'img', 'table', 'title', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5'],
|
|
@@ -4362,9 +4483,9 @@ CodeEditor.utils = { // These ones don't have hightlight, used as suggestions to
|
|
|
4362
4483
|
'bind', 'prototype', 'length', 'assign', 'entries', 'values', 'concat', 'substring', 'substr', 'splice', 'slice', 'buffer', 'appendChild', 'createElement', 'prompt',
|
|
4363
4484
|
'alert'],
|
|
4364
4485
|
'WGSL': ['textureSample'],
|
|
4365
|
-
'Python': ['abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod',
|
|
4486
|
+
'Python': ['abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod',
|
|
4366
4487
|
'enumerate', 'eval', 'exec', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance',
|
|
4367
|
-
'issubclass', 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr',
|
|
4488
|
+
'issubclass', 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr',
|
|
4368
4489
|
'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
|
|
4369
4490
|
};
|
|
4370
4491
|
|
|
@@ -4373,14 +4494,14 @@ CodeEditor.types = {
|
|
|
4373
4494
|
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer', 'InputEvent', 'MouseEvent',
|
|
4374
4495
|
'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element'],
|
|
4375
4496
|
'Rust': ['u128'],
|
|
4376
|
-
'Python': ['int', 'type', 'float', 'map', 'list', 'ArithmeticError', 'AssertionError', 'AttributeError', 'Exception', 'EOFError', 'FloatingPointError', 'GeneratorExit',
|
|
4497
|
+
'Python': ['int', 'type', 'float', 'map', 'list', 'ArithmeticError', 'AssertionError', 'AttributeError', 'Exception', 'EOFError', 'FloatingPointError', 'GeneratorExit',
|
|
4377
4498
|
'ImportError', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'NotImplementedError', 'OSError',
|
|
4378
|
-
'OverflowError', 'ReferenceError', 'RuntimeError', 'StopIteration', 'SyntaxError', 'TabError', 'SystemError', 'SystemExit', 'TypeError', 'UnboundLocalError',
|
|
4499
|
+
'OverflowError', 'ReferenceError', 'RuntimeError', 'StopIteration', 'SyntaxError', 'TabError', 'SystemError', 'SystemExit', 'TypeError', 'UnboundLocalError',
|
|
4379
4500
|
'UnicodeError', 'UnicodeEncodeError', 'UnicodeDecodeError', 'UnicodeTranslateError', 'ValueError', 'ZeroDivisionError'],
|
|
4380
4501
|
'C++': ['uint8_t', 'uint16_t', 'uint32_t']
|
|
4381
4502
|
};
|
|
4382
4503
|
|
|
4383
|
-
CodeEditor.
|
|
4504
|
+
CodeEditor.builtIn = {
|
|
4384
4505
|
|
|
4385
4506
|
'JavaScript': ['document', 'console', 'window', 'navigator', 'performance'],
|
|
4386
4507
|
'CSS': ['*', '!important'],
|
|
@@ -4393,11 +4514,12 @@ CodeEditor.statementsAndDeclarations = {
|
|
|
4393
4514
|
|
|
4394
4515
|
'JavaScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await'],
|
|
4395
4516
|
'CSS': ['@', 'import'],
|
|
4396
|
-
'C
|
|
4517
|
+
'C': ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'using', 'default', 'goto', 'do'],
|
|
4518
|
+
'C++': ['std', 'for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'using', 'glm', 'spdlog', 'default'],
|
|
4397
4519
|
'GLSL': ['for', 'if', 'else', 'return', 'continue', 'break'],
|
|
4398
4520
|
'WGSL': ['const','for', 'if', 'else', 'return', 'continue', 'break', 'storage', 'read', 'read_write', 'uniform', 'function', 'workgroup'],
|
|
4399
4521
|
'Rust': ['break', 'else', 'continue', 'for', 'if', 'loop', 'match', 'return', 'while', 'do', 'yield'],
|
|
4400
|
-
'Python': ['if', 'raise', 'del', 'import', 'return', 'elif', 'try', 'else', 'while', 'as', 'except', 'with', 'assert', 'finally', 'yield', 'break', 'for', 'class', 'continue',
|
|
4522
|
+
'Python': ['if', 'raise', 'del', 'import', 'return', 'elif', 'try', 'else', 'while', 'as', 'except', 'with', 'assert', 'finally', 'yield', 'break', 'for', 'class', 'continue',
|
|
4401
4523
|
'global', 'pass', 'from'],
|
|
4402
4524
|
'Batch': ['if', 'IF', 'for', 'FOR', 'in', 'IN', 'do', 'DO', 'call', 'CALL', 'goto', 'GOTO', 'exit', 'EXIT']
|
|
4403
4525
|
};
|
|
@@ -4405,7 +4527,9 @@ CodeEditor.statementsAndDeclarations = {
|
|
|
4405
4527
|
CodeEditor.symbols = {
|
|
4406
4528
|
|
|
4407
4529
|
'JavaScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
|
|
4530
|
+
'C': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '*', '-', '+'],
|
|
4408
4531
|
'C++': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '::', '*', '-', '+'],
|
|
4532
|
+
'CMake': ['{', '}'],
|
|
4409
4533
|
'JSON': ['[', ']', '{', '}', '(', ')'],
|
|
4410
4534
|
'GLSL': ['[', ']', '{', '}', '(', ')'],
|
|
4411
4535
|
'WGSL': ['[', ']', '{', '}', '(', ')', '->'],
|