From 244a54a18b7db6af177c9d10f3224772f08d7484 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Mon, 9 Dec 2024 12:58:25 +0300 Subject: implemented Scintilla lexer for SciTECO code, i.e. TECO syntax highlighting * this works by embedding the SciTECO parser and driving it always (exclusively) in parse-only mode. * A new teco_state_t::style determines the Scintilla style for any character accepted in the given state. * Therefore, the SciTECO lexer is always 100% exact and corresponds to the current SciTECO grammer - it does not have to be maintained separately. There are a few exceptions and tweaks, though. * The contents of curly-brace escapes (`@^Uq{...}`) are rendered as ordinary code using a separate parser instance. This can be disabled with the lexer.sciteco.macrodef property. Unfortunately, SciTECO does not currently allow setting lexer properties (FIXME). * Labels and comments are currently styled the same. This could change in the future once we introduce real comments. * Lexers are usually implemented in C++, but I did not want to draw in C++. Especially not since we'd have to include parser.h and other SciTECO headers, that really do not want to keep C++-compatible. Instead, the lexer is implemented "in the container". @ES/SCI_SETILEXER/sciteco/ is internally translated to SCI_SETILEXER(NULL) and we get Scintilla notifications when styling the view becomes necessary. This is then centrally forwarded to the teco_lexer_style() which uses the ordinary teco_view_ssm() API for styling. * Once the command line becomes a Scintilla view even on Curses, we can enabled syntax highlighting of the command line macro. --- src/symbols.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/symbols.c') diff --git a/src/symbols.c b/src/symbols.c index 944d01d..798b89c 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -321,8 +321,13 @@ teco_state_scintilla_lparam_done(teco_machine_main_t *ctx, const teco_string_t * sptr_t lParam = 0; + if (ctx->scintilla.iMessage == SCI_SETILEXER && + !teco_string_cmp(str, "sciteco", 7)) { + /* perform lexing in the container (see teco_lexer_style()) */ + lParam = 0; + } #ifdef HAVE_LEXILLA - if (ctx->scintilla.iMessage == SCI_SETILEXER) { + else if (ctx->scintilla.iMessage == SCI_SETILEXER) { if (teco_string_contains(str, '\0')) { g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, "Lexer name must not contain null-byte."); @@ -336,9 +341,9 @@ teco_state_scintilla_lparam_done(teco_machine_main_t *ctx, const teco_string_t * "Lexilla lexer \"%s\" not found.", lexer); return NULL; } - } else + } #endif - if (str->len > 0) { + else if (str->len > 0) { /* * NOTE: There may even be messages that read strings * with embedded nulls. -- cgit v1.2.3