1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-30 14:56:39 +02:00

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}`
This commit is contained in:
Sébastien Helleu
2023-11-23 08:18:22 +01:00
parent 2b0c2747ad
commit 87f74e9f95
26 changed files with 5803 additions and 3503 deletions
+70 -1
View File
@@ -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;
@@ -822,6 +825,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".
@@ -1295,6 +1323,23 @@ config_change_nick_colors (const void *pointer, void *data,
gui_color_buffer_display ();
}
/*
* 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);
+3
View File
@@ -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;
+140 -10
View File
@@ -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"
@@ -1464,13 +1464,122 @@ end:
return (value) ? value : strdup ("");
}
/*
* 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;
+6
View File
@@ -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 */
+44 -21
View File
@@ -870,8 +870,8 @@ gui_color_info_term_colors (char *buffer, int size)
void
gui_color_buffer_display ()
{
int y, i, lines, columns, line, col, color, max_color, num_items;
char str_line[1024], str_color[64], str_rgb[64], **items;
int y, i, lines, columns, line, col, color, max_color;
char str_line[1024], str_color[64], str_rgb[64];
struct t_gui_color_palette *color_palette;
if (!gui_color_buffer)
@@ -1011,47 +1011,70 @@ gui_color_buffer_display ()
y++;
gui_chat_printf_y (gui_color_buffer, y++,
_("Nick colors:"));
items = string_split (CONFIG_STRING(config_color_chat_nick_colors),
",",
NULL,
WEECHAT_STRING_SPLIT_STRIP_LEFT
| WEECHAT_STRING_SPLIT_STRIP_RIGHT
| WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
0,
&num_items);
if (items)
if (config_num_nick_colors > 0)
{
str_line[0] = '\0';
for (i = 0; i < num_items; i++)
for (i = 0; i < config_num_nick_colors; i++)
{
if (gui_color_use_term_colors)
{
snprintf (str_color, sizeof (str_color),
" %s",
items[i]);
config_nick_colors[i]);
}
else
{
snprintf (str_color, sizeof (str_color),
"%c %s%s",
GUI_COLOR_RESET_CHAR,
gui_color_get_custom (items[i]),
items[i]);
gui_color_get_custom (config_nick_colors[i]),
config_nick_colors[i]);
}
if (gui_chat_strlen_screen (str_line) + gui_chat_strlen_screen (str_color) > 80)
if (gui_chat_strlen_screen (str_line)
+ gui_chat_strlen_screen (str_color) > 80)
{
gui_chat_printf_y (gui_color_buffer, y++,
" %s", str_line);
gui_chat_printf_y (gui_color_buffer, y++, " %s", str_line);
str_line[0] = '\0';
}
strcat (str_line, str_color);
}
if (str_line[0])
gui_chat_printf_y (gui_color_buffer, y++, " %s", str_line);
}
/* display eval syntax highlighting colors */
y++;
gui_chat_printf_y (gui_color_buffer, y++,
_("Syntax highlighting colors in evaluated strings:"));
if (config_num_eval_syntax_colors > 0)
{
str_line[0] = '\0';
for (i = 0; i < config_num_eval_syntax_colors; i++)
{
gui_chat_printf_y (gui_color_buffer, y++,
" %s", str_line);
if (gui_color_use_term_colors)
{
snprintf (str_color, sizeof (str_color),
" %s",
config_eval_syntax_colors[i]);
}
else
{
snprintf (str_color, sizeof (str_color),
"%c %s%s",
GUI_COLOR_RESET_CHAR,
gui_color_get_custom (config_eval_syntax_colors[i]),
config_eval_syntax_colors[i]);
}
if (gui_chat_strlen_screen (str_line)
+ gui_chat_strlen_screen (str_color) > 80)
{
gui_chat_printf_y (gui_color_buffer, y++, " %s", str_line);
str_line[0] = '\0';
}
strcat (str_line, str_color);
}
string_free_split (items);
if (str_line[0])
gui_chat_printf_y (gui_color_buffer, y++, " %s", str_line);
}
/* display palette colors */