summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2023-11-23 08:18:22 +0100
committerSébastien Helleu <flashcode@flashtux.org>2023-11-23 08:49:54 +0100
commit87f74e9f9544a7e3b7e4ffd0acc40841b8eb79e8 (patch)
treec13466c75920da25ee3e80e838cb8a7b5bf6adf7 /src/core
parent2b0c2747ade0b65c4d2bdeee2ee80c1529edb633 (diff)
downloadweechat-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.c71
-rw-r--r--src/core/wee-config.h3
-rw-r--r--src/core/wee-eval.c150
-rw-r--r--src/core/wee-eval.h6
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 */