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/parser.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/parser.h') diff --git a/src/parser.h b/src/parser.h index 20f73fb..7ca5ab3 100644 --- a/src/parser.h +++ b/src/parser.h @@ -27,6 +27,7 @@ #include "goto.h" #include "undo.h" #include "qreg.h" +#include "lexer.h" /* * Forward Declarations @@ -202,6 +203,12 @@ struct teco_state_t { */ teco_keymacro_mask_t keymacro_mask : 8; + /** + * Scintilla style to apply to all input characters in this state + * when syntax highlighting SciTECO code. + */ + teco_style_t style : 8; + /** * Additional state-dependent callbacks and settings. * This wastes some bytes compared to other techniques for extending teco_state_t @@ -241,6 +248,7 @@ gboolean teco_state_process_edit_cmd(teco_machine_t *ctx, teco_machine_t *parent .process_edit_cmd_cb = teco_state_process_edit_cmd, \ .is_start = FALSE, \ .keymacro_mask = TECO_KEYMACRO_MASK_DEFAULT, \ + .style = SCE_SCITECO_DEFAULT, \ ##__VA_ARGS__ \ } @@ -441,7 +449,9 @@ typedef enum { /** Parse, but don't execute until reaching end of conditional or its else-clause */ TECO_MODE_PARSE_ONLY_COND, /** Parse, but don't execute until reaching the very end of conditional */ - TECO_MODE_PARSE_ONLY_COND_FORCE + TECO_MODE_PARSE_ONLY_COND_FORCE, + /** Parse, but don't execute until end of macro (for Scintilla lexing) */ + TECO_MODE_LEXING } teco_mode_t; /** @extends teco_machine_t */ @@ -568,6 +578,7 @@ gboolean teco_state_expectstring_process_edit_cmd(teco_machine_main_t *ctx, teco .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t) \ teco_state_expectstring_process_edit_cmd, \ .keymacro_mask = TECO_KEYMACRO_MASK_STRING, \ + .style = SCE_SCITECO_STRING, \ .expectstring.string_building = TRUE, \ .expectstring.last = TRUE, \ .expectstring.process_cb = NULL, /* do nothing */ \ -- cgit v1.2.3