lexgui 8.1.2 → 8.2.1
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/AlertDialog.d.ts +7 -7
- package/build/components/Avatar.d.ts +15 -0
- package/build/components/Counter.d.ts +9 -9
- package/build/components/Dialog.d.ts +20 -20
- package/build/components/Footer.d.ts +14 -14
- package/build/components/Menubar.d.ts +59 -59
- package/build/components/NodeTree.d.ts +26 -1
- package/build/components/Vector.d.ts +1 -0
- package/build/core/Area.d.ts +143 -143
- package/build/core/Event.d.ts +0 -20
- package/build/core/Namespace.js +1 -1
- package/build/core/Namespace.js.map +1 -1
- package/build/core/Panel.d.ts +538 -538
- package/build/extensions/AssetView.d.ts +137 -136
- package/build/extensions/AssetView.js +193 -155
- package/build/extensions/AssetView.js.map +1 -1
- package/build/extensions/Audio.js +163 -163
- package/build/extensions/Audio.js.map +1 -1
- package/build/extensions/CodeEditor.d.ts +358 -350
- package/build/extensions/CodeEditor.js +302 -270
- package/build/extensions/CodeEditor.js.map +1 -1
- package/build/extensions/DocMaker.d.ts +27 -27
- package/build/extensions/DocMaker.js +15 -11
- package/build/extensions/DocMaker.js.map +1 -1
- package/build/extensions/GraphEditor.js +2754 -2760
- package/build/extensions/GraphEditor.js.map +1 -1
- package/build/extensions/ImUi.js +227 -227
- package/build/extensions/Timeline.d.ts +668 -670
- package/build/extensions/Timeline.js +71 -79
- package/build/extensions/Timeline.js.map +1 -1
- package/build/extensions/VideoEditor.d.ts +38 -16
- package/build/extensions/VideoEditor.js +294 -180
- package/build/extensions/VideoEditor.js.map +1 -1
- package/build/extensions/index.d.ts +8 -8
- package/build/extensions/index.js +10 -10
- package/build/index.all.d.ts +2 -2
- package/build/index.css.d.ts +3 -4
- package/build/index.d.ts +57 -56
- package/build/lexgui.all.js +1877 -1520
- package/build/lexgui.all.js.map +1 -1
- package/build/lexgui.all.min.js +1 -1
- package/build/lexgui.all.module.js +1875 -1516
- package/build/lexgui.all.module.js.map +1 -1
- package/build/lexgui.all.module.min.js +1 -1
- package/build/lexgui.css +6123 -5556
- package/build/lexgui.js +997 -814
- package/build/lexgui.js.map +1 -1
- package/build/lexgui.min.css +2 -3
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +995 -810
- package/build/lexgui.module.js.map +1 -1
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +65 -2
- package/demo.js +167 -65
- package/examples/all-components.html +40 -55
- package/examples/asset-view.html +27 -0
- package/examples/code-editor.html +12 -1
- package/examples/dialogs.html +13 -2
- package/examples/editor.html +9 -49
- package/examples/index.html +2 -2
- package/examples/side-bar.html +1 -1
- package/examples/timeline.html +2 -2
- package/examples/video-editor.html +1 -1
- package/examples/video-editor2.html +2 -2
- package/package.json +7 -4
|
@@ -114,6 +114,9 @@ class Cursor {
|
|
|
114
114
|
print() {
|
|
115
115
|
console.log(this.line, this.position);
|
|
116
116
|
}
|
|
117
|
+
destroy() {
|
|
118
|
+
LX.deleteElement(this.root);
|
|
119
|
+
}
|
|
117
120
|
isLast() {
|
|
118
121
|
return (this.editor._getLastCursor() == this);
|
|
119
122
|
}
|
|
@@ -261,10 +264,8 @@ class ScrollBar {
|
|
|
261
264
|
const HighlightRules = {
|
|
262
265
|
common: [
|
|
263
266
|
{ test: (ctx) => ctx.inBlockComment, className: 'cm-com' },
|
|
264
|
-
{ test: (ctx) => ctx.inString,
|
|
265
|
-
|
|
266
|
-
{ test: (ctx) => ctx.token.substr(0, ctx.singleLineCommentToken.length) == ctx.singleLineCommentToken,
|
|
267
|
-
className: 'cm-com' },
|
|
267
|
+
{ test: (ctx) => ctx.inString, action: (ctx, editor) => editor._appendStringToken(ctx.token), discard: true },
|
|
268
|
+
{ test: (ctx) => ctx.token.substr(0, ctx.singleLineCommentToken.length) == ctx.singleLineCommentToken, className: 'cm-com' },
|
|
268
269
|
{ test: (ctx, editor) => editor._isKeyword(ctx), className: 'cm-kwd' },
|
|
269
270
|
{
|
|
270
271
|
test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.builtIn, ctx.lang) && (ctx.lang.tags ?? false
|
|
@@ -272,12 +273,9 @@ const HighlightRules = {
|
|
|
272
273
|
: true),
|
|
273
274
|
className: 'cm-bln'
|
|
274
275
|
},
|
|
275
|
-
{ test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.statements, ctx.lang),
|
|
276
|
-
|
|
277
|
-
{ test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.
|
|
278
|
-
className: 'cm-sym' },
|
|
279
|
-
{ test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.types, ctx.lang),
|
|
280
|
-
className: 'cm-typ' },
|
|
276
|
+
{ test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.statements, ctx.lang), className: 'cm-std' },
|
|
277
|
+
{ test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.symbols, ctx.lang), className: 'cm-sym' },
|
|
278
|
+
{ test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.types, ctx.lang), className: 'cm-typ' },
|
|
281
279
|
{
|
|
282
280
|
test: (ctx, editor) => editor._isNumber(ctx.token) || editor._isNumber(ctx.token.replace(/[px]|[em]|%/g, '')),
|
|
283
281
|
className: 'cm-dec'
|
|
@@ -332,12 +330,9 @@ const HighlightRules = {
|
|
|
332
330
|
|| (ctx.token[0] == '#' && ctx.prev != ':')),
|
|
333
331
|
className: 'cm-kwd'
|
|
334
332
|
},
|
|
335
|
-
{ test: (ctx) => ctx.prev === ':' && (ctx.next === ';' || ctx.next === '!important'),
|
|
336
|
-
|
|
337
|
-
{ test: (ctx) =>
|
|
338
|
-
className: 'cm-typ' }, // CSS attribute
|
|
339
|
-
{ test: (ctx) => ctx.prev === '(' && ctx.next === ')' && ctx.token.startsWith('--'),
|
|
340
|
-
className: 'cm-typ' } // CSS vars
|
|
333
|
+
{ test: (ctx) => ctx.prev === ':' && (ctx.next === ';' || ctx.next === '!important'), className: 'cm-str' }, // CSS value
|
|
334
|
+
{ test: (ctx) => (ctx.prev === undefined || ctx.prev === '{' || ctx.prev === ';') && ctx.next === ':', className: 'cm-typ' }, // CSS attribute
|
|
335
|
+
{ test: (ctx) => ctx.prev === '(' && ctx.next === ')' && ctx.token.startsWith('--'), className: 'cm-typ' } // CSS vars
|
|
341
336
|
],
|
|
342
337
|
batch: [
|
|
343
338
|
{ test: (ctx) => ctx.token === '@' || ctx.prev === ':' || ctx.prev === '@', className: 'cm-kwd' }
|
|
@@ -462,17 +457,29 @@ class CodeEditor {
|
|
|
462
457
|
newTabOptions;
|
|
463
458
|
customSuggestions = [];
|
|
464
459
|
// Editor callbacks
|
|
465
|
-
onSave;
|
|
466
|
-
onRun;
|
|
467
|
-
onCtrlSpace;
|
|
468
|
-
onCreateStatusPanel;
|
|
469
460
|
onContextMenu;
|
|
461
|
+
onCreateFile;
|
|
462
|
+
onCreateStatusPanel;
|
|
463
|
+
onCtrlSpace;
|
|
470
464
|
onNewTab;
|
|
465
|
+
onSave;
|
|
471
466
|
onSelectTab;
|
|
472
|
-
|
|
467
|
+
onReady;
|
|
468
|
+
onRun;
|
|
473
469
|
// Inner functions
|
|
474
470
|
addExplorerItem;
|
|
475
|
-
//
|
|
471
|
+
// Internal variables
|
|
472
|
+
_blockCommentCache = [];
|
|
473
|
+
_buildingBlockComment = undefined;
|
|
474
|
+
_buildingString = undefined;
|
|
475
|
+
_currentOcurrences = undefined;
|
|
476
|
+
_currentLineNumber = undefined;
|
|
477
|
+
_currentLineString = undefined;
|
|
478
|
+
_currentTokenPositions = undefined;
|
|
479
|
+
_discardScroll = false;
|
|
480
|
+
_displayObserver = null;
|
|
481
|
+
_fullVerticalOffset = -1;
|
|
482
|
+
_isReady = false;
|
|
476
483
|
_lastTime = null;
|
|
477
484
|
_lastProcessedLine = -1;
|
|
478
485
|
_lastResult = undefined;
|
|
@@ -482,28 +489,21 @@ class CodeEditor {
|
|
|
482
489
|
_lastMouseDown = 0;
|
|
483
490
|
_lastTextFound = '';
|
|
484
491
|
_lastBaseareaWidth = undefined;
|
|
485
|
-
_blockCommentCache = [];
|
|
486
|
-
_pendingString = undefined;
|
|
487
|
-
_skipTabs = undefined;
|
|
488
|
-
_discardScroll = false;
|
|
489
492
|
_markdownHeader = undefined;
|
|
490
|
-
_tabStorage = {};
|
|
491
|
-
_tripleClickSelection = undefined;
|
|
492
|
-
_currentOcurrences = undefined;
|
|
493
|
-
_currentLineNumber = undefined;
|
|
494
|
-
_currentLineString = undefined;
|
|
495
|
-
_currentTokenPositions = undefined;
|
|
496
|
-
_buildingBlockComment = undefined;
|
|
497
|
-
_buildingString = undefined;
|
|
498
|
-
_verticalTopOffset = -1;
|
|
499
|
-
_verticalBottomOffset = -1;
|
|
500
|
-
_fullVerticalOffset = -1;
|
|
501
|
-
_scopeStack = null;
|
|
502
493
|
_mouseDown = undefined;
|
|
494
|
+
_nextCursorPositionOffset = undefined;
|
|
495
|
+
_pendingString = undefined;
|
|
496
|
+
_preparedAt = undefined;
|
|
497
|
+
_scopeStack = null;
|
|
503
498
|
_scopesUpdated = undefined;
|
|
499
|
+
_skipTabs = undefined;
|
|
504
500
|
_stringEnded = false;
|
|
505
501
|
_stringInterpolation = undefined;
|
|
506
502
|
_stringInterpolationOpened = undefined;
|
|
503
|
+
_tabStorage = {};
|
|
504
|
+
_tripleClickSelection = undefined;
|
|
505
|
+
_verticalBottomOffset = -1;
|
|
506
|
+
_verticalTopOffset = -1;
|
|
507
507
|
constructor(area, options = {}) {
|
|
508
508
|
if (options.filesAsync) {
|
|
509
509
|
options.files = [...options.filesAsync];
|
|
@@ -541,6 +541,7 @@ class CodeEditor {
|
|
|
541
541
|
this.onContextMenu = options.onContextMenu;
|
|
542
542
|
this.onNewTab = options.onNewTab;
|
|
543
543
|
this.onSelectTab = options.onSelectTab;
|
|
544
|
+
this.onReady = options.onReady;
|
|
544
545
|
// File explorer
|
|
545
546
|
if (this.useFileExplorer) {
|
|
546
547
|
let [explorerArea, editorArea] = area.split({ sizes: ['15%', '85%'] });
|
|
@@ -552,27 +553,15 @@ class CodeEditor {
|
|
|
552
553
|
this.explorer = panel.addTree(null, sceneData, {
|
|
553
554
|
filter: false,
|
|
554
555
|
rename: false,
|
|
555
|
-
skipDefaultIcon: true
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
this.closeTab(event.node.id);
|
|
565
|
-
break;
|
|
566
|
-
// case LX.TreeEvent.NODE_CONTEXTMENU:
|
|
567
|
-
// LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.value, m => {
|
|
568
|
-
//
|
|
569
|
-
// });
|
|
570
|
-
// break;
|
|
571
|
-
// case LX.TreeEvent.NODE_DRAGGED:
|
|
572
|
-
// console.log(event.node.id + " is now child of " + event.value.id);
|
|
573
|
-
// break;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
556
|
+
skipDefaultIcon: true
|
|
557
|
+
});
|
|
558
|
+
this.explorer.on('dblClick', (event) => {
|
|
559
|
+
const node = event.items[0];
|
|
560
|
+
this.loadTab(node.id);
|
|
561
|
+
});
|
|
562
|
+
this.explorer.on('delete', (event) => {
|
|
563
|
+
const node = event.items[0];
|
|
564
|
+
this.closeTab(node.id);
|
|
576
565
|
});
|
|
577
566
|
this.addExplorerItem = function (item) {
|
|
578
567
|
if (!this.explorer.innerTree.data.find((value, index) => value.id === item.id)) {
|
|
@@ -584,13 +573,13 @@ class CodeEditor {
|
|
|
584
573
|
area = editorArea;
|
|
585
574
|
}
|
|
586
575
|
this.baseArea = area;
|
|
587
|
-
this.area = new LX.Area({ className: 'lexcodeeditor
|
|
576
|
+
this.area = new LX.Area({ className: 'lexcodeeditor outline-none overflow-hidden size-full select-none bg-inherit', skipAppend: true });
|
|
588
577
|
if (!this.skipTabs) {
|
|
589
578
|
this.tabs = this.area.addTabs({ onclose: (name) => {
|
|
590
579
|
delete this.openedTabs[name];
|
|
591
580
|
if (Object.keys(this.openedTabs).length < 2) {
|
|
592
581
|
clearInterval(this.blinker);
|
|
593
|
-
LX.
|
|
582
|
+
LX.removeClass(this.cursorsDOM, 'show');
|
|
594
583
|
}
|
|
595
584
|
} });
|
|
596
585
|
LX.addClass(this.tabs.root.parentElement, 'rounded-t-lg');
|
|
@@ -607,13 +596,12 @@ class CodeEditor {
|
|
|
607
596
|
else {
|
|
608
597
|
this.codeArea = new LX.Area({ skipAppend: true });
|
|
609
598
|
this.area.attach(this.codeArea);
|
|
610
|
-
const loadFileButton = LX.makeElement('button', 'grid absolute self-center z-100 p-3 rounded-full bg-secondary hover:bg-
|
|
599
|
+
const loadFileButton = LX.makeElement('button', 'grid absolute place-self-center z-100 p-3 rounded-full bg-secondary hover:bg-accent cursor-pointer border-color', LX.makeIcon('FolderOpen').innerHTML, this.area, {
|
|
611
600
|
bottom: '8px'
|
|
612
601
|
});
|
|
613
602
|
loadFileButton.addEventListener('click', (e) => {
|
|
614
603
|
const dropdownOptions = [];
|
|
615
|
-
for (const [key, value] of [...Object.entries(this.loadedTabs).slice(1),
|
|
616
|
-
...Object.entries(this._tabStorage)]) {
|
|
604
|
+
for (const [key, value] of [...Object.entries(this.loadedTabs).slice(1), ...Object.entries(this._tabStorage)]) {
|
|
617
605
|
const icon = this._getFileIcon(key);
|
|
618
606
|
const classes = icon ? icon.split(' ') : [];
|
|
619
607
|
dropdownOptions.push({
|
|
@@ -628,7 +616,7 @@ class CodeEditor {
|
|
|
628
616
|
new LX.DropdownMenu(loadFileButton, dropdownOptions, { side: 'top', align: 'center' });
|
|
629
617
|
});
|
|
630
618
|
}
|
|
631
|
-
this.codeArea.root.classList.add('lexcodearea');
|
|
619
|
+
this.codeArea.root.classList.add('lexcodearea', 'scrollbar-hidden');
|
|
632
620
|
const codeResizeObserver = new ResizeObserver((entries) => {
|
|
633
621
|
if (!this.code) {
|
|
634
622
|
return;
|
|
@@ -637,7 +625,7 @@ class CodeEditor {
|
|
|
637
625
|
});
|
|
638
626
|
codeResizeObserver.observe(this.codeArea.root);
|
|
639
627
|
// Full editor
|
|
640
|
-
area.root.
|
|
628
|
+
area.root.className = LX.mergeClass(area.root.className, 'codebasearea flex relative bg-card');
|
|
641
629
|
const observer = new MutationObserver((e) => {
|
|
642
630
|
if (e[0].attributeName == 'style') {
|
|
643
631
|
this.resize();
|
|
@@ -766,11 +754,11 @@ class CodeEditor {
|
|
|
766
754
|
box.appendChild(searchPanel.root);
|
|
767
755
|
searchPanel.sameLine(4);
|
|
768
756
|
searchPanel.addText(null, '', null, { placeholder: 'Find', inputClass: 'bg-secondary' });
|
|
769
|
-
searchPanel.addButton(null, 'up', () => this.search(null, true), { icon: 'ArrowUp',
|
|
770
|
-
|
|
771
|
-
searchPanel.addButton(null, 'down', () => this.search(), { icon: 'ArrowDown', title: 'Next Match',
|
|
757
|
+
searchPanel.addButton(null, 'up', () => this.search(null, true), { icon: 'ArrowUp', buttonClass: 'ghost', title: 'Previous Match',
|
|
758
|
+
tooltip: true });
|
|
759
|
+
searchPanel.addButton(null, 'down', () => this.search(), { icon: 'ArrowDown', buttonClass: 'ghost', title: 'Next Match',
|
|
772
760
|
tooltip: true });
|
|
773
|
-
searchPanel.addButton(null, 'x', this.hideSearchBox.bind(this), { icon: 'X', title: 'Close',
|
|
761
|
+
searchPanel.addButton(null, 'x', this.hideSearchBox.bind(this), { icon: 'X', buttonClass: 'ghost', title: 'Close',
|
|
774
762
|
tooltip: true });
|
|
775
763
|
const searchInput = box.querySelector('input');
|
|
776
764
|
searchInput?.addEventListener('keyup', (e) => {
|
|
@@ -793,7 +781,7 @@ class CodeEditor {
|
|
|
793
781
|
input.value = ':' + value.replaceAll(':', '');
|
|
794
782
|
this.goToLine(input.value.slice(1));
|
|
795
783
|
}, { placeholder: 'Go to line', trigger: 'input' });
|
|
796
|
-
searchPanel.addButton(null, 'x', this.hideSearchLineBox.bind(this), { icon: 'X', title: 'Close',
|
|
784
|
+
searchPanel.addButton(null, 'x', this.hideSearchLineBox.bind(this), { icon: 'X', title: 'Close', buttonClass: 'ghost',
|
|
797
785
|
tooltip: true });
|
|
798
786
|
let input = box.querySelector('input');
|
|
799
787
|
input.addEventListener('keyup', (e) => {
|
|
@@ -858,9 +846,8 @@ class CodeEditor {
|
|
|
858
846
|
CodeEditor.types[lang] = new Set(CodeEditor.types[lang]);
|
|
859
847
|
for (let lang in CodeEditor.builtIn)
|
|
860
848
|
CodeEditor.builtIn[lang] = new Set(CodeEditor.builtIn[lang]);
|
|
861
|
-
for (let lang in CodeEditor.statements)
|
|
849
|
+
for (let lang in CodeEditor.statements)
|
|
862
850
|
CodeEditor.statements[lang] = new Set(CodeEditor.statements[lang]);
|
|
863
|
-
}
|
|
864
851
|
for (let lang in CodeEditor.symbols)
|
|
865
852
|
CodeEditor.symbols[lang] = new Set(CodeEditor.symbols[lang]);
|
|
866
853
|
CodeEditor._staticReady = true;
|
|
@@ -931,6 +918,9 @@ class CodeEditor {
|
|
|
931
918
|
if (letter) {
|
|
932
919
|
this.code.lines[ln] = sliceChars(this.code.lines[ln], cursor.position);
|
|
933
920
|
this.processLine(ln);
|
|
921
|
+
// "Delete" removes the char at the right, so cursor position does not change
|
|
922
|
+
// but line length does and next cursor position must be updated 1 position to the left
|
|
923
|
+
this._nextCursorPositionOffset = -1;
|
|
934
924
|
}
|
|
935
925
|
else if (this.code.lines[ln + 1] != undefined) {
|
|
936
926
|
this.code.lines[ln] += this.code.lines[ln + 1];
|
|
@@ -1159,18 +1149,18 @@ class CodeEditor {
|
|
|
1159
1149
|
this._processSelection(cursor, e, false, CodeEditor.SELECTION_X);
|
|
1160
1150
|
}
|
|
1161
1151
|
else {
|
|
1162
|
-
if (
|
|
1163
|
-
this.cursorToLeft(letter, cursor);
|
|
1164
|
-
if (this.useAutoComplete && this.isAutoCompleteActive) {
|
|
1165
|
-
this.showAutoCompleteBox('foo', cursor);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
else {
|
|
1152
|
+
if (cursor.selection) {
|
|
1169
1153
|
cursor.selection.invertIfNecessary();
|
|
1170
1154
|
this.resetCursorPos(CodeEditor.CURSOR_LEFT_TOP, cursor);
|
|
1171
1155
|
this.cursorToLine(cursor, cursor.selection.fromY);
|
|
1172
1156
|
this.cursorToPosition(cursor, cursor.selection.fromX, true);
|
|
1173
|
-
this.endSelection();
|
|
1157
|
+
this.endSelection(cursor);
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
this.cursorToLeft(letter, cursor);
|
|
1161
|
+
if (this.useAutoComplete && this.isAutoCompleteActive) {
|
|
1162
|
+
this.showAutoCompleteBox('foo', cursor);
|
|
1163
|
+
}
|
|
1174
1164
|
}
|
|
1175
1165
|
}
|
|
1176
1166
|
}
|
|
@@ -1271,39 +1261,7 @@ class CodeEditor {
|
|
|
1271
1261
|
if (this.statusPanel) {
|
|
1272
1262
|
area.attach(this.statusPanel);
|
|
1273
1263
|
}
|
|
1274
|
-
|
|
1275
|
-
await document.fonts.ready;
|
|
1276
|
-
}
|
|
1277
|
-
// Load any font size from local storage
|
|
1278
|
-
const savedFontSize = window.localStorage.getItem('lexcodeeditor-font-size');
|
|
1279
|
-
if (savedFontSize) {
|
|
1280
|
-
this._setFontSize(parseInt(savedFontSize));
|
|
1281
|
-
}
|
|
1282
|
-
// Use default size
|
|
1283
|
-
else {
|
|
1284
|
-
const r = document.querySelector(':root');
|
|
1285
|
-
const s = getComputedStyle(r);
|
|
1286
|
-
this.fontSize = parseInt(s.getPropertyValue('--code-editor-font-size'));
|
|
1287
|
-
this.charWidth = this._measureChar();
|
|
1288
|
-
}
|
|
1289
|
-
LX.emitSignal('@font-size', this.fontSize);
|
|
1290
|
-
// Get final sizes for editor elements based on Tabs and status bar offsets
|
|
1291
|
-
LX.doAsync(() => {
|
|
1292
|
-
this._verticalTopOffset = this.tabs?.root.getBoundingClientRect().height ?? 0;
|
|
1293
|
-
this._verticalBottomOffset = this.statusPanel?.root.getBoundingClientRect().height ?? 0;
|
|
1294
|
-
this._fullVerticalOffset = this._verticalTopOffset + this._verticalBottomOffset;
|
|
1295
|
-
this.gutter.style.marginTop = `${this._verticalTopOffset}px`;
|
|
1296
|
-
this.gutter.style.height = `calc(100% - ${this._fullVerticalOffset}px)`;
|
|
1297
|
-
this.vScrollbar.root.style.marginTop = `${this._verticalTopOffset}px`;
|
|
1298
|
-
this.vScrollbar.root.style.height = `calc(100% - ${this._fullVerticalOffset}px)`;
|
|
1299
|
-
this.hScrollbar.root.style.bottom = `${this._verticalBottomOffset}px`;
|
|
1300
|
-
this.codeArea.root.style.height = `calc(100% - ${this._fullVerticalOffset}px)`;
|
|
1301
|
-
// Process lines on finish computing final sizes
|
|
1302
|
-
this.processLines();
|
|
1303
|
-
}, 50);
|
|
1304
|
-
if (options.callback) {
|
|
1305
|
-
options.callback.call(this, this);
|
|
1306
|
-
}
|
|
1264
|
+
this._setupDisplayObserver();
|
|
1307
1265
|
g.editor = this;
|
|
1308
1266
|
};
|
|
1309
1267
|
if (options.allowAddScripts ?? true) {
|
|
@@ -1318,8 +1276,7 @@ class CodeEditor {
|
|
|
1318
1276
|
for (let url of options.files) {
|
|
1319
1277
|
const finalUrl = url.constructor === Array ? url[0] : url;
|
|
1320
1278
|
const finalFileName = url.constructor === Array ? url[1] : undefined;
|
|
1321
|
-
await this.loadFile(finalUrl, { filename: finalFileName, async: loadAsync,
|
|
1322
|
-
callback: (name, text) => {
|
|
1279
|
+
await this.loadFile(finalUrl, { filename: finalFileName, async: loadAsync, callback: (name, text) => {
|
|
1323
1280
|
filesLoaded++;
|
|
1324
1281
|
if (filesLoaded == numFiles) {
|
|
1325
1282
|
onLoadAll();
|
|
@@ -1339,6 +1296,92 @@ class CodeEditor {
|
|
|
1339
1296
|
onLoadAll();
|
|
1340
1297
|
}
|
|
1341
1298
|
}
|
|
1299
|
+
_setupDisplayObserver() {
|
|
1300
|
+
if (this._displayObserver)
|
|
1301
|
+
return;
|
|
1302
|
+
this._isReady = false;
|
|
1303
|
+
const root = this.root;
|
|
1304
|
+
const _isVisible = () => {
|
|
1305
|
+
return (root.offsetParent !== null
|
|
1306
|
+
&& root.clientWidth > 0
|
|
1307
|
+
&& root.clientHeight > 0);
|
|
1308
|
+
};
|
|
1309
|
+
const _tryPrepare = async () => {
|
|
1310
|
+
if (this._isReady)
|
|
1311
|
+
return;
|
|
1312
|
+
if (!_isVisible())
|
|
1313
|
+
return;
|
|
1314
|
+
this._isReady = true;
|
|
1315
|
+
// Stop observing once prepared
|
|
1316
|
+
intersectionObserver.disconnect();
|
|
1317
|
+
resizeObserver.disconnect();
|
|
1318
|
+
await this._setupEditorWhenVisible();
|
|
1319
|
+
};
|
|
1320
|
+
// IntersectionObserver (for viewport)
|
|
1321
|
+
const intersectionObserver = new IntersectionObserver((entries) => {
|
|
1322
|
+
for (const entry of entries) {
|
|
1323
|
+
if (entry.isIntersecting) {
|
|
1324
|
+
_tryPrepare();
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
intersectionObserver.observe(root);
|
|
1329
|
+
// ResizeObserver (for display property changes)
|
|
1330
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
1331
|
+
_tryPrepare();
|
|
1332
|
+
});
|
|
1333
|
+
resizeObserver.observe(root);
|
|
1334
|
+
// Fallback polling (don't use it for now)
|
|
1335
|
+
// const interval = setInterval( () => {
|
|
1336
|
+
// if ( this._isReady ) {
|
|
1337
|
+
// clearInterval( interval );
|
|
1338
|
+
// return;
|
|
1339
|
+
// }
|
|
1340
|
+
// _tryPrepare();
|
|
1341
|
+
// }, 250 );
|
|
1342
|
+
this._displayObserver = {
|
|
1343
|
+
intersectionObserver,
|
|
1344
|
+
resizeObserver
|
|
1345
|
+
// interval,
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
async _setupEditorWhenVisible() {
|
|
1349
|
+
if (document.fonts.status == 'loading') {
|
|
1350
|
+
await document.fonts.ready;
|
|
1351
|
+
}
|
|
1352
|
+
// Load any font size from local storage
|
|
1353
|
+
const savedFontSize = window.localStorage.getItem('lexcodeeditor-font-size');
|
|
1354
|
+
if (savedFontSize) {
|
|
1355
|
+
this._setFontSize(parseInt(savedFontSize));
|
|
1356
|
+
}
|
|
1357
|
+
// Use default size
|
|
1358
|
+
else {
|
|
1359
|
+
const r = document.querySelector(':root');
|
|
1360
|
+
const s = getComputedStyle(r);
|
|
1361
|
+
this.fontSize = parseInt(s.getPropertyValue('--code-editor-font-size'));
|
|
1362
|
+
this.charWidth = this._measureChar();
|
|
1363
|
+
}
|
|
1364
|
+
LX.emitSignal('@font-size', this.fontSize);
|
|
1365
|
+
// Get final sizes for editor elements based on Tabs and status bar offsets
|
|
1366
|
+
LX.doAsync(() => {
|
|
1367
|
+
this._verticalTopOffset = this.tabs?.root.getBoundingClientRect().height ?? 0;
|
|
1368
|
+
this._verticalBottomOffset = this.statusPanel?.root.getBoundingClientRect().height ?? 0;
|
|
1369
|
+
this._fullVerticalOffset = this._verticalTopOffset + this._verticalBottomOffset;
|
|
1370
|
+
this.gutter.style.marginTop = `${this._verticalTopOffset}px`;
|
|
1371
|
+
this.gutter.style.height = `calc(100% - ${this._fullVerticalOffset}px)`;
|
|
1372
|
+
this.vScrollbar.root.style.marginTop = `${this._verticalTopOffset}px`;
|
|
1373
|
+
this.vScrollbar.root.style.height = `calc(100% - ${this._fullVerticalOffset}px)`;
|
|
1374
|
+
this.hScrollbar.root.style.bottom = `${this._verticalBottomOffset}px`;
|
|
1375
|
+
this.codeArea.root.style.height = `calc(100% - ${this._fullVerticalOffset}px)`;
|
|
1376
|
+
// Process lines on finish computing final sizes
|
|
1377
|
+
this.processLines();
|
|
1378
|
+
this._preparedAt = performance.now();
|
|
1379
|
+
if (this.onReady) {
|
|
1380
|
+
this.onReady(this);
|
|
1381
|
+
}
|
|
1382
|
+
console.log(`[LX.CodeEditor] Ready! (font size: ${this.fontSize}px)`);
|
|
1383
|
+
}, 50);
|
|
1384
|
+
}
|
|
1342
1385
|
// Clear signals
|
|
1343
1386
|
clear() {
|
|
1344
1387
|
console.assert(this.rightStatusPanel && this.leftStatusPanel, 'No panels to clear.');
|
|
@@ -1367,7 +1410,7 @@ class CodeEditor {
|
|
|
1367
1410
|
return this.code.lines.join(min ? ' ' : '\n');
|
|
1368
1411
|
}
|
|
1369
1412
|
// This can be used to empty all text...
|
|
1370
|
-
setText(text = '', langString) {
|
|
1413
|
+
setText(text = '', langString, detectLanguage = false) {
|
|
1371
1414
|
let newLines = text.split('\n');
|
|
1372
1415
|
this.code.lines = [].concat(newLines);
|
|
1373
1416
|
this._removeSecondaryCursors();
|
|
@@ -1376,6 +1419,9 @@ class CodeEditor {
|
|
|
1376
1419
|
this.cursorToLine(cursor, newLines.length); // Already substracted 1
|
|
1377
1420
|
this.cursorToPosition(cursor, lastLine?.length ?? 0, true);
|
|
1378
1421
|
this.mustProcessLines = true;
|
|
1422
|
+
if (detectLanguage) {
|
|
1423
|
+
langString = this._detectLanguage(text);
|
|
1424
|
+
}
|
|
1379
1425
|
if (langString) {
|
|
1380
1426
|
this._changeLanguage(langString);
|
|
1381
1427
|
}
|
|
@@ -1638,25 +1684,22 @@ class CodeEditor {
|
|
|
1638
1684
|
this.onCreateStatusPanel(panel, this);
|
|
1639
1685
|
}
|
|
1640
1686
|
let leftStatusPanel = this.leftStatusPanel = new LX.Panel({ id: 'FontSizeZoomStatusComponent',
|
|
1641
|
-
height: 'auto' });
|
|
1687
|
+
className: 'pad-xs content-center items-center flex-auto-keep', width: 'auto', height: 'auto' });
|
|
1642
1688
|
leftStatusPanel.sameLine();
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
width: '32px', title: 'Zoom Out', tooltip: true });
|
|
1646
|
-
}
|
|
1647
|
-
leftStatusPanel.addButton(null, 'ZoomOutButton', this._decreaseFontSize.bind(this), { icon: 'ZoomOut',
|
|
1648
|
-
width: '32px', title: 'Zoom Out', tooltip: true });
|
|
1689
|
+
leftStatusPanel.addButton(null, 'ZoomOutButton', this._decreaseFontSize.bind(this), { icon: 'ZoomOut', buttonClass: 'ghost sm',
|
|
1690
|
+
title: 'Zoom Out', tooltip: true });
|
|
1649
1691
|
leftStatusPanel.addLabel(this.fontSize, { fit: true, signal: '@font-size' });
|
|
1650
|
-
leftStatusPanel.addButton(null, 'ZoomInButton', this._increaseFontSize.bind(this), { icon: 'ZoomIn',
|
|
1651
|
-
|
|
1692
|
+
leftStatusPanel.addButton(null, 'ZoomInButton', this._increaseFontSize.bind(this), { icon: 'ZoomIn', buttonClass: 'ghost sm',
|
|
1693
|
+
title: 'Zoom In', tooltip: true });
|
|
1652
1694
|
leftStatusPanel.endLine('justify-start');
|
|
1653
1695
|
panel.attach(leftStatusPanel.root);
|
|
1654
|
-
let rightStatusPanel = this.rightStatusPanel = new LX.Panel({ height: 'auto' });
|
|
1696
|
+
let rightStatusPanel = this.rightStatusPanel = new LX.Panel({ className: 'pad-xs content-center items-center', height: 'auto' });
|
|
1655
1697
|
rightStatusPanel.sameLine();
|
|
1656
|
-
rightStatusPanel.addLabel(this.code?.title ?? '', { id: 'EditorFilenameStatusComponent', fit: true,
|
|
1698
|
+
rightStatusPanel.addLabel(this.code?.title ?? '', { id: 'EditorFilenameStatusComponent', fit: true, inputClass: 'text-xs',
|
|
1657
1699
|
signal: '@tab-name' });
|
|
1658
1700
|
rightStatusPanel.addButton(null, 'Ln 1, Col 1', this.showSearchLineBox.bind(this), {
|
|
1659
1701
|
id: 'EditorSelectionStatusComponent',
|
|
1702
|
+
buttonClass: 'outline xs',
|
|
1660
1703
|
fit: true,
|
|
1661
1704
|
signal: '@cursor-data'
|
|
1662
1705
|
});
|
|
@@ -1671,7 +1714,7 @@ class CodeEditor {
|
|
|
1671
1714
|
});
|
|
1672
1715
|
}
|
|
1673
1716
|
});
|
|
1674
|
-
}, { id: 'EditorIndentationStatusComponent',
|
|
1717
|
+
}, { id: 'EditorIndentationStatusComponent', buttonClass: 'outline xs', signal: '@tab-spaces' });
|
|
1675
1718
|
rightStatusPanel.addButton('<b>{ }</b>', this.highlight, (value, event) => {
|
|
1676
1719
|
LX.addContextMenu('Language', event, (m) => {
|
|
1677
1720
|
for (const lang of Object.keys(CodeEditor.languages)) {
|
|
@@ -1681,7 +1724,7 @@ class CodeEditor {
|
|
|
1681
1724
|
});
|
|
1682
1725
|
}
|
|
1683
1726
|
});
|
|
1684
|
-
}, { id: 'EditorLanguageStatusComponent', nameWidth: '
|
|
1727
|
+
}, { id: 'EditorLanguageStatusComponent', nameWidth: 'auto', buttonClass: 'outline xs', signal: '@highlight', title: '' });
|
|
1685
1728
|
rightStatusPanel.endLine('justify-end');
|
|
1686
1729
|
panel.attach(rightStatusPanel.root);
|
|
1687
1730
|
const itemVisibilityMap = {
|
|
@@ -1753,13 +1796,13 @@ class CodeEditor {
|
|
|
1753
1796
|
}
|
|
1754
1797
|
}
|
|
1755
1798
|
if (langString === undefined) {
|
|
1756
|
-
return 'AlignLeft
|
|
1799
|
+
return 'AlignLeft text-neutral-500';
|
|
1757
1800
|
}
|
|
1758
1801
|
const iconPlusClasses = CodeEditor.languages[langString]?.icon;
|
|
1759
1802
|
if (iconPlusClasses) {
|
|
1760
1803
|
return iconPlusClasses[extension] ?? iconPlusClasses;
|
|
1761
1804
|
}
|
|
1762
|
-
return 'AlignLeft
|
|
1805
|
+
return 'AlignLeft text-neutral-500';
|
|
1763
1806
|
}
|
|
1764
1807
|
_onNewTab(e) {
|
|
1765
1808
|
this.processFocus(false);
|
|
@@ -1769,8 +1812,7 @@ class CodeEditor {
|
|
|
1769
1812
|
}
|
|
1770
1813
|
const dmOptions = this.newTabOptions ?? [
|
|
1771
1814
|
{ name: 'Create file', icon: 'FilePlus', callback: this._onCreateNewFile.bind(this) },
|
|
1772
|
-
{ name: 'Load file', icon: 'FileUp', disabled: !this.allowLoadingFiles,
|
|
1773
|
-
callback: this.loadTabFromFile.bind(this) }
|
|
1815
|
+
{ name: 'Load file', icon: 'FileUp', disabled: !this.allowLoadingFiles, callback: this.loadTabFromFile.bind(this) }
|
|
1774
1816
|
];
|
|
1775
1817
|
new LX.DropdownMenu(e.target, dmOptions, { side: 'bottom', align: 'start' });
|
|
1776
1818
|
}
|
|
@@ -1783,8 +1825,7 @@ class CodeEditor {
|
|
|
1783
1825
|
}
|
|
1784
1826
|
}
|
|
1785
1827
|
const name = options.name ?? 'unnamed.js';
|
|
1786
|
-
this.addTab(name, true, name, { indexOffset: options.indexOffset,
|
|
1787
|
-
language: options.language ?? 'JavaScript' });
|
|
1828
|
+
this.addTab(name, true, name, { indexOffset: options.indexOffset, language: options.language ?? 'JavaScript' });
|
|
1788
1829
|
}
|
|
1789
1830
|
_onSelectTab(isNewTabButton, event, name) {
|
|
1790
1831
|
if (this.disableEdition) {
|
|
@@ -2196,8 +2237,7 @@ class CodeEditor {
|
|
|
2196
2237
|
processClick(e) {
|
|
2197
2238
|
var cursor = this.getCurrentCursor();
|
|
2198
2239
|
var code_rect = this.codeScroller.getBoundingClientRect();
|
|
2199
|
-
var position = [(e.clientX - code_rect.x) + this.getScrollLeft(),
|
|
2200
|
-
(e.clientY - code_rect.y) + this.getScrollTop()];
|
|
2240
|
+
var position = [(e.clientX - code_rect.x) + this.getScrollLeft(), (e.clientY - code_rect.y) + this.getScrollTop()];
|
|
2201
2241
|
var ln = (position[1] / this.lineHeight) | 0;
|
|
2202
2242
|
// Check out of range line
|
|
2203
2243
|
const outOfRange = ln > this.code.lines.length - 1;
|
|
@@ -2362,12 +2402,12 @@ class CodeEditor {
|
|
|
2362
2402
|
}
|
|
2363
2403
|
async processKey(e) {
|
|
2364
2404
|
const numCursors = this.cursors.length;
|
|
2365
|
-
if (!this.code || e.
|
|
2405
|
+
if (!this.code || e.target?.constructor != HTMLDivElement) {
|
|
2366
2406
|
return;
|
|
2367
2407
|
}
|
|
2368
2408
|
const detail = e.detail ?? {};
|
|
2369
2409
|
const key = e.key ?? detail.key;
|
|
2370
|
-
//
|
|
2410
|
+
// Don't propagate "space to scroll" event
|
|
2371
2411
|
if (key == ' ') {
|
|
2372
2412
|
e.preventDefault();
|
|
2373
2413
|
e.stopPropagation();
|
|
@@ -2384,6 +2424,7 @@ class CodeEditor {
|
|
|
2384
2424
|
return;
|
|
2385
2425
|
}
|
|
2386
2426
|
this._lastProcessedCursorIndex = null;
|
|
2427
|
+
this._nextCursorPositionOffset = 0;
|
|
2387
2428
|
var lastProcessedCursor = null;
|
|
2388
2429
|
var cursorOffset = new LX.vec2(0, 0);
|
|
2389
2430
|
for (var i = 0; i < numCursors; i++) {
|
|
@@ -2397,18 +2438,35 @@ class CodeEditor {
|
|
|
2397
2438
|
cursor.position += cursorOffset.x;
|
|
2398
2439
|
cursor.line += cursorOffset.y;
|
|
2399
2440
|
this.relocateCursors();
|
|
2441
|
+
// Apart from relocation based on offsets, its selection (if any) must be relocated too
|
|
2442
|
+
if (cursor.selection) {
|
|
2443
|
+
cursor.selection.fromX += cursorOffset.x;
|
|
2444
|
+
cursor.selection.toX += cursorOffset.x;
|
|
2445
|
+
cursor.selection.fromY += cursorOffset.y;
|
|
2446
|
+
cursor.selection.toY += cursorOffset.y;
|
|
2447
|
+
this._processSelection(cursor);
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
else if (lastProcessedCursor && lastProcessedCursor.line != cursor.line) {
|
|
2451
|
+
// Reset offset X in case we changed line
|
|
2452
|
+
cursorOffset.x = 0;
|
|
2400
2453
|
}
|
|
2401
2454
|
lastProcessedCursor = this.saveCursor(cursor);
|
|
2402
2455
|
this._lastProcessedCursorIndex = i;
|
|
2403
2456
|
this._processKeyAtCursor(e, key, cursor);
|
|
2404
|
-
|
|
2405
|
-
|
|
2457
|
+
// Apply difference offset between last processed cursor and current positions plus any offset generated
|
|
2458
|
+
// during processing the key pressed
|
|
2459
|
+
const totalCursorOffsetX = (cursor.position - lastProcessedCursor.position) + this._nextCursorPositionOffset;
|
|
2460
|
+
const totalCursorOffsetY = cursor.line - lastProcessedCursor.line;
|
|
2461
|
+
cursorOffset.x += totalCursorOffsetX;
|
|
2462
|
+
cursorOffset.y += totalCursorOffsetY;
|
|
2406
2463
|
// Set active line in case it's blurred
|
|
2407
2464
|
if (!cursor.selection) {
|
|
2408
2465
|
cursor.line = cursor.line;
|
|
2409
2466
|
}
|
|
2410
2467
|
}
|
|
2411
2468
|
// Clear tmp
|
|
2469
|
+
delete this._nextCursorPositionOffset;
|
|
2412
2470
|
delete this._lastProcessedCursorIndex;
|
|
2413
2471
|
}
|
|
2414
2472
|
async processKeyAtTargetCursor(e, key, targetIdx) {
|
|
@@ -2580,8 +2638,9 @@ class CodeEditor {
|
|
|
2580
2638
|
lidx = cursor.line;
|
|
2581
2639
|
}
|
|
2582
2640
|
// Append key
|
|
2641
|
+
const nextChar = this.getCharAtPos(cursor); // Only pair keys if no next char or its a space
|
|
2583
2642
|
const isPairKey = (Object.values(this.pairKeys).indexOf(key) > -1) && !this.wasKeyPaired;
|
|
2584
|
-
const sameKeyNext = isPairKey && (
|
|
2643
|
+
const sameKeyNext = isPairKey && (nextChar === key);
|
|
2585
2644
|
if (!sameKeyNext) {
|
|
2586
2645
|
this.code.lines[lidx] = [
|
|
2587
2646
|
this.code.lines[lidx].slice(0, cursor.position),
|
|
@@ -2591,7 +2650,7 @@ class CodeEditor {
|
|
|
2591
2650
|
}
|
|
2592
2651
|
this.cursorToRight(key, cursor);
|
|
2593
2652
|
// Some custom cases for auto key pair (), {}, "", '', ...
|
|
2594
|
-
const keyMustPair = this.pairKeys[key] !== undefined;
|
|
2653
|
+
const keyMustPair = (this.pairKeys[key] !== undefined) && (!nextChar || /\s/.test(nextChar));
|
|
2595
2654
|
if (keyMustPair && !this.wasKeyPaired) {
|
|
2596
2655
|
// Make sure to detect later that the key is paired automatically to avoid loops...
|
|
2597
2656
|
this.wasKeyPaired = true;
|
|
@@ -2967,8 +3026,7 @@ class CodeEditor {
|
|
|
2967
3026
|
if (blockComments && this._buildingBlockComment != undefined
|
|
2968
3027
|
&& token.substr(0, blockCommentsTokens[1].length) == blockCommentsTokens[1]) {
|
|
2969
3028
|
const [commentLineNumber, tokenPos] = this._buildingBlockComment;
|
|
2970
|
-
this._blockCommentCache.push([new LX.vec2(commentLineNumber, lineNumber),
|
|
2971
|
-
new LX.vec2(tokenPos, tokenStartIndex)]);
|
|
3029
|
+
this._blockCommentCache.push([new LX.vec2(commentLineNumber, lineNumber), new LX.vec2(tokenPos, tokenStartIndex)]);
|
|
2972
3030
|
delete this._buildingBlockComment;
|
|
2973
3031
|
}
|
|
2974
3032
|
if (token !== '{') {
|
|
@@ -3229,16 +3287,13 @@ class CodeEditor {
|
|
|
3229
3287
|
// Add regexes to detect methods, variables ( including "id : nativeType" )
|
|
3230
3288
|
{
|
|
3231
3289
|
if (nativeTypes) {
|
|
3232
|
-
topLevelRegexes.push([new RegExp(`^(?:${nativeTypes.join('|')})\\s+([A-Za-z0-9_]+)\s*[\(]+`),
|
|
3233
|
-
'method']);
|
|
3290
|
+
topLevelRegexes.push([new RegExp(`^(?:${nativeTypes.join('|')})\\s+([A-Za-z0-9_]+)\s*[\(]+`), 'method']);
|
|
3234
3291
|
if (this.highlight === 'WGSL') {
|
|
3235
|
-
topLevelRegexes.push([new RegExp(`[A-Za-z0-9]+(\\s*)+:(\\s*)+(${nativeTypes.join('|')})`),
|
|
3236
|
-
'variable', (m) => m[0].split(':')[0].trim()]);
|
|
3292
|
+
topLevelRegexes.push([new RegExp(`[A-Za-z0-9]+(\\s*)+:(\\s*)+(${nativeTypes.join('|')})`), 'variable', (m) => m[0].split(':')[0].trim()]);
|
|
3237
3293
|
}
|
|
3238
3294
|
}
|
|
3239
3295
|
const declarationKeywords = CodeEditor.declarationKeywords[this.highlight] ?? ['const', 'let', 'var'];
|
|
3240
|
-
topLevelRegexes.push([new RegExp(`^(?:${declarationKeywords.join('|')})\\s+([A-Za-z0-9_]+)`),
|
|
3241
|
-
'variable']);
|
|
3296
|
+
topLevelRegexes.push([new RegExp(`^(?:${declarationKeywords.join('|')})\\s+([A-Za-z0-9_]+)`), 'variable']);
|
|
3242
3297
|
}
|
|
3243
3298
|
for (let [regex, kind, fn] of topLevelRegexes) {
|
|
3244
3299
|
const m = text.match(regex);
|
|
@@ -3455,8 +3510,7 @@ class CodeEditor {
|
|
|
3455
3510
|
return wordCategory[this.highlight] && wordCategory[this.highlight].has(t);
|
|
3456
3511
|
}
|
|
3457
3512
|
_getTokenHighlighting(ctx, highlight) {
|
|
3458
|
-
const rules = [...HighlightRules.common, ...(HighlightRules[highlight] || []),
|
|
3459
|
-
...HighlightRules.post_common];
|
|
3513
|
+
const rules = [...HighlightRules.common, ...(HighlightRules[highlight] || []), ...HighlightRules.post_common];
|
|
3460
3514
|
for (const rule of rules) {
|
|
3461
3515
|
if (!rule.test(ctx, this)) {
|
|
3462
3516
|
continue;
|
|
@@ -3809,12 +3863,11 @@ class CodeEditor {
|
|
|
3809
3863
|
}
|
|
3810
3864
|
deleteSelection(cursor) {
|
|
3811
3865
|
// I think it's not necessary but...
|
|
3812
|
-
if (this.disableEdition) {
|
|
3866
|
+
if (this.disableEdition || !cursor.selection) {
|
|
3813
3867
|
return;
|
|
3814
3868
|
}
|
|
3815
3869
|
// Some selections don't depend on mouse up..
|
|
3816
|
-
|
|
3817
|
-
cursor.selection.invertIfNecessary();
|
|
3870
|
+
cursor.selection.invertIfNecessary();
|
|
3818
3871
|
const selection = cursor.selection;
|
|
3819
3872
|
const separator = '_NEWLINE_';
|
|
3820
3873
|
let code = this.code.lines.join(separator);
|
|
@@ -4002,7 +4055,7 @@ class CodeEditor {
|
|
|
4002
4055
|
}
|
|
4003
4056
|
LX.deleteElement(this.selections[cursor.name]);
|
|
4004
4057
|
delete this.selections[cursor.name];
|
|
4005
|
-
|
|
4058
|
+
cursor.destroy();
|
|
4006
4059
|
}
|
|
4007
4060
|
resetCursorPos(flag, cursor, resetScroll = false) {
|
|
4008
4061
|
cursor = cursor ?? this.getCurrentCursor();
|
|
@@ -4341,8 +4394,7 @@ class CodeEditor {
|
|
|
4341
4394
|
text.innerText = char;
|
|
4342
4395
|
var rect = text.getBoundingClientRect();
|
|
4343
4396
|
LX.deleteElement(parentContainer);
|
|
4344
|
-
const bb = [useFloating ? rect.width : Math.floor(rect.width),
|
|
4345
|
-
useFloating ? rect.height : Math.floor(rect.height)];
|
|
4397
|
+
const bb = [useFloating ? rect.width : Math.floor(rect.width), useFloating ? rect.height : Math.floor(rect.height)];
|
|
4346
4398
|
return getBB ? bb : bb[0];
|
|
4347
4399
|
}
|
|
4348
4400
|
measureString(str) {
|
|
@@ -4442,15 +4494,15 @@ class CodeEditor {
|
|
|
4442
4494
|
{
|
|
4443
4495
|
case 'variable':
|
|
4444
4496
|
iconName = 'Cuboid';
|
|
4445
|
-
iconClass = '
|
|
4497
|
+
iconClass = 'text-blue-400';
|
|
4446
4498
|
break;
|
|
4447
4499
|
case 'method':
|
|
4448
4500
|
iconName = 'Box';
|
|
4449
|
-
iconClass = '
|
|
4501
|
+
iconClass = 'text-fuchsia-500';
|
|
4450
4502
|
break;
|
|
4451
4503
|
case 'class':
|
|
4452
4504
|
iconName = 'CircleNodes';
|
|
4453
|
-
iconClass = '
|
|
4505
|
+
iconClass = 'text-orange-500';
|
|
4454
4506
|
break;
|
|
4455
4507
|
}
|
|
4456
4508
|
}
|
|
@@ -4460,7 +4512,7 @@ class CodeEditor {
|
|
|
4460
4512
|
}
|
|
4461
4513
|
else if (this._mustHightlightWord(currSuggestion, CodeEditor.types)) {
|
|
4462
4514
|
iconName = 'Type';
|
|
4463
|
-
iconClass = '
|
|
4515
|
+
iconClass = 'text-blue-400';
|
|
4464
4516
|
}
|
|
4465
4517
|
}
|
|
4466
4518
|
pre.appendChild(LX.makeIcon(iconName, { iconClass: 'mr-1', svgClass: 'sm ' + iconClass }));
|
|
@@ -4491,8 +4543,7 @@ class CodeEditor {
|
|
|
4491
4543
|
this.autocomplete.classList.toggle('show', true);
|
|
4492
4544
|
this.autocomplete.classList.toggle('no-scrollbar', !(this.autocomplete.scrollHeight > this.autocomplete.offsetHeight));
|
|
4493
4545
|
this.autocomplete.style.left = `${Math.min(cursor.left + CodeEditor.LINE_GUTTER_WIDTH - this.getScrollLeft(), maxX)}px`;
|
|
4494
|
-
this.autocomplete.style.top =
|
|
4495
|
-
`${(cursor.top + this._verticalTopOffset + this.lineHeight - this.getScrollTop())}px`;
|
|
4546
|
+
this.autocomplete.style.top = `${(cursor.top + this._verticalTopOffset + this.lineHeight - this.getScrollTop())}px`;
|
|
4496
4547
|
this.isAutoCompleteActive = true;
|
|
4497
4548
|
}
|
|
4498
4549
|
hideAutoCompleteBox() {
|
|
@@ -4729,8 +4780,10 @@ class CodeEditor {
|
|
|
4729
4780
|
var newCursor = this._addCursor(ln, col, true);
|
|
4730
4781
|
if (newCursor) {
|
|
4731
4782
|
this.startSelection(newCursor);
|
|
4732
|
-
newCursor
|
|
4733
|
-
|
|
4783
|
+
if (newCursor.selection) {
|
|
4784
|
+
newCursor.selection.selectInline(newCursor, col, ln, this.measureString(text));
|
|
4785
|
+
this.cursorToString(newCursor, text);
|
|
4786
|
+
}
|
|
4734
4787
|
}
|
|
4735
4788
|
this._currentOcurrences[key] = true;
|
|
4736
4789
|
}, true, false);
|
|
@@ -4838,117 +4891,99 @@ class CodeEditor {
|
|
|
4838
4891
|
}
|
|
4839
4892
|
const CE = CodeEditor;
|
|
4840
4893
|
CE.languages = {
|
|
4841
|
-
'Plain Text': { ext: 'txt', blockComments: false, singleLineComments: false, numbers: false,
|
|
4842
|
-
|
|
4843
|
-
'
|
|
4844
|
-
'
|
|
4845
|
-
'C': { ext: ['
|
|
4846
|
-
'
|
|
4847
|
-
icon: { 'cpp': 'CPlusPlus fg-sky-400', 'hpp': 'CPlusPlus fg-fuchsia-500' } },
|
|
4848
|
-
'CSS': { ext: 'css', icon: 'Hash fg-blue-700' },
|
|
4894
|
+
'Plain Text': { ext: 'txt', blockComments: false, singleLineComments: false, numbers: false, icon: 'AlignLeft text-neutral-500' },
|
|
4895
|
+
'JavaScript': { ext: 'js', icon: 'Js text-yellow-500' },
|
|
4896
|
+
'TypeScript': { ext: 'ts', icon: 'Ts text-blue-600' },
|
|
4897
|
+
'C': { ext: ['c', 'h'], usePreprocessor: true, icon: { 'c': 'C text-sky-400', 'h': 'C text-fuchsia-500' } },
|
|
4898
|
+
'C++': { ext: ['cpp', 'hpp'], usePreprocessor: true, icon: { 'cpp': 'CPlusPlus text-sky-400', 'hpp': 'CPlusPlus text-fuchsia-500' } },
|
|
4899
|
+
'CSS': { ext: 'css', icon: 'Hash text-blue-700' },
|
|
4849
4900
|
'CMake': { ext: 'cmake', singleLineCommentToken: '#', blockComments: false, ignoreCase: true },
|
|
4850
4901
|
'GLSL': { ext: 'glsl', usePreprocessor: true },
|
|
4851
4902
|
'WGSL': { ext: 'wgsl', usePreprocessor: true },
|
|
4852
|
-
'JSON': { ext: 'json', blockComments: false, singleLineComments: false, icon: 'Json
|
|
4853
|
-
'XML': { ext: 'xml', tags: true, icon: 'Rss
|
|
4854
|
-
'Rust': { ext: 'rs', icon: 'Rust
|
|
4855
|
-
'Python': { ext: 'py', singleLineCommentToken: '#', icon: 'Python
|
|
4856
|
-
'HTML': { ext: 'html', tags: true, singleLineComments: false, blockCommentsTokens: ['<!--', '-->'],
|
|
4857
|
-
|
|
4858
|
-
'Batch': { ext: 'bat', blockComments: false, singleLineCommentToken: '::', ignoreCase: true,
|
|
4859
|
-
|
|
4860
|
-
'
|
|
4861
|
-
icon: 'Markdown fg-primary' },
|
|
4862
|
-
'PHP': { ext: 'php', icon: 'Php fg-purple-700' }
|
|
4903
|
+
'JSON': { ext: 'json', blockComments: false, singleLineComments: false, icon: 'Json text-yellow-400' },
|
|
4904
|
+
'XML': { ext: 'xml', tags: true, icon: 'Rss text-orange-500' },
|
|
4905
|
+
'Rust': { ext: 'rs', icon: 'Rust text-foreground' },
|
|
4906
|
+
'Python': { ext: 'py', singleLineCommentToken: '#', icon: 'Python text-cyan-600' },
|
|
4907
|
+
'HTML': { ext: 'html', tags: true, singleLineComments: false, blockCommentsTokens: ['<!--', '-->'], numbers: false,
|
|
4908
|
+
icon: 'Code text-orange-500' },
|
|
4909
|
+
'Batch': { ext: 'bat', blockComments: false, singleLineCommentToken: '::', ignoreCase: true, icon: 'Windows text-blue-400' },
|
|
4910
|
+
'Markdown': { ext: 'md', blockComments: false, singleLineCommentToken: '::', tags: true, numbers: false, icon: 'Markdown text-foreground' },
|
|
4911
|
+
'PHP': { ext: 'php', icon: 'Php text-purple-700' }
|
|
4863
4912
|
};
|
|
4864
4913
|
CE.nativeTypes = {
|
|
4865
4914
|
'C++': ['int', 'float', 'double', 'bool', 'long', 'short', 'char', 'wchar_t', 'void'],
|
|
4866
|
-
'WGSL': ['bool', 'u32', 'i32', 'f16', 'f32', 'vec2', 'vec3', 'vec4', 'vec2f', 'vec3f', 'vec4f', 'mat2x2f',
|
|
4867
|
-
'
|
|
4915
|
+
'WGSL': ['bool', 'u32', 'i32', 'f16', 'f32', 'vec2', 'vec3', 'vec4', 'vec2f', 'vec3f', 'vec4f', 'mat2x2f', 'mat3x3f', 'mat4x4f', 'array',
|
|
4916
|
+
'vec2u', 'vec3u', 'vec4u', 'ptr', 'sampler']
|
|
4868
4917
|
};
|
|
4869
4918
|
CE.declarationKeywords = {
|
|
4870
4919
|
'JavaScript': ['var', 'let', 'const', 'this', 'static', 'class'],
|
|
4871
4920
|
'C++': [...CE.nativeTypes['C++'], 'const', 'auto', 'class', 'struct', 'namespace', 'enum', 'extern']
|
|
4872
4921
|
};
|
|
4873
4922
|
CE.keywords = {
|
|
4874
|
-
'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static',
|
|
4875
|
-
'
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
'
|
|
4884
|
-
|
|
4885
|
-
'
|
|
4886
|
-
'set_target_properties', 'set_property', 'add_compile_options', 'add_link_options', 'include_directories',
|
|
4887
|
-
'add_library', 'target_link_libraries', 'target_link_options', 'add_subdirectory', 'add_compile_definitions',
|
|
4888
|
-
'project', 'cache'],
|
|
4923
|
+
'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static', 'class', 'constructor', 'null',
|
|
4924
|
+
'typeof', 'debugger', 'abstract', 'arguments', 'extends', 'instanceof', 'Infinity', 'get'],
|
|
4925
|
+
'TypeScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'class', 'extends', 'instanceof', 'Infinity',
|
|
4926
|
+
'private', 'public', 'protected', 'interface', 'enum', 'type', 'get'],
|
|
4927
|
+
'C': ['int', 'float', 'double', 'long', 'short', 'char', 'const', 'void', 'true', 'false', 'auto', 'struct', 'typedef', 'signed', 'volatile',
|
|
4928
|
+
'unsigned', 'static', 'extern', 'enum', 'register', 'union'],
|
|
4929
|
+
'C++': [...CE.nativeTypes['C++'], 'const', 'static_cast', 'dynamic_cast', 'new', 'delete', 'true', 'false', 'auto', 'class', 'struct', 'typedef',
|
|
4930
|
+
'nullptr', 'NULL', 'signed', 'unsigned', 'namespace', 'enum', 'extern', 'union', 'sizeof', 'static', 'private', 'public'],
|
|
4931
|
+
'CMake': ['cmake_minimum_required', 'set', 'not', 'if', 'endif', 'exists', 'string', 'strequal', 'add_definitions', 'macro', 'endmacro', 'file',
|
|
4932
|
+
'list', 'source_group', 'add_executable', 'target_include_directories', 'set_target_properties', 'set_property', 'add_compile_options',
|
|
4933
|
+
'add_link_options', 'include_directories', 'add_library', 'target_link_libraries', 'target_link_options', 'add_subdirectory',
|
|
4934
|
+
'add_compile_definitions', 'project', 'cache'],
|
|
4889
4935
|
'JSON': ['true', 'false'],
|
|
4890
|
-
'GLSL': ['true', 'false', 'function', 'int', 'float', 'vec2', 'vec3', 'vec4', 'mat2x2', 'mat3x3', 'mat4x4',
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
'
|
|
4895
|
-
|
|
4896
|
-
'texture_depth_2d', 'texture_depth_2d_array', 'texture_depth_cube', 'texture_depth_cube_array',
|
|
4897
|
-
'texture_depth_multisampled_2d', 'texture_external', 'texture_1d', 'texture_2d', 'texture_2d_array',
|
|
4898
|
-
'texture_3d', 'texture_cube', 'texture_cube_array', 'texture_storage_1d', 'texture_storage_2d',
|
|
4936
|
+
'GLSL': ['true', 'false', 'function', 'int', 'float', 'vec2', 'vec3', 'vec4', 'mat2x2', 'mat3x3', 'mat4x4', 'struct'],
|
|
4937
|
+
'CSS': ['body', 'html', 'canvas', 'div', 'input', 'span', '.', 'table', 'tr', 'td', 'th', 'label', 'video', 'img', 'code', 'button', 'select',
|
|
4938
|
+
'option', 'svg', 'media', 'all', 'i', 'a', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'last-child', 'tbody', 'pre', 'monospace', 'font-face'],
|
|
4939
|
+
'WGSL': [...CE.nativeTypes['WGSL'], 'var', 'let', 'true', 'false', 'fn', 'atomic', 'struct', 'sampler_comparison', 'texture_depth_2d',
|
|
4940
|
+
'texture_depth_2d_array', 'texture_depth_cube', 'texture_depth_cube_array', 'texture_depth_multisampled_2d', 'texture_external', 'texture_1d',
|
|
4941
|
+
'texture_2d', 'texture_2d_array', 'texture_3d', 'texture_cube', 'texture_cube_array', 'texture_storage_1d', 'texture_storage_2d',
|
|
4899
4942
|
'texture_storage_2d_array', 'texture_storage_3d'],
|
|
4900
|
-
'Rust': ['as', 'const', 'crate', 'enum', 'extern', 'false', 'fn', 'impl', 'in', 'let', 'mod', 'move', 'mut', 'pub',
|
|
4901
|
-
'
|
|
4902
|
-
'
|
|
4943
|
+
'Rust': ['as', 'const', 'crate', 'enum', 'extern', 'false', 'fn', 'impl', 'in', 'let', 'mod', 'move', 'mut', 'pub', 'ref', 'self', 'Self',
|
|
4944
|
+
'static', 'struct', 'super', 'trait', 'true', 'type', 'unsafe', 'use', 'where', 'abstract', 'become', 'box', 'final', 'macro', 'override',
|
|
4945
|
+
'priv', 'typeof', 'unsized', 'virtual'],
|
|
4903
4946
|
'Python': ['False', 'def', 'None', 'True', 'in', 'is', 'and', 'lambda', 'nonlocal', 'not', 'or'],
|
|
4904
4947
|
'Batch': ['set', 'echo', 'off', 'del', 'defined', 'setlocal', 'enabledelayedexpansion', 'driverquery', 'print'],
|
|
4905
|
-
'HTML': ['html', 'meta', 'title', 'link', 'script', 'body', 'DOCTYPE', 'head', 'br', 'i', 'a', 'li', 'img', 'tr',
|
|
4906
|
-
'
|
|
4948
|
+
'HTML': ['html', 'meta', 'title', 'link', 'script', 'body', 'DOCTYPE', 'head', 'br', 'i', 'a', 'li', 'img', 'tr', 'td', 'h1', 'h2', 'h3', 'h4',
|
|
4949
|
+
'h5'],
|
|
4907
4950
|
'Markdown': ['br', 'i', 'a', 'li', 'img', 'table', 'title', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5'],
|
|
4908
|
-
'PHP': ['const', 'function', 'array', 'new', 'int', 'string', '$this', 'public', 'null', 'private', 'protected',
|
|
4909
|
-
'
|
|
4951
|
+
'PHP': ['const', 'function', 'array', 'new', 'int', 'string', '$this', 'public', 'null', 'private', 'protected', 'implements', 'class', 'use',
|
|
4952
|
+
'namespace', 'abstract', 'clone', 'final', 'enum']
|
|
4910
4953
|
};
|
|
4911
4954
|
// These ones don't have hightlight, used as suggestions to autocomplete only...
|
|
4912
4955
|
CE.utils = {
|
|
4913
|
-
'JavaScript': ['querySelector', 'body', 'addEventListener', 'removeEventListener', 'remove', 'sort', 'keys',
|
|
4914
|
-
'
|
|
4915
|
-
'
|
|
4916
|
-
'createElement', 'prompt', 'alert'],
|
|
4956
|
+
'JavaScript': ['querySelector', 'body', 'addEventListener', 'removeEventListener', 'remove', 'sort', 'keys', 'filter', 'isNaN', 'parseFloat',
|
|
4957
|
+
'parseInt', 'EPSILON', 'isFinite', 'bind', 'prototype', 'length', 'assign', 'entries', 'values', 'concat', 'substring', 'substr', 'splice',
|
|
4958
|
+
'slice', 'buffer', 'appendChild', 'createElement', 'prompt', 'alert'],
|
|
4917
4959
|
'WGSL': ['textureSample'],
|
|
4918
|
-
'Python': ['abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod',
|
|
4919
|
-
'
|
|
4920
|
-
'
|
|
4921
|
-
'
|
|
4922
|
-
'
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
'
|
|
4926
|
-
'
|
|
4927
|
-
'
|
|
4928
|
-
'
|
|
4929
|
-
'
|
|
4930
|
-
'
|
|
4931
|
-
'
|
|
4932
|
-
'conic-gradient', 'url', 'calc', 'min', 'max', 'clamp', 'red', 'blue', 'green', 'black', 'white', 'gray',
|
|
4933
|
-
'silver', 'yellow', 'orange', 'purple', 'pink', 'cyan', 'magenta', 'lime', 'teal', 'navy', 'transparent',
|
|
4934
|
-
'currentcolor', 'inherit', 'initial', 'unset', 'revert', 'none', 'auto', 'fit-content', 'min-content',
|
|
4935
|
-
'max-content']
|
|
4960
|
+
'Python': ['abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'delattr',
|
|
4961
|
+
'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash',
|
|
4962
|
+
'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next',
|
|
4963
|
+
'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted',
|
|
4964
|
+
'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip'],
|
|
4965
|
+
'CSS': [...Object.keys(document.body.style).map(LX.toKebabCase), 'block', 'inline', 'inline-block', 'flex', 'grid', 'none', 'inherit',
|
|
4966
|
+
'initial', 'unset', 'revert', 'sticky', 'relative', 'absolute', 'fixed', 'static', 'auto', 'visible', 'hidden', 'scroll', 'clip', 'ellipsis',
|
|
4967
|
+
'nowrap', 'wrap', 'break-word', 'solid', 'dashed', 'dotted', 'double', 'groove', 'ridge', 'inset', 'outset', 'left', 'right', 'center', 'top',
|
|
4968
|
+
'bottom', 'start', 'end', 'justify', 'stretch', 'space-between', 'space-around', 'space-evenly', 'baseline', 'middle', 'normal', 'bold',
|
|
4969
|
+
'lighter', 'bolder', 'italic', 'blur', 'uppercase', 'lowercase', 'capitalize', 'transparent', 'currentColor', 'pointer', 'default', 'move',
|
|
4970
|
+
'grab', 'grabbing', 'not-allowed', 'none', 'cover', 'contain', 'repeat', 'no-repeat', 'repeat-x', 'repeat-y', 'round', 'space',
|
|
4971
|
+
'linear-gradient', 'radial-gradient', 'conic-gradient', 'url', 'calc', 'min', 'max', 'clamp', 'red', 'blue', 'green', 'black', 'white',
|
|
4972
|
+
'gray', 'silver', 'yellow', 'orange', 'purple', 'pink', 'cyan', 'magenta', 'lime', 'teal', 'navy', 'transparent', 'currentcolor', 'inherit',
|
|
4973
|
+
'initial', 'unset', 'revert', 'none', 'auto', 'fit-content', 'min-content', 'max-content']
|
|
4936
4974
|
};
|
|
4937
4975
|
CE.types = {
|
|
4938
|
-
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder',
|
|
4939
|
-
'
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
'
|
|
4943
|
-
'ArrayBuffer', 'InputEvent', 'MouseEvent', 'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array',
|
|
4944
|
-
'Float64Array', 'Element', 'bigint', 'unknown', 'any', 'Record'],
|
|
4976
|
+
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer',
|
|
4977
|
+
'InputEvent', 'MouseEvent', 'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element'],
|
|
4978
|
+
'TypeScript': ['arguments', 'constructor', 'null', 'typeof', 'debugger', 'abstract', 'Object', 'string', 'String', 'Function', 'Boolean',
|
|
4979
|
+
'boolean', 'Error', 'Number', 'number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer', 'InputEvent', 'MouseEvent', 'Int8Array',
|
|
4980
|
+
'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element', 'bigint', 'unknown', 'any', 'Record'],
|
|
4945
4981
|
'Rust': ['u128'],
|
|
4946
|
-
'Python': ['int', 'type', 'float', 'map', 'list', 'ArithmeticError', 'AssertionError', 'AttributeError',
|
|
4947
|
-
'
|
|
4948
|
-
'
|
|
4949
|
-
'
|
|
4950
|
-
'
|
|
4951
|
-
'UnicodeTranslateError', 'ValueError', 'ZeroDivisionError'],
|
|
4982
|
+
'Python': ['int', 'type', 'float', 'map', 'list', 'ArithmeticError', 'AssertionError', 'AttributeError', 'Exception', 'EOFError',
|
|
4983
|
+
'FloatingPointError', 'GeneratorExit', 'ImportError', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
|
|
4984
|
+
'MemoryError', 'NameError', 'NotImplementedError', 'OSError', 'OverflowError', 'ReferenceError', 'RuntimeError', 'StopIteration',
|
|
4985
|
+
'SyntaxError', 'TabError', 'SystemError', 'SystemExit', 'TypeError', 'UnboundLocalError', 'UnicodeError', 'UnicodeEncodeError',
|
|
4986
|
+
'UnicodeDecodeError', 'UnicodeTranslateError', 'ValueError', 'ZeroDivisionError'],
|
|
4952
4987
|
'C++': ['uint8_t', 'uint16_t', 'uint32_t'],
|
|
4953
4988
|
'PHP': ['Exception', 'DateTime', 'JsonSerializable']
|
|
4954
4989
|
};
|
|
@@ -4962,25 +4997,22 @@ CE.builtIn = {
|
|
|
4962
4997
|
'PHP': ['echo', 'print']
|
|
4963
4998
|
};
|
|
4964
4999
|
CE.statements = {
|
|
4965
|
-
'JavaScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import',
|
|
4966
|
-
'
|
|
4967
|
-
'TypeScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import',
|
|
4968
|
-
'
|
|
5000
|
+
'JavaScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'default', 'export', 'from',
|
|
5001
|
+
'throw', 'async', 'try', 'catch', 'await', 'as'],
|
|
5002
|
+
'TypeScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'default', 'export', 'from',
|
|
5003
|
+
'throw', 'async', 'try', 'catch', 'await', 'as'],
|
|
4969
5004
|
'CSS': ['@', 'import'],
|
|
4970
|
-
'C': ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'using', 'default', 'goto',
|
|
4971
|
-
|
|
4972
|
-
'C++': ['std', 'for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'using', 'glm',
|
|
4973
|
-
'spdlog', 'default'],
|
|
5005
|
+
'C': ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'using', 'default', 'goto', 'do'],
|
|
5006
|
+
'C++': ['std', 'for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'using', 'glm', 'spdlog', 'default'],
|
|
4974
5007
|
'GLSL': ['for', 'if', 'else', 'return', 'continue', 'break'],
|
|
4975
|
-
'WGSL': ['const', 'for', 'if', 'else', 'return', 'continue', 'break', 'storage', 'read', 'read_write', 'uniform',
|
|
4976
|
-
'
|
|
5008
|
+
'WGSL': ['const', 'for', 'if', 'else', 'return', 'continue', 'break', 'storage', 'read', 'read_write', 'uniform', 'function', 'workgroup',
|
|
5009
|
+
'bitcast'],
|
|
4977
5010
|
'Rust': ['break', 'else', 'continue', 'for', 'if', 'loop', 'match', 'return', 'while', 'do', 'yield'],
|
|
4978
|
-
'Python': ['if', 'raise', 'del', 'import', 'return', 'elif', 'try', 'else', 'while', 'as', 'except', 'with',
|
|
4979
|
-
'
|
|
5011
|
+
'Python': ['if', 'raise', 'del', 'import', 'return', 'elif', 'try', 'else', 'while', 'as', 'except', 'with', 'assert', 'finally', 'yield',
|
|
5012
|
+
'break', 'for', 'class', 'continue', 'global', 'pass', 'from'],
|
|
4980
5013
|
'Batch': ['if', 'IF', 'for', 'FOR', 'in', 'IN', 'do', 'DO', 'call', 'CALL', 'goto', 'GOTO', 'exit', 'EXIT'],
|
|
4981
|
-
'PHP': ['declare', 'enddeclare', 'foreach', 'endforeach', 'if', 'else', 'elseif', 'endif', 'for', 'endfor',
|
|
4982
|
-
'
|
|
4983
|
-
'die', 'do', 'exit', 'finally']
|
|
5014
|
+
'PHP': ['declare', 'enddeclare', 'foreach', 'endforeach', 'if', 'else', 'elseif', 'endif', 'for', 'endfor', 'while', 'endwhile', 'switch',
|
|
5015
|
+
'case', 'default', 'endswitch', 'return', 'break', 'continue', 'try', 'catch', 'die', 'do', 'exit', 'finally']
|
|
4984
5016
|
};
|
|
4985
5017
|
CE.symbols = {
|
|
4986
5018
|
'JavaScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
|