diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2023-11-23 08:18:22 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2023-11-23 08:49:54 +0100 |
commit | 87f74e9f9544a7e3b7e4ffd0acc40841b8eb79e8 (patch) | |
tree | c13466c75920da25ee3e80e838cb8a7b5bf6adf7 /src/core | |
parent | 2b0c2747ade0b65c4d2bdeee2ee80c1529edb633 (diff) | |
download | weechat-87f74e9f9544a7e3b7e4ffd0acc40841b8eb79e8.zip |
core: add syntax highlighting in evaluation of expressions, add option weechat.color.eval_syntax_colors (issue #2042)
Syntax highlighting (raw string without evaluation): `${raw_hl:xxx}`
Syntax highlighting: `${hl:xxx}`
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/wee-config.c | 71 | ||||
-rw-r--r-- | src/core/wee-config.h | 3 | ||||
-rw-r--r-- | src/core/wee-eval.c | 150 | ||||
-rw-r--r-- | src/core/wee-eval.h | 6 |
4 files changed, 219 insertions, 11 deletions
diff --git a/src/core/wee-config.c b/src/core/wee-config.c index ebf058958..0b380c669 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -269,6 +269,7 @@ struct t_config_option *config_color_chat_value = NULL; struct t_config_option *config_color_chat_value_null = NULL; struct t_config_option *config_color_emphasized = NULL; struct t_config_option *config_color_emphasized_bg = NULL; +struct t_config_option *config_color_eval_syntax_colors = NULL; struct t_config_option *config_color_input_actions = NULL; struct t_config_option *config_color_input_text_not_found = NULL; struct t_config_option *config_color_item_away = NULL; @@ -364,6 +365,8 @@ int config_word_chars_input_count = 0; char **config_nick_colors = NULL; int config_num_nick_colors = 0; struct t_hashtable *config_hashtable_nick_color_force = NULL; +char **config_eval_syntax_colors = NULL; +int config_num_eval_syntax_colors = 0; char *config_item_time_evaluated = NULL; char *config_buffer_time_same_evaluated = NULL; struct t_hashtable *config_hashtable_completion_partial_templates = NULL; @@ -823,6 +826,31 @@ config_change_look_nick_color_force (const void *pointer, void *data, } /* + * Sets eval syntax highlighting colors using option + * "weechat.color.eval_syntax_colors". + */ + +void +config_set_eval_syntax_colors () +{ + if (config_eval_syntax_colors) + { + string_free_split (config_eval_syntax_colors); + config_eval_syntax_colors = NULL; + config_num_eval_syntax_colors = 0; + } + + config_eval_syntax_colors = string_split ( + CONFIG_STRING(config_color_eval_syntax_colors), + ",", + NULL, + WEECHAT_STRING_SPLIT_STRIP_LEFT + | WEECHAT_STRING_SPLIT_STRIP_RIGHT + | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, + 0, &config_num_eval_syntax_colors); +} + +/* * Callback for changes on options "weechat.look.nick_prefix" and * "weechat.look.nick_suffix". */ @@ -1296,6 +1324,23 @@ config_change_nick_colors (const void *pointer, void *data, } /* + * Callback for changes on option "weechat.color.eval_syntax_colors". + */ + +void +config_change_eval_syntax_colors (const void *pointer, void *data, + struct t_config_option *option) +{ + /* make C compiler happy */ + (void) pointer; + (void) data; + (void) option; + + config_set_eval_syntax_colors (); + gui_color_buffer_display (); +} + +/* * Callback for changes on option * "weechat.completion.partial_completion_templates". */ @@ -1516,7 +1561,9 @@ config_weechat_init_after_read () /* apply filters on all buffers */ gui_filter_all_buffers (NULL); + config_set_nick_colors (); config_change_look_nick_color_force (NULL, NULL, NULL); + config_set_eval_syntax_colors (); } /* @@ -4611,6 +4658,21 @@ config_weechat_init_options () NULL, NULL, NULL, &config_change_color, NULL, NULL, NULL, NULL, NULL); + /* eval syntax highlighting colors (for "${raw_hl:xxx}" and "${hl:xxx}") */ + config_color_eval_syntax_colors = config_file_new_option ( + weechat_config_file, weechat_config_section_color, + "eval_syntax_colors", "string", + /* TRANSLATORS: please do not translate "lightred:blue" */ + N_("text color for syntax highlighting in evaluated strings, " + "with \"${raw_hl:...}\" and \"${hl:...}\" (comma separated " + "list of colors, background is allowed with format: \"fg:bg\", " + "for example: \"lightred:blue\")"), + NULL, 0, 0, + "green,lightred,lightblue,lightmagenta,yellow,cyan", + NULL, 0, + NULL, NULL, NULL, + &config_change_eval_syntax_colors, NULL, NULL, + NULL, NULL, NULL); /* input bar */ config_color_input_actions = config_file_new_option ( weechat_config_file, weechat_config_section_color, @@ -4654,7 +4716,7 @@ config_weechat_init_options () NULL, NULL, NULL, &config_change_color, NULL, NULL, NULL, NULL, NULL); - /* general color settings */ + /* separator */ config_color_separator = config_file_new_option ( weechat_config_file, weechat_config_section_color, "separator", "color", @@ -5374,6 +5436,13 @@ config_weechat_free () config_num_nick_colors = 0; } + if (config_eval_syntax_colors) + { + string_free_split (config_eval_syntax_colors); + config_eval_syntax_colors = NULL; + config_num_eval_syntax_colors = 0; + } + if (config_hashtable_nick_color_force) { hashtable_free (config_hashtable_nick_color_force); diff --git a/src/core/wee-config.h b/src/core/wee-config.h index a191505f1..9f38bac6b 100644 --- a/src/core/wee-config.h +++ b/src/core/wee-config.h @@ -321,6 +321,7 @@ extern struct t_config_option *config_color_chat_value; extern struct t_config_option *config_color_chat_value_null; extern struct t_config_option *config_color_emphasized; extern struct t_config_option *config_color_emphasized_bg; +extern struct t_config_option *config_color_eval_syntax_colors; extern struct t_config_option *config_color_input_actions; extern struct t_config_option *config_color_input_text_not_found; extern struct t_config_option *config_color_item_away; @@ -400,6 +401,8 @@ extern int config_word_chars_input_count; extern char **config_nick_colors; extern int config_num_nick_colors; extern struct t_hashtable *config_hashtable_nick_color_force; +extern char **config_eval_syntax_colors; +extern int config_num_eval_syntax_colors; extern char *config_buffer_time_same_evaluated; extern struct t_hashtable *config_hashtable_completion_partial_templates; diff --git a/src/core/wee-eval.c b/src/core/wee-eval.c index c2370b504..4d8c0e7da 100644 --- a/src/core/wee-eval.c +++ b/src/core/wee-eval.c @@ -32,7 +32,7 @@ #include "weechat.h" #include "wee-eval.h" #include "wee-calc.h" -#include "wee-config-file.h" +#include "wee-config.h" #include "wee-hashtable.h" #include "wee-hdata.h" #include "wee-hook.h" @@ -1465,12 +1465,121 @@ end: } /* + * Returns text with syntax highlighting (using markers, to be replaced by + * colors later). + * + * Note: result must be freed after use. + */ + +char * +eval_syntax_highlight_add_markers (const char *text, + struct t_eval_context *eval_context) +{ + char **value; + + value = string_dyn_alloc (128); + if (!value) + return NULL; + + string_dyn_concat (value, EVAL_SYNTAX_HL_INC, -1); + string_dyn_concat (value, eval_context->prefix, -1); + if (text) + string_dyn_concat (value, text, -1); + string_dyn_concat (value, eval_context->suffix, -1); + string_dyn_concat (value, EVAL_SYNTAX_HL_DEC, -1); + + return string_dyn_free (value, 0); +} + +/* + * Replaces raw highlight markers with color codes defined in option + * weechat.color.eval_syntax_colors. + * + * Note: result must be freed after use. + */ + +char * +eval_syntax_highlight_colorize (const char *value) +{ + const char *ptr_value; + char **result, *pos; + int color; + + if (!value) + return NULL; + + result = string_dyn_alloc (128); + if (!result) + return NULL; + + color = -1; + ptr_value = value; + while (ptr_value && ptr_value[0]) + { + pos = strstr (ptr_value, EVAL_SYNTAX_HL_MARKER); + if (!pos) + { + string_dyn_concat (result, ptr_value, -1); + break; + } + string_dyn_concat (result, ptr_value, pos - ptr_value); + ptr_value = pos + strlen (EVAL_SYNTAX_HL_MARKER); + if (config_num_eval_syntax_colors > 0) + { + if (ptr_value[0] == '+') + color++; + else if (ptr_value[0] == '-') + color--; + } + ptr_value++; + if (config_num_eval_syntax_colors > 0) + { + string_dyn_concat ( + result, + gui_color_get_custom ( + (color >= 0) ? + config_eval_syntax_colors[color % config_num_eval_syntax_colors] : + "reset"), + -1); + } + } + + return string_dyn_free (result, 0); +} + +/* + * Adds syntax highlighting in text. + * + * Note: result must be freed after use. + */ + +char * +eval_syntax_highlight (const char *text, struct t_eval_context *eval_context) +{ + char *value, *value2; + + eval_context->syntax_highlight++; + + value = eval_replace_vars (text, eval_context); + value2 = eval_syntax_highlight_colorize (value); + if (value) + free (value); + + eval_context->syntax_highlight--; + + return value2; +} + +/* * Replaces variables, which can be, by order of priority: + * - the string itself without evaluation but with syntax highlighting + * (format: raw_hl:xxx) * - the string itself without evaluation (format: raw:xxx) + * - a string with syntax highlighting (format: hl:xxx) * - a variable from hashtable "user_vars" or "extra_vars" * - a WeeChat home directory, one of: "weechat_config_dir", * "weechat_data_dir", "weechat_cache_dir", "weechat_runtime_dir" - * - a string to evaluate (format: eval:xxx) + * - an evaluated string (format: eval:xxx) * - a condition to evaluate (format: eval_cond:xxx) * - a string with escaped chars (format: esc:xxx or \xxx) * - a string with a range of chars (format: chars:range) @@ -1531,6 +1640,16 @@ eval_replace_vars_cb (void *data, const char *text) EVAL_DEBUG_MSG(1, "eval_replace_vars_cb(\"%s\")", text); + if (eval_context->syntax_highlight) + return eval_syntax_highlight_add_markers (text, eval_context); + + /* raw text (no evaluation at all), with syntax highlighting */ + if (strncmp (text, "raw_hl:", 7) == 0) + { + value = eval_syntax_highlight (text + 7, eval_context); + goto end; + } + /* raw text (no evaluation at all) */ if (strncmp (text, "raw:", 4) == 0) { @@ -1538,6 +1657,13 @@ eval_replace_vars_cb (void *data, const char *text) goto end; } + /* syntax highlighting */ + if (strncmp (text, "hl:", 3) == 0) + { + value = eval_syntax_highlight (text + 3, eval_context); + goto end; + } + /* variable in hashtable "user_vars" or "extra_vars" */ ptr_value = hashtable_get (eval_context->user_vars, text); if (ptr_value) @@ -1891,7 +2017,8 @@ end: char * eval_replace_vars (const char *expr, struct t_eval_context *eval_context) { - const char *no_replace_prefix_list[] = { "if:", "raw:", NULL }; + const char *no_replace_prefix_list_std[] = { "if:", "raw:", "raw_hl:", NULL }; + const char *no_replace_prefix_list_col[] = { "raw:", "raw_hl:", NULL }; char *result; int debug_id; @@ -1901,13 +2028,15 @@ eval_replace_vars (const char *expr, struct t_eval_context *eval_context) if (eval_context->recursion_count < EVAL_RECURSION_MAX) { - result = string_replace_with_callback (expr, - eval_context->prefix, - eval_context->suffix, - no_replace_prefix_list, - &eval_replace_vars_cb, - eval_context, - NULL); + result = string_replace_with_callback ( + expr, + eval_context->prefix, + eval_context->suffix, + (eval_context->syntax_highlight) ? + no_replace_prefix_list_col : no_replace_prefix_list_std, + &eval_replace_vars_cb, + eval_context, + NULL); } else { @@ -2542,6 +2671,7 @@ eval_expression (const char *expr, struct t_hashtable *pointers, eval_context->regex = NULL; eval_context->regex_replacement_index = 1; eval_context->recursion_count = 0; + eval_context->syntax_highlight = 0; eval_context->debug_level = 0; eval_context->debug_depth = 0; eval_context->debug_id = 0; diff --git a/src/core/wee-eval.h b/src/core/wee-eval.h index b703c03ed..6f00c4620 100644 --- a/src/core/wee-eval.h +++ b/src/core/wee-eval.h @@ -37,6 +37,10 @@ #define EVAL_RANGE_ALPHA EVAL_RANGE_LOWER EVAL_RANGE_UPPER #define EVAL_RANGE_ALNUM EVAL_RANGE_ALPHA EVAL_RANGE_DIGIT +#define EVAL_SYNTAX_HL_MARKER "\xef\xbf\xbf\xef\xbf\xbf" +#define EVAL_SYNTAX_HL_INC (EVAL_SYNTAX_HL_MARKER "+") +#define EVAL_SYNTAX_HL_DEC (EVAL_SYNTAX_HL_MARKER "-") + struct t_hashtable; enum t_eval_logical_op @@ -89,6 +93,8 @@ struct t_eval_context struct t_eval_regex *regex; /* in case of replace with regex */ int regex_replacement_index; /* replacement index (≥ 1) */ int recursion_count; /* to prevent infinite recursion */ + int syntax_highlight; /* syntax highlight: ${raw_hl:...} */ + /* or ${hl:...} */ int debug_level; /* 0: no debug, 1: debug, 2: extra */ int debug_depth; /* used for debug indentation */ int debug_id; /* operation id in debug output */ |