lexgui 0.1.26 → 0.1.27
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 +199 -135
- package/build/lexgui.js +4 -1
- package/build/lexgui.module.js +4 -1
- package/changelog.md +10 -0
- package/package.json +1 -1
|
@@ -377,17 +377,7 @@ class CodeEditor {
|
|
|
377
377
|
this.xPadding = "48px";
|
|
378
378
|
|
|
379
379
|
// Add main cursor
|
|
380
|
-
|
|
381
|
-
this._addCursor( 0, 0, true, true );
|
|
382
|
-
|
|
383
|
-
Object.defineProperty( this, 'line', {
|
|
384
|
-
get: (v) => { return this._getCurrentCursor().line }
|
|
385
|
-
} );
|
|
386
|
-
|
|
387
|
-
Object.defineProperty( this, 'position', {
|
|
388
|
-
get: (v) => { return this._getCurrentCursor().position }
|
|
389
|
-
} );
|
|
390
|
-
}
|
|
380
|
+
this._addCursor( 0, 0, true, true );
|
|
391
381
|
|
|
392
382
|
// Scroll stuff
|
|
393
383
|
{
|
|
@@ -600,12 +590,17 @@ class CodeEditor {
|
|
|
600
590
|
|
|
601
591
|
// Convert reserved word arrays to maps so we can search tokens faster
|
|
602
592
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
593
|
+
if( !CodeEditor._staticReady )
|
|
594
|
+
{
|
|
595
|
+
for( let lang in CodeEditor.keywords ) CodeEditor.keywords[lang] = CodeEditor.keywords[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
596
|
+
for( let lang in CodeEditor.utils ) CodeEditor.utils[lang] = CodeEditor.utils[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
597
|
+
for( let lang in CodeEditor.types ) CodeEditor.types[lang] = CodeEditor.types[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
598
|
+
for( let lang in CodeEditor.builtin ) CodeEditor.builtin[lang] = CodeEditor.builtin[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
599
|
+
for( let lang in CodeEditor.statementsAndDeclarations ) CodeEditor.statementsAndDeclarations[lang] = CodeEditor.statementsAndDeclarations[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
600
|
+
for( let lang in CodeEditor.symbols ) CodeEditor.symbols[lang] = CodeEditor.symbols[lang].reduce((a, v) => ({ ...a, [v]: true}), {});
|
|
601
|
+
|
|
602
|
+
CodeEditor._staticReady = true;
|
|
603
|
+
}
|
|
609
604
|
|
|
610
605
|
// Action keys
|
|
611
606
|
|
|
@@ -698,14 +693,31 @@ class CodeEditor {
|
|
|
698
693
|
|
|
699
694
|
this.action( 'Tab', true, ( ln, cursor, e ) => {
|
|
700
695
|
|
|
701
|
-
if( this.
|
|
696
|
+
if( this._skipTabs )
|
|
697
|
+
{
|
|
698
|
+
this._skipTabs--;
|
|
699
|
+
if( !this._skipTabs )
|
|
700
|
+
delete this._skipTabs;
|
|
701
|
+
}
|
|
702
|
+
else if( this.isAutoCompleteActive )
|
|
702
703
|
{
|
|
703
|
-
this.autoCompleteWord(
|
|
704
|
-
}
|
|
704
|
+
this.autoCompleteWord();
|
|
705
|
+
}
|
|
706
|
+
else
|
|
705
707
|
{
|
|
706
|
-
this.
|
|
708
|
+
this._addUndoStep( cursor );
|
|
709
|
+
|
|
710
|
+
if( e && e.shiftKey )
|
|
711
|
+
{
|
|
712
|
+
this._removeSpaces( cursor );
|
|
713
|
+
}
|
|
714
|
+
else
|
|
715
|
+
{
|
|
716
|
+
const indentSpaces = this.tabSpaces - (cursor.position % this.tabSpaces);
|
|
717
|
+
this._addSpaces( indentSpaces );
|
|
718
|
+
}
|
|
707
719
|
}
|
|
708
|
-
});
|
|
720
|
+
}, "shiftKey");
|
|
709
721
|
|
|
710
722
|
this.action( 'Home', false, ( ln, cursor, e ) => {
|
|
711
723
|
|
|
@@ -718,7 +730,8 @@ class CodeEditor {
|
|
|
718
730
|
let lastX = cursor.position;
|
|
719
731
|
|
|
720
732
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT, cursor );
|
|
721
|
-
if(idx > 0)
|
|
733
|
+
if(idx > 0)
|
|
734
|
+
this.cursorToString( cursor, prestring );
|
|
722
735
|
this.setScrollLeft( 0 );
|
|
723
736
|
|
|
724
737
|
// Merge cursors
|
|
@@ -777,7 +790,7 @@ class CodeEditor {
|
|
|
777
790
|
// Add word
|
|
778
791
|
if( this.isAutoCompleteActive )
|
|
779
792
|
{
|
|
780
|
-
this.autoCompleteWord(
|
|
793
|
+
this.autoCompleteWord();
|
|
781
794
|
return;
|
|
782
795
|
}
|
|
783
796
|
|
|
@@ -804,10 +817,10 @@ class CodeEditor {
|
|
|
804
817
|
|
|
805
818
|
if( _c0 == '{' && _c1 == '}' ) {
|
|
806
819
|
this.code.lines.splice( cursor.line, 0, "" );
|
|
807
|
-
this.
|
|
820
|
+
this._addSpaceTabs( cursor, tabs + 1 );
|
|
808
821
|
this.code.lines[ cursor.line + 1 ] = " ".repeat(spaces) + this.code.lines[ cursor.line + 1 ];
|
|
809
822
|
} else {
|
|
810
|
-
this.
|
|
823
|
+
this._addSpaceTabs( cursor, tabs );
|
|
811
824
|
}
|
|
812
825
|
|
|
813
826
|
this.processLines();
|
|
@@ -1462,14 +1475,25 @@ class CodeEditor {
|
|
|
1462
1475
|
|
|
1463
1476
|
panel.sameLine();
|
|
1464
1477
|
panel.addLabel( this.code.title, { float: 'right', signal: "@tab-name" });
|
|
1465
|
-
panel.addLabel( "Ln " + 1, {
|
|
1466
|
-
panel.addLabel( "Col " + 1, {
|
|
1478
|
+
panel.addLabel( "Ln " + 1, { maxWidth: "48px", signal: "@cursor-line" });
|
|
1479
|
+
panel.addLabel( "Col " + 1, { maxWidth: "48px", signal: "@cursor-pos" });
|
|
1480
|
+
panel.addButton( null, "Spaces: " + this.tabSpaces, ( value, event ) => {
|
|
1481
|
+
LX.addContextMenu( "Spaces", event, m => {
|
|
1482
|
+
const options = [ 2, 4, 8 ];
|
|
1483
|
+
for( const n of options )
|
|
1484
|
+
m.add( n, (v) => {
|
|
1485
|
+
this.tabSpaces = v;
|
|
1486
|
+
this.processLines();
|
|
1487
|
+
this._updateDataInfoPanel( "@tab-spaces", "Spaces: " + this.tabSpaces );
|
|
1488
|
+
} );
|
|
1489
|
+
});
|
|
1490
|
+
}, { width: "10%", nameWidth: "15%", signal: "@tab-spaces" });
|
|
1467
1491
|
panel.addButton( "<b>{ }</b>", this.highlight, ( value, event ) => {
|
|
1468
1492
|
LX.addContextMenu( "Language", event, m => {
|
|
1469
1493
|
for( const lang of Object.keys(this.languages) )
|
|
1470
1494
|
m.add( lang, this._changeLanguage.bind(this) );
|
|
1471
1495
|
});
|
|
1472
|
-
}, { width: "
|
|
1496
|
+
}, { width: "17.5%", nameWidth: "15%", signal: "@highlight" });
|
|
1473
1497
|
panel.endLine();
|
|
1474
1498
|
|
|
1475
1499
|
return panel;
|
|
@@ -1878,8 +1902,8 @@ class CodeEditor {
|
|
|
1878
1902
|
let ccw = true;
|
|
1879
1903
|
|
|
1880
1904
|
// Check if we must change ccw or not ... (not with mouse)
|
|
1881
|
-
if( !isMouseEvent &&
|
|
1882
|
-
(
|
|
1905
|
+
if( !isMouseEvent && cursor.line >= cursor.selection.fromY &&
|
|
1906
|
+
(cursor.line == cursor.selection.fromY ? cursor.position >= cursor.selection.fromX : true) )
|
|
1883
1907
|
{
|
|
1884
1908
|
ccw = ( e && this._lastSelectionKeyDir && ( e.key == 'ArrowRight' || e.key == 'ArrowDown' || e.key == 'End' ) );
|
|
1885
1909
|
}
|
|
@@ -2231,10 +2255,12 @@ class CodeEditor {
|
|
|
2231
2255
|
|
|
2232
2256
|
for( const actKey in this.actions ) {
|
|
2233
2257
|
|
|
2234
|
-
if( key != actKey )
|
|
2258
|
+
if( key != actKey )
|
|
2259
|
+
continue;
|
|
2260
|
+
|
|
2235
2261
|
e.preventDefault();
|
|
2236
2262
|
|
|
2237
|
-
if( this.actions[ key ]
|
|
2263
|
+
if( this._actionMustDelete( cursor, this.actions[ key ], e ) )
|
|
2238
2264
|
this.actions['Backspace'].callback( lidx, cursor, e );
|
|
2239
2265
|
|
|
2240
2266
|
return this.actions[ key ].callback( lidx, cursor, e );
|
|
@@ -2529,14 +2555,22 @@ class CodeEditor {
|
|
|
2529
2555
|
}
|
|
2530
2556
|
}
|
|
2531
2557
|
|
|
2532
|
-
action( key, deleteSelection, fn ) {
|
|
2558
|
+
action( key, deleteSelection, fn, eventSkipDelete ) {
|
|
2533
2559
|
|
|
2534
2560
|
this.actions[ key ] = {
|
|
2561
|
+
"key": key,
|
|
2535
2562
|
"callback": fn,
|
|
2536
|
-
"deleteSelection": deleteSelection
|
|
2563
|
+
"deleteSelection": deleteSelection,
|
|
2564
|
+
"eventSkipDelete": eventSkipDelete
|
|
2537
2565
|
};
|
|
2538
2566
|
}
|
|
2539
2567
|
|
|
2568
|
+
_actionMustDelete( cursor, action, e ) {
|
|
2569
|
+
|
|
2570
|
+
return cursor.selection && action.deleteSelection &&
|
|
2571
|
+
( action.eventSkipDelete ? !e[ action.eventSkipDelete ] : true );
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2540
2574
|
scanWordSuggestions() {
|
|
2541
2575
|
|
|
2542
2576
|
this.code.tokens = {};
|
|
@@ -2861,111 +2895,98 @@ class CodeEditor {
|
|
|
2861
2895
|
|
|
2862
2896
|
const usesBlockComments = lang.blockComments ?? true;
|
|
2863
2897
|
const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
|
|
2898
|
+
const singleLineCommentToken = lang.singleLineCommentToken ?? this.defaultSingleLineCommentToken;
|
|
2899
|
+
|
|
2900
|
+
let token_classname = "";
|
|
2901
|
+
let discardToken = false;
|
|
2864
2902
|
|
|
2865
|
-
if(
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
}
|
|
2874
|
-
else
|
|
2875
|
-
{
|
|
2876
|
-
const singleLineCommentToken = lang.singleLineCommentToken ?? this.defaultSingleLineCommentToken;
|
|
2877
|
-
|
|
2878
|
-
let token_classname = "";
|
|
2879
|
-
let discardToken = false;
|
|
2880
|
-
|
|
2881
|
-
if( this._buildingBlockComment != undefined )
|
|
2882
|
-
token_classname = "cm-com";
|
|
2883
|
-
|
|
2884
|
-
else if( this._buildingString != undefined )
|
|
2885
|
-
discardToken = this._appendStringToken( token );
|
|
2886
|
-
|
|
2887
|
-
else if( this._mustHightlightWord( token, CodeEditor.keywords ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
2888
|
-
token_classname = "cm-kwd";
|
|
2903
|
+
if( this._buildingBlockComment != undefined )
|
|
2904
|
+
token_classname = "cm-com";
|
|
2905
|
+
|
|
2906
|
+
else if( this._buildingString != undefined )
|
|
2907
|
+
discardToken = this._appendStringToken( token );
|
|
2908
|
+
|
|
2909
|
+
else if( this._mustHightlightWord( token, CodeEditor.keywords ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
2910
|
+
token_classname = "cm-kwd";
|
|
2889
2911
|
|
|
2890
|
-
|
|
2891
|
-
|
|
2912
|
+
else if( this._mustHightlightWord( token, CodeEditor.builtin ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
2913
|
+
token_classname = "cm-bln";
|
|
2892
2914
|
|
|
2893
|
-
|
|
2894
|
-
|
|
2915
|
+
else if( this._mustHightlightWord( token, CodeEditor.statementsAndDeclarations ) )
|
|
2916
|
+
token_classname = "cm-std";
|
|
2895
2917
|
|
|
2896
|
-
|
|
2897
|
-
|
|
2918
|
+
else if( this._mustHightlightWord( token, CodeEditor.symbols ) )
|
|
2919
|
+
token_classname = "cm-sym";
|
|
2898
2920
|
|
|
2899
|
-
|
|
2900
|
-
|
|
2921
|
+
else if( token.substr( 0, singleLineCommentToken.length ) == singleLineCommentToken )
|
|
2922
|
+
token_classname = "cm-com";
|
|
2901
2923
|
|
|
2902
|
-
|
|
2903
|
-
|
|
2924
|
+
else if( this._isNumber( token ) || this._isNumber( token.replace(/[px]|[em]|%/g,'') ) )
|
|
2925
|
+
token_classname = "cm-dec";
|
|
2904
2926
|
|
|
2905
|
-
|
|
2906
|
-
|
|
2927
|
+
else if( this._isCSSClass( token, prev, next ) )
|
|
2928
|
+
token_classname = "cm-kwd";
|
|
2907
2929
|
|
|
2908
|
-
|
|
2909
|
-
|
|
2930
|
+
else if ( this._isType( token, prev, next ) )
|
|
2931
|
+
token_classname = "cm-typ";
|
|
2910
2932
|
|
|
2911
|
-
|
|
2912
|
-
|
|
2933
|
+
else if ( highlight == 'batch' && ( token == '@' || prev == ':' || prev == '@' ) )
|
|
2934
|
+
token_classname = "cm-kwd";
|
|
2913
2935
|
|
|
2914
|
-
|
|
2915
|
-
|
|
2936
|
+
else if ( [ 'cpp', 'wgsl', 'glsl' ].indexOf( highlight ) > -1 && token.includes( '#' ) ) // C++ preprocessor
|
|
2937
|
+
token_classname = "cm-ppc";
|
|
2916
2938
|
|
|
2917
|
-
|
|
2918
|
-
|
|
2939
|
+
else if ( highlight == 'cpp' && prev == '<' && (next == '>' || next == '*') ) // Defining template type in C++
|
|
2940
|
+
token_classname = "cm-typ";
|
|
2919
2941
|
|
|
2920
|
-
|
|
2921
|
-
|
|
2942
|
+
else if ( highlight == 'cpp' && (next == '::' || prev == '::' && next != '(' )) // C++ Class
|
|
2943
|
+
token_classname = "cm-typ";
|
|
2922
2944
|
|
|
2923
|
-
|
|
2924
|
-
|
|
2945
|
+
else if ( highlight == 'css' && prev == ':' && (next == ';' || next == '!important') ) // CSS value
|
|
2946
|
+
token_classname = "cm-str";
|
|
2925
2947
|
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2948
|
+
else if ( highlight == 'css' && prev == undefined && next == ':' ) // CSS attribute
|
|
2949
|
+
token_classname = "cm-typ";
|
|
2950
|
+
|
|
2951
|
+
else if ( this._markdownHeader || ( highlight == 'markdown' && isFirstToken && token.replaceAll('#', '').length != token.length ) ) // Header
|
|
2952
|
+
{
|
|
2953
|
+
token_classname = "cm-kwd";
|
|
2954
|
+
this._markdownHeader = true;
|
|
2955
|
+
}
|
|
2934
2956
|
|
|
2935
|
-
|
|
2936
|
-
|
|
2957
|
+
else if ( token[ 0 ] != '@' && token[ 0 ] != ',' && next == '(' )
|
|
2958
|
+
token_classname = "cm-mtd";
|
|
2937
2959
|
|
|
2938
2960
|
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2961
|
+
if( usesBlockComments && this._buildingBlockComment != undefined
|
|
2962
|
+
&& token.substr( 0, blockCommentsTokens[ 1 ].length ) == blockCommentsTokens[ 1 ] )
|
|
2963
|
+
{
|
|
2964
|
+
this._blockCommentCache.push( new LX.vec2( this._buildingBlockComment, this._currentLineNumber ) );
|
|
2965
|
+
delete this._buildingBlockComment;
|
|
2966
|
+
}
|
|
2945
2967
|
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2968
|
+
// We finished constructing a string
|
|
2969
|
+
if( this._buildingString && ( this._stringEnded || isLastToken ) )
|
|
2970
|
+
{
|
|
2971
|
+
token = this._getCurrentString();
|
|
2972
|
+
token_classname = "cm-str";
|
|
2973
|
+
discardToken = false;
|
|
2974
|
+
}
|
|
2953
2975
|
|
|
2954
|
-
|
|
2955
|
-
|
|
2976
|
+
// Update state
|
|
2977
|
+
this._buildingString = this._stringEnded ? undefined : this._buildingString;
|
|
2956
2978
|
|
|
2957
|
-
|
|
2958
|
-
|
|
2979
|
+
if( discardToken )
|
|
2980
|
+
return "";
|
|
2959
2981
|
|
|
2960
|
-
|
|
2961
|
-
|
|
2982
|
+
token = token.replace( "<", "<" );
|
|
2983
|
+
token = token.replace( ">", ">" );
|
|
2962
2984
|
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2985
|
+
// No highlighting, no need to put it inside another span..
|
|
2986
|
+
if( !token_classname.length )
|
|
2987
|
+
return token;
|
|
2966
2988
|
|
|
2967
|
-
|
|
2968
|
-
}
|
|
2989
|
+
return "<span class='" + highlight + " " + token_classname + "'>" + token + "</span>";
|
|
2969
2990
|
}
|
|
2970
2991
|
|
|
2971
2992
|
_appendStringToken( token ) {
|
|
@@ -3204,6 +3225,7 @@ class CodeEditor {
|
|
|
3204
3225
|
delete this._tripleClickSelection;
|
|
3205
3226
|
delete this._lastSelectionKeyDir;
|
|
3206
3227
|
delete this._currentOcurrences;
|
|
3228
|
+
delete this._lastResult;
|
|
3207
3229
|
|
|
3208
3230
|
if( cursor )
|
|
3209
3231
|
{
|
|
@@ -3428,14 +3450,14 @@ class CodeEditor {
|
|
|
3428
3450
|
}
|
|
3429
3451
|
}
|
|
3430
3452
|
|
|
3431
|
-
|
|
3453
|
+
_addSpaceTabs( cursor, n ) {
|
|
3432
3454
|
|
|
3433
3455
|
for( var i = 0; i < n; ++i ) {
|
|
3434
|
-
this.actions[ 'Tab' ].callback();
|
|
3456
|
+
this.actions[ 'Tab' ].callback( cursor.line, cursor, null );
|
|
3435
3457
|
}
|
|
3436
3458
|
}
|
|
3437
3459
|
|
|
3438
|
-
|
|
3460
|
+
_addSpaces( n ) {
|
|
3439
3461
|
|
|
3440
3462
|
for( var i = 0; i < n; ++i ) {
|
|
3441
3463
|
this.root.dispatchEvent( new CustomEvent( 'keydown', { 'detail': {
|
|
@@ -3446,6 +3468,37 @@ class CodeEditor {
|
|
|
3446
3468
|
}
|
|
3447
3469
|
}
|
|
3448
3470
|
|
|
3471
|
+
_removeSpaces( cursor ) {
|
|
3472
|
+
|
|
3473
|
+
// Remove indentation
|
|
3474
|
+
const lidx = cursor.line;
|
|
3475
|
+
const lineStart = firstNonspaceIndex( this.code.lines[ lidx ] );
|
|
3476
|
+
|
|
3477
|
+
// Nothing to remove...
|
|
3478
|
+
if( lineStart == 0 )
|
|
3479
|
+
return;
|
|
3480
|
+
|
|
3481
|
+
let indentSpaces = lineStart % this.tabSpaces;
|
|
3482
|
+
indentSpaces = indentSpaces == 0 ? this.tabSpaces : indentSpaces;
|
|
3483
|
+
const newStart = Math.max( lineStart - indentSpaces, 0 );
|
|
3484
|
+
|
|
3485
|
+
this.code.lines[ lidx ] = [
|
|
3486
|
+
this.code.lines[ lidx ].slice( 0, newStart ),
|
|
3487
|
+
this.code.lines[ lidx ].slice( lineStart )
|
|
3488
|
+
].join('');
|
|
3489
|
+
|
|
3490
|
+
this.processLine( lidx );
|
|
3491
|
+
|
|
3492
|
+
this.cursorToString( cursor, " ".repeat( indentSpaces ), true );
|
|
3493
|
+
|
|
3494
|
+
if( cursor.selection )
|
|
3495
|
+
{
|
|
3496
|
+
cursor.selection.invertIfNecessary();
|
|
3497
|
+
cursor.selection.fromX = Math.max( cursor.selection.fromX - indentSpaces, 0 );
|
|
3498
|
+
this._processSelection( cursor );
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
|
|
3449
3502
|
getScrollLeft() {
|
|
3450
3503
|
|
|
3451
3504
|
if( !this.codeScroller ) return 0;
|
|
@@ -3715,8 +3768,11 @@ class CodeEditor {
|
|
|
3715
3768
|
|
|
3716
3769
|
showAutoCompleteBox( key, cursor ) {
|
|
3717
3770
|
|
|
3771
|
+
if( !cursor.isMain )
|
|
3772
|
+
return;
|
|
3773
|
+
|
|
3718
3774
|
const [word, start, end] = this.getWordAtPos( cursor, -1 );
|
|
3719
|
-
if(key == ' ' || !word.length) {
|
|
3775
|
+
if( key == ' ' || !word.length ) {
|
|
3720
3776
|
this.hideAutoCompleteBox();
|
|
3721
3777
|
return;
|
|
3722
3778
|
}
|
|
@@ -3763,7 +3819,7 @@ class CodeEditor {
|
|
|
3763
3819
|
pre.appendChild( icon );
|
|
3764
3820
|
|
|
3765
3821
|
pre.addEventListener( 'click', () => {
|
|
3766
|
-
this.autoCompleteWord(
|
|
3822
|
+
this.autoCompleteWord( s );
|
|
3767
3823
|
} );
|
|
3768
3824
|
|
|
3769
3825
|
// Highlight the written part
|
|
@@ -3795,8 +3851,8 @@ class CodeEditor {
|
|
|
3795
3851
|
// Show box
|
|
3796
3852
|
this.autocomplete.classList.toggle('show', true);
|
|
3797
3853
|
this.autocomplete.classList.toggle('no-scrollbar', !(this.autocomplete.scrollHeight > this.autocomplete.offsetHeight));
|
|
3798
|
-
this.autocomplete.style.left = (cursor._left +
|
|
3799
|
-
this.autocomplete.style.top = (cursor._top +
|
|
3854
|
+
this.autocomplete.style.left = (cursor._left + 48 - this.getScrollLeft()) + "px";
|
|
3855
|
+
this.autocomplete.style.top = (cursor._top + 28 + this.lineHeight - this.getScrollTop()) + "px";
|
|
3800
3856
|
|
|
3801
3857
|
this.isAutoCompleteActive = true;
|
|
3802
3858
|
}
|
|
@@ -3809,23 +3865,30 @@ class CodeEditor {
|
|
|
3809
3865
|
return isActive != this.isAutoCompleteActive;
|
|
3810
3866
|
}
|
|
3811
3867
|
|
|
3812
|
-
autoCompleteWord(
|
|
3868
|
+
autoCompleteWord( suggestion ) {
|
|
3813
3869
|
|
|
3814
3870
|
if( !this.isAutoCompleteActive )
|
|
3815
|
-
|
|
3871
|
+
return;
|
|
3816
3872
|
|
|
3817
3873
|
let [suggestedWord, idx] = this._getSelectedAutoComplete();
|
|
3818
3874
|
suggestedWord = suggestion ?? suggestedWord;
|
|
3819
3875
|
|
|
3820
|
-
|
|
3876
|
+
for( let cursor of this.cursors.children )
|
|
3877
|
+
{
|
|
3878
|
+
const [word, start, end] = this.getWordAtPos( cursor, -1 );
|
|
3879
|
+
|
|
3880
|
+
const lineString = this.code.lines[ cursor.line ];
|
|
3881
|
+
this.code.lines[ cursor.line ] =
|
|
3882
|
+
lineString.slice(0, start) + suggestedWord + lineString.slice( end );
|
|
3883
|
+
|
|
3884
|
+
// Process lines and remove suggestion box
|
|
3885
|
+
this.cursorToPosition( cursor, start + suggestedWord.length );
|
|
3886
|
+
this.processLine( cursor.line );
|
|
3887
|
+
}
|
|
3821
3888
|
|
|
3822
|
-
|
|
3823
|
-
this.
|
|
3824
|
-
lineString.slice(0, start) + suggestedWord + lineString.slice(end);
|
|
3889
|
+
// Only the main cursor autocompletes, skip the "Tab" event for the rest
|
|
3890
|
+
this._skipTabs = this.cursors.childElementCount - 1;
|
|
3825
3891
|
|
|
3826
|
-
// Process lines and remove suggestion box
|
|
3827
|
-
this.cursorToPosition(cursor, start + suggestedWord.length);
|
|
3828
|
-
this.processLine(cursor.line);
|
|
3829
3892
|
this.hideAutoCompleteBox();
|
|
3830
3893
|
}
|
|
3831
3894
|
|
|
@@ -4210,7 +4273,7 @@ class CodeEditor {
|
|
|
4210
4273
|
CodeEditor.keywords = {
|
|
4211
4274
|
|
|
4212
4275
|
'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static', 'class', 'constructor', 'null', 'typeof', 'debugger', 'abstract',
|
|
4213
|
-
'arguments', 'extends', 'instanceof'],
|
|
4276
|
+
'arguments', 'extends', 'instanceof', 'Infinity'],
|
|
4214
4277
|
'C++': ['int', 'float', 'double', 'bool', 'char', 'wchar_t', 'const', 'static_cast', 'dynamic_cast', 'new', 'delete', 'void', 'true', 'false', 'auto', 'struct', 'typedef', 'nullptr',
|
|
4215
4278
|
'NULL', 'unsigned', 'namespace'],
|
|
4216
4279
|
'JSON': ['true', 'false'],
|
|
@@ -4243,7 +4306,8 @@ CodeEditor.utils = { // These ones don't have hightlight, used as suggestions to
|
|
|
4243
4306
|
|
|
4244
4307
|
CodeEditor.types = {
|
|
4245
4308
|
|
|
4246
|
-
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder'
|
|
4309
|
+
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer', 'InputEvent', 'MouseEvent',
|
|
4310
|
+
'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element'],
|
|
4247
4311
|
'Rust': ['u128'],
|
|
4248
4312
|
'Python': ['int', 'type', 'float', 'map', 'list', 'ArithmeticError', 'AssertionError', 'AttributeError', 'Exception', 'EOFError', 'FloatingPointError', 'GeneratorExit',
|
|
4249
4313
|
'ImportError', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'NotImplementedError', 'OSError',
|
package/build/lexgui.js
CHANGED
|
@@ -12,7 +12,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
var LX = global.LX = {
|
|
15
|
-
version: "0.1.
|
|
15
|
+
version: "0.1.27",
|
|
16
16
|
ready: false,
|
|
17
17
|
components: [], // specific pre-build components
|
|
18
18
|
signals: {} // events and triggers
|
|
@@ -3016,6 +3016,9 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
3016
3016
|
if( options.width ) {
|
|
3017
3017
|
element.style.width = element.style.minWidth = options.width;
|
|
3018
3018
|
}
|
|
3019
|
+
if( options.maxWidth ) {
|
|
3020
|
+
element.style.maxWidth = options.maxWidth;
|
|
3021
|
+
}
|
|
3019
3022
|
if( options.minWidth ) {
|
|
3020
3023
|
element.style.minWidth = options.minWidth;
|
|
3021
3024
|
}
|
package/build/lexgui.module.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
var LX = {
|
|
11
|
-
version: "0.1.
|
|
11
|
+
version: "0.1.27",
|
|
12
12
|
ready: false,
|
|
13
13
|
components: [], // specific pre-build components
|
|
14
14
|
signals: {} // events and triggers
|
|
@@ -3012,6 +3012,9 @@ class Panel {
|
|
|
3012
3012
|
if( options.width ) {
|
|
3013
3013
|
element.style.width = element.style.minWidth = options.width;
|
|
3014
3014
|
}
|
|
3015
|
+
if( options.maxWidth ) {
|
|
3016
|
+
element.style.maxWidth = options.maxWidth;
|
|
3017
|
+
}
|
|
3015
3018
|
if( options.minWidth ) {
|
|
3016
3019
|
element.style.minWidth = options.minWidth;
|
|
3017
3020
|
}
|
package/changelog.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# lexgui.js changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.27
|
|
4
|
+
|
|
5
|
+
Code Editor:
|
|
6
|
+
- Tab key follows fixed 4 space layout indentation.
|
|
7
|
+
- Support for removing indentation using "Shift+Tab".
|
|
8
|
+
- Support for changing number of tab spaces from the info panel.
|
|
9
|
+
- Minor bugfixes.
|
|
10
|
+
|
|
11
|
+
Support "maxWidth" as options when creating a widget.
|
|
12
|
+
|
|
3
13
|
## 0.1.26
|
|
4
14
|
|
|
5
15
|
Code Editor:
|