code-panel: self-contained BrowserLexer; revert library-ts to fix ts-node

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Rokojori 2026-07-17 23:42:43 +02:00
parent d96a1bf470
commit 6e3fe19395
4 changed files with 90 additions and 27 deletions

View File

@ -0,0 +1,64 @@
function makeSticky( re: RegExp ): RegExp
{
if ( re.sticky ) return re;
const flags = re.flags.includes( 'y' ) ? re.flags : re.flags + 'y';
return new RegExp( re.source, flags );
}
export class BrowserMatcher
{
readonly type: string;
private _re: RegExp;
constructor( type: string, re: RegExp )
{
this.type = type;
this._re = makeSticky( re );
}
matchLength( source: string, offset: number ): number
{
this._re.lastIndex = offset;
const result = this._re.exec( source );
if ( result && result.index === offset ) return result[ 0 ].length;
return -1;
}
}
export class BrowserLexer
{
readonly modes = new Map<string, BrowserMatcher[]>();
addMatchers( ...matchers: BrowserMatcher[] ): void
{
const list = this.modes.get( 'default' ) ?? [];
list.push( ...matchers );
this.modes.set( 'default', list );
}
}
export function cLikeLexer(): BrowserLexer
{
const l = new BrowserLexer();
l.addMatchers(
new BrowserMatcher( 'SINGLE_LINE_COMMENT', /\/\/.*/ ),
new BrowserMatcher( 'MULTI_LINE_COMMENT', /\/\*[\s\S]*?\*\// ),
new BrowserMatcher( 'DOUBLE_QUOTED_STRING', /"(?:[^"\\]|\\.)*"/ ),
new BrowserMatcher( 'SINGLE_QUOTED_STRING', /'(?:[^'\\]|\\.)*'/ ),
new BrowserMatcher( 'C_INSTRUCTION', /\#.*/ ),
new BrowserMatcher( 'NUMBER', /(?=\.\d|\d)(?:\d+)?(?:\.?\d*)(?:[eE][+-]?\d+)?/ ),
new BrowserMatcher( 'NULL', /\bnull\b/ ),
new BrowserMatcher( 'BOOL', /\b(?:true|false)\b/ ),
new BrowserMatcher( 'BREAK', /\r\n|\r|\n/ ),
new BrowserMatcher( 'WHITESPACE', /\s+/ ),
new BrowserMatcher( 'LOGIC', /\b(?:if|else|switch|do|while|for|break|continue|return|case)\b/ ),
new BrowserMatcher( 'BRACKET', /[()[\]{}]/ ),
new BrowserMatcher( 'ACCESS_MODIFIER', /\b(?:public|protected|private)\b/ ),
new BrowserMatcher( 'CLASS', /\bclass\b/ ),
new BrowserMatcher( 'OPERATOR', /==|\+\+|--|[+\-*\/^|~&%<>=!.:,;]/ ),
new BrowserMatcher( 'CFUNCTION', /[a-zA-Z_]\w*(?=\s*\()/ ),
new BrowserMatcher( 'CWORD', /[a-zA-Z_]\w*/ ),
new BrowserMatcher( 'ANY_SYMBOL', /./ ),
);
return l;
}

View File

@ -1,27 +1,26 @@
import { CLikeLexer } from '../../library-ts/browser/text/lexer/CLikeLexer.js';
import { LexerTypes } from '../../library-ts/browser/text/lexer/LexerType.js';
import { cLikeLexer } from './BrowserLexer.js';
import { CodeMirrorLexerMode } from './CodeMirrorLexerMode.js';
const TYPE_TO_CLASS: Record<string, string | null> =
{
[ LexerTypes.SINGLE_LINE_COMMENT ]: 'comment',
[ LexerTypes.MULTI_LINE_COMMENT ]: 'comment',
[ LexerTypes.DOUBLE_QUOTED_STRING ]: 'string',
[ LexerTypes.SINGLE_QUOTED_STRING ]: 'string',
[ LexerTypes.NUMBER ]: 'number',
[ LexerTypes.BOOL ]: 'atom',
[ LexerTypes.NULL ]: 'atom',
[ LexerTypes.LOGIC ]: 'keyword',
[ LexerTypes.CLASS ]: 'keyword',
[ LexerTypes.ACCESS_MODIFIER ]: 'keyword',
[ LexerTypes.C_INSTRUCTION ]: 'meta',
[ LexerTypes.CFUNCTION ]: 'variable-2',
[ LexerTypes.CWORD ]: 'variable',
[ LexerTypes.OPERATOR ]: 'operator',
[ LexerTypes.BRACKET ]: 'bracket',
[ LexerTypes.WHITESPACE ]: null,
[ LexerTypes.BREAK ]: null,
[ LexerTypes.ANY_SYMBOL ]: null,
SINGLE_LINE_COMMENT: 'comment',
MULTI_LINE_COMMENT: 'comment',
DOUBLE_QUOTED_STRING: 'string',
SINGLE_QUOTED_STRING: 'string',
NUMBER: 'number',
BOOL: 'atom',
NULL: 'atom',
LOGIC: 'keyword',
CLASS: 'keyword',
ACCESS_MODIFIER: 'keyword',
C_INSTRUCTION: 'meta',
CFUNCTION: 'variable-2',
CWORD: 'variable',
OPERATOR: 'operator',
BRACKET: 'bracket',
WHITESPACE: null,
BREAK: null,
ANY_SYMBOL: null,
};
const CS_KEYWORDS =
@ -42,9 +41,9 @@ const CS_KEYWORDS =
];
export const csharpMode = new CodeMirrorLexerMode(
new CLikeLexer(),
cLikeLexer(),
TYPE_TO_CLASS,
[ { type: LexerTypes.MULTI_LINE_COMMENT, start: /\/\*/, end: /\*\//, cmClass: 'comment' } ]
[ { type: 'MULTI_LINE_COMMENT', start: /\/\*/, end: /\*\//, cmClass: 'comment' } ]
);
csharpMode.setKeywordSet( 'keywords', CS_KEYWORDS, 'keyword', [ LexerTypes.CWORD ] );
csharpMode.setKeywordSet( 'keywords', CS_KEYWORDS, 'keyword', [ 'CWORD' ] );

View File

@ -1,4 +1,4 @@
import { Lexer } from '../../library-ts/browser/text/lexer/Lexer.js';
import { BrowserLexer } from './BrowserLexer.js';
export interface MultiLineBlock
{
@ -18,7 +18,7 @@ interface KeywordSet
export class CodeMirrorLexerMode
{
private _lexer: Lexer;
private _lexer: BrowserLexer;
private _typeToClass: Record<string, string | null>;
private _multiLineBlocks: MultiLineBlock[];
private _multiLineTypes: Set<string>;
@ -28,7 +28,7 @@ export class CodeMirrorLexerMode
name: string = '';
constructor(
lexer: Lexer,
lexer: BrowserLexer,
typeToClass: Record<string, string | null>,
multiLineBlocks: MultiLineBlock[] = []
)

@ -1 +1 @@
Subproject commit 3fa79fb4f376c0a3903844edfcd8f3b529d2db0f
Subproject commit 98895de241f4f05e98ab46f9976e3756c2df5c7d