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:
+70
-1
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user