mirror of
https://github.com/weechat/weechat.git
synced 2026-07-10 11:43:13 +02:00
core: add text emphasis in messages when searching text in buffer
New options: - weechat.look.emphasized_attributes - weechat.color.emphasized - weechat.color.emphasized_bg
This commit is contained in:
@@ -101,6 +101,7 @@ struct t_config_option *config_look_confirm_quit;
|
||||
struct t_config_option *config_look_day_change;
|
||||
struct t_config_option *config_look_day_change_time_format;
|
||||
struct t_config_option *config_look_eat_newline_glitch;
|
||||
struct t_config_option *config_look_emphasized_attributes;
|
||||
struct t_config_option *config_look_highlight;
|
||||
struct t_config_option *config_look_highlight_regex;
|
||||
struct t_config_option *config_look_highlight_tags;
|
||||
@@ -198,6 +199,8 @@ struct t_config_option *config_color_chat_text_found_bg;
|
||||
struct t_config_option *config_color_chat_time;
|
||||
struct t_config_option *config_color_chat_time_delimiters;
|
||||
struct t_config_option *config_color_chat_value;
|
||||
struct t_config_option *config_color_emphasized;
|
||||
struct t_config_option *config_color_emphasized_bg;
|
||||
struct t_config_option *config_color_input_actions;
|
||||
struct t_config_option *config_color_input_text_not_found;
|
||||
struct t_config_option *config_color_separator;
|
||||
@@ -262,6 +265,7 @@ int config_length_nick_prefix_suffix = 0;
|
||||
int config_length_prefix_same_nick = 0;
|
||||
struct t_hook *config_day_change_timer = NULL;
|
||||
int config_day_change_old_day = -1;
|
||||
int config_emphasized_attributes = 0;
|
||||
regex_t *config_highlight_regex = NULL;
|
||||
char **config_highlight_tags = NULL;
|
||||
int config_num_highlight_tags = 0;
|
||||
@@ -482,6 +486,34 @@ config_change_eat_newline_glitch (void *data, struct t_config_option *option)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for changes on option "weechat.look.emphasized_attributes".
|
||||
*/
|
||||
|
||||
void
|
||||
config_change_emphasized_attributes (void *data, struct t_config_option *option)
|
||||
{
|
||||
int i;
|
||||
const char *ptr_attr;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) option;
|
||||
|
||||
config_emphasized_attributes = 0;
|
||||
|
||||
ptr_attr = CONFIG_STRING(config_look_emphasized_attributes);
|
||||
if (ptr_attr)
|
||||
{
|
||||
for (i = 0; ptr_attr[i]; i++)
|
||||
{
|
||||
config_emphasized_attributes |= gui_color_attr_get_flag (ptr_attr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
gui_window_ask_refresh (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for changes on option "weechat.look.highlight_regex".
|
||||
*/
|
||||
@@ -2065,6 +2097,13 @@ config_weechat_init_options ()
|
||||
"display bugs)"),
|
||||
NULL, 0, 0, "off", NULL, 0, NULL, NULL,
|
||||
&config_change_eat_newline_glitch, NULL, NULL, NULL);
|
||||
config_look_emphasized_attributes = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
"emphasized_attributes", "string",
|
||||
N_("attributes for emphasized text: one or more attribute chars ("
|
||||
"\"*\" for bold, \"!\" for reverse, \"_\" for underline); if the "
|
||||
"string is empty, the colors weechat.color.emphasized* are used"),
|
||||
NULL, 0, 0, "", NULL, 0, NULL, NULL, &config_change_emphasized_attributes, NULL, NULL, NULL);
|
||||
config_look_highlight = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
"highlight", "string",
|
||||
@@ -2737,6 +2776,23 @@ config_weechat_init_options ()
|
||||
N_("text color for values"),
|
||||
NULL, GUI_COLOR_CHAT_VALUE, 0, "cyan", NULL, 0,
|
||||
NULL, NULL, &config_change_color, NULL, NULL, NULL);
|
||||
/* emphasis (chat/bars) */
|
||||
config_color_emphasized = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
"emphasized", "color",
|
||||
N_("text color for emphasized text (for example when searching text); "
|
||||
"this option is used only if option weechat.look.emphasized_attributes "
|
||||
"is an empty string (default value)"),
|
||||
NULL, GUI_COLOR_EMPHASIS, 0, "yellow", NULL, 0,
|
||||
NULL, NULL, &config_change_color, NULL, NULL, NULL);
|
||||
config_color_emphasized_bg = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
"emphasized_bg", "color",
|
||||
N_("background color for emphasized text (for example when searching "
|
||||
"text); used only if option weechat.look.emphasized_attributes is an "
|
||||
"empty string (default value)"),
|
||||
NULL, -1, 0, "magenta", NULL, 0,
|
||||
NULL, NULL, &config_change_color, NULL, NULL, NULL);
|
||||
/* input bar */
|
||||
config_color_input_actions = config_file_new_option (
|
||||
weechat_config_file, ptr_section,
|
||||
|
||||
@@ -118,6 +118,7 @@ extern struct t_config_option *config_look_confirm_quit;
|
||||
extern struct t_config_option *config_look_day_change;
|
||||
extern struct t_config_option *config_look_day_change_time_format;
|
||||
extern struct t_config_option *config_look_eat_newline_glitch;
|
||||
extern struct t_config_option *config_look_emphasized_attributes;
|
||||
extern struct t_config_option *config_look_highlight;
|
||||
extern struct t_config_option *config_look_highlight_regex;
|
||||
extern struct t_config_option *config_look_highlight_tags;
|
||||
@@ -213,6 +214,8 @@ extern struct t_config_option *config_color_chat_text_found_bg;
|
||||
extern struct t_config_option *config_color_chat_time;
|
||||
extern struct t_config_option *config_color_chat_time_delimiters;
|
||||
extern struct t_config_option *config_color_chat_value;
|
||||
extern struct t_config_option *config_color_emphasized;
|
||||
extern struct t_config_option *config_color_emphasized_bg;
|
||||
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_separator;
|
||||
@@ -265,6 +268,7 @@ extern struct t_config_option *config_plugin_save_config_on_unload;
|
||||
|
||||
extern int config_length_nick_prefix_suffix;
|
||||
extern int config_length_prefix_same_nick;
|
||||
extern int config_emphasized_attributes;
|
||||
extern regex_t *config_highlight_regex;
|
||||
extern char **config_highlight_tags;
|
||||
extern int config_num_highlight_tags;
|
||||
|
||||
@@ -204,6 +204,10 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window,
|
||||
gui_window_string_apply_color_pair ((unsigned char **)&string,
|
||||
GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar);
|
||||
break;
|
||||
case GUI_COLOR_EMPHASIS_CHAR: /* emphasis */
|
||||
string++;
|
||||
gui_window_toggle_emphasis ();
|
||||
break;
|
||||
case GUI_COLOR_BAR_CHAR: /* bar color */
|
||||
switch (string[1])
|
||||
{
|
||||
@@ -364,6 +368,12 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window,
|
||||
if (output)
|
||||
free (output);
|
||||
|
||||
if (gui_window_current_emphasis)
|
||||
{
|
||||
gui_window_emphasize (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
*x, *y, size_on_screen);
|
||||
}
|
||||
|
||||
*x += size_on_screen;
|
||||
}
|
||||
}
|
||||
@@ -437,6 +447,8 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window,
|
||||
index_subitem = -1;
|
||||
index_line = 0;
|
||||
|
||||
gui_window_current_emphasis = 0;
|
||||
|
||||
filling = gui_bar_get_filling (bar_window->bar);
|
||||
|
||||
content = gui_bar_window_content_get_with_filling (bar_window, window);
|
||||
|
||||
@@ -262,6 +262,11 @@ gui_chat_string_next_char (struct t_gui_window *window, struct t_gui_line *line,
|
||||
gui_window_string_apply_color_pair ((unsigned char **)&string,
|
||||
(apply_style) ? GUI_WINDOW_OBJECTS(window)->win_chat : NULL);
|
||||
break;
|
||||
case GUI_COLOR_EMPHASIS_CHAR: /* emphasis */
|
||||
string++;
|
||||
if (apply_style)
|
||||
gui_window_toggle_emphasis ();
|
||||
break;
|
||||
case GUI_COLOR_BAR_CHAR: /* bar color */
|
||||
string++;
|
||||
switch (string[0])
|
||||
@@ -402,6 +407,13 @@ gui_chat_display_word_raw (struct t_gui_window *window, struct t_gui_line *line,
|
||||
"%s", (output) ? output : utf_char);
|
||||
if (output)
|
||||
free (output);
|
||||
|
||||
if (gui_window_current_emphasis)
|
||||
{
|
||||
gui_window_emphasize (GUI_WINDOW_OBJECTS(window)->win_chat,
|
||||
x, window->win_chat_cursor_y,
|
||||
size_on_screen);
|
||||
}
|
||||
}
|
||||
chars_displayed += size_on_screen;
|
||||
}
|
||||
@@ -432,10 +444,6 @@ gui_chat_display_word (struct t_gui_window *window,
|
||||
char *data, *ptr_data, *end_line, saved_char, str_space[] = " ";
|
||||
int chars_displayed, pos_saved_char, chars_to_display, num_displayed;
|
||||
int length_align;
|
||||
attr_t attrs;
|
||||
attr_t *ptr_attrs;
|
||||
short pair;
|
||||
short *ptr_pair;
|
||||
|
||||
chars_displayed = 0;
|
||||
|
||||
@@ -481,17 +489,12 @@ gui_chat_display_word (struct t_gui_window *window,
|
||||
&& CONFIG_STRING(config_look_prefix_suffix)[0]
|
||||
&& line->data->date > 0)
|
||||
{
|
||||
attrs = 0;
|
||||
pair = 0;
|
||||
if (!simulate)
|
||||
{
|
||||
ptr_attrs = &attrs;
|
||||
ptr_pair = &pair;
|
||||
wattr_get (GUI_WINDOW_OBJECTS(window)->win_chat,
|
||||
ptr_attrs, ptr_pair, NULL);
|
||||
gui_window_save_style ();
|
||||
gui_window_save_style (GUI_WINDOW_OBJECTS(window)->win_chat);
|
||||
gui_window_set_weechat_color (GUI_WINDOW_OBJECTS(window)->win_chat,
|
||||
GUI_COLOR_CHAT_PREFIX_SUFFIX);
|
||||
gui_window_current_emphasis = 0;
|
||||
}
|
||||
chars_displayed += gui_chat_display_word_raw (window, line,
|
||||
CONFIG_STRING(config_look_prefix_suffix),
|
||||
@@ -506,16 +509,7 @@ gui_chat_display_word (struct t_gui_window *window,
|
||||
nick_offline);
|
||||
window->win_chat_cursor_x += gui_chat_strlen_screen (str_space);
|
||||
if (!simulate)
|
||||
{
|
||||
wattr_set (GUI_WINDOW_OBJECTS(window)->win_chat, attrs, pair, NULL);
|
||||
/*
|
||||
* for unknown reason, the wattr_set function sometimes
|
||||
* fails to set the color pair under FreeBSD, so we force
|
||||
* it again with wcolor_set
|
||||
*/
|
||||
wcolor_set (GUI_WINDOW_OBJECTS(window)->win_chat, pair, NULL);
|
||||
gui_window_restore_style ();
|
||||
}
|
||||
gui_window_restore_style (GUI_WINDOW_OBJECTS(window)->win_chat);
|
||||
}
|
||||
if (window->win_chat_cursor_y < window->coords_size)
|
||||
window->coords[window->win_chat_cursor_y].data = (char *)word + (ptr_data - data);
|
||||
@@ -1130,7 +1124,7 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
|
||||
int word_start_offset, word_end_offset;
|
||||
int word_length_with_spaces, word_length;
|
||||
char *ptr_data, *ptr_end_offset, *next_char;
|
||||
char *ptr_style, *message_with_tags;
|
||||
char *ptr_style, *message_with_tags, *message_with_search;
|
||||
|
||||
if (!line)
|
||||
return 0;
|
||||
@@ -1152,6 +1146,7 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
|
||||
num_lines = gui_chat_display_line (window, line, 0, 1);
|
||||
window->win_chat_cursor_x = x;
|
||||
window->win_chat_cursor_y = y;
|
||||
gui_window_current_emphasis = 0;
|
||||
}
|
||||
|
||||
/* calculate marker position (maybe not used for this line!) */
|
||||
@@ -1205,6 +1200,16 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
|
||||
gui_chat_build_string_message_tags (line) : NULL;
|
||||
ptr_data = (message_with_tags) ?
|
||||
message_with_tags : line->data->message;
|
||||
message_with_search = NULL;
|
||||
if (window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
|
||||
{
|
||||
message_with_search = gui_color_emphasize (ptr_data,
|
||||
window->buffer->input_buffer,
|
||||
window->buffer->text_search_exact,
|
||||
NULL);
|
||||
if (message_with_search)
|
||||
ptr_data = message_with_search;
|
||||
}
|
||||
while (ptr_data && ptr_data[0])
|
||||
{
|
||||
gui_chat_get_word_info (window,
|
||||
@@ -1295,6 +1300,8 @@ gui_chat_display_line (struct t_gui_window *window, struct t_gui_line *line,
|
||||
}
|
||||
if (message_with_tags)
|
||||
free (message_with_tags);
|
||||
if (message_with_search)
|
||||
free (message_with_search);
|
||||
}
|
||||
|
||||
if (marker_line)
|
||||
|
||||
@@ -1434,6 +1434,7 @@ gui_color_init_weechat ()
|
||||
gui_color_build (GUI_COLOR_CHAT_NICK_OFFLINE_HIGHLIGHT, CONFIG_COLOR(config_color_chat_nick_offline_highlight), CONFIG_COLOR(config_color_chat_nick_offline_highlight_bg));
|
||||
gui_color_build (GUI_COLOR_CHAT_NICK_PREFIX, CONFIG_COLOR(config_color_chat_nick_prefix), CONFIG_COLOR(config_color_chat_bg));
|
||||
gui_color_build (GUI_COLOR_CHAT_NICK_SUFFIX, CONFIG_COLOR(config_color_chat_nick_suffix), CONFIG_COLOR(config_color_chat_bg));
|
||||
gui_color_build (GUI_COLOR_EMPHASIS, CONFIG_COLOR(config_color_emphasized), CONFIG_COLOR(config_color_emphasized_bg));
|
||||
|
||||
/*
|
||||
* define old nick colors for compatibility on /upgrade with previous
|
||||
|
||||
@@ -57,11 +57,16 @@
|
||||
#include "gui-curses.h"
|
||||
|
||||
|
||||
#define GUI_WINDOW_MAX_SAVED_STYLES 32
|
||||
|
||||
|
||||
int gui_window_current_style_fg; /* current foreground color */
|
||||
int gui_window_current_style_bg; /* current background color */
|
||||
int gui_window_current_style_attr; /* current attributes (bold, ..) */
|
||||
int gui_window_current_color_attr; /* attr sum of last color(s) used */
|
||||
int gui_window_saved_style[4]; /* current style saved */
|
||||
int gui_window_current_emphasis; /* 1 if text emphasis is enabled */
|
||||
struct t_gui_window_saved_style gui_window_saved_style[GUI_WINDOW_MAX_SAVED_STYLES];
|
||||
/* circular list of saved styles */
|
||||
int gui_window_saved_style_index = 0; /* index in list of savec styles */
|
||||
|
||||
|
||||
/*
|
||||
@@ -218,12 +223,28 @@ gui_window_clrtoeol (WINDOW *window)
|
||||
*/
|
||||
|
||||
void
|
||||
gui_window_save_style ()
|
||||
gui_window_save_style (WINDOW *window)
|
||||
{
|
||||
gui_window_saved_style[0] = gui_window_current_style_fg;
|
||||
gui_window_saved_style[1] = gui_window_current_style_bg;
|
||||
gui_window_saved_style[2] = gui_window_current_style_attr;
|
||||
gui_window_saved_style[3] = gui_window_current_color_attr;
|
||||
struct t_gui_window_saved_style *ptr_saved_style;
|
||||
attr_t *ptr_attrs;
|
||||
short *ptr_pair;
|
||||
|
||||
/* get pointer on saved style */
|
||||
ptr_saved_style = &gui_window_saved_style[gui_window_saved_style_index];
|
||||
|
||||
/* save current style */
|
||||
ptr_saved_style->style_fg = gui_window_current_style_fg;
|
||||
ptr_saved_style->style_bg = gui_window_current_style_bg;
|
||||
ptr_saved_style->color_attr = gui_window_current_color_attr;
|
||||
ptr_saved_style->emphasis = gui_window_current_emphasis;
|
||||
ptr_attrs = &ptr_saved_style->attrs;
|
||||
ptr_pair = &ptr_saved_style->pair;
|
||||
wattr_get (window, ptr_attrs, ptr_pair, NULL);
|
||||
|
||||
/* increment style index (circular list) */
|
||||
gui_window_saved_style_index++;
|
||||
if (gui_window_saved_style_index >= GUI_WINDOW_MAX_SAVED_STYLES)
|
||||
gui_window_saved_style_index = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -231,12 +252,30 @@ gui_window_save_style ()
|
||||
*/
|
||||
|
||||
void
|
||||
gui_window_restore_style ()
|
||||
gui_window_restore_style (WINDOW *window)
|
||||
{
|
||||
gui_window_current_style_fg = gui_window_saved_style[0];
|
||||
gui_window_current_style_bg = gui_window_saved_style[1];
|
||||
gui_window_current_style_attr = gui_window_saved_style[2];
|
||||
gui_window_current_color_attr = gui_window_saved_style[3];
|
||||
struct t_gui_window_saved_style *ptr_saved_style;
|
||||
|
||||
/* decrement style index (circular list) */
|
||||
gui_window_saved_style_index--;
|
||||
if (gui_window_saved_style_index < 0)
|
||||
gui_window_saved_style_index = GUI_WINDOW_MAX_SAVED_STYLES - 1;
|
||||
|
||||
/* get pointer on saved style */
|
||||
ptr_saved_style = &gui_window_saved_style[gui_window_saved_style_index];
|
||||
|
||||
/* restore style */
|
||||
gui_window_current_style_fg = ptr_saved_style->style_fg;
|
||||
gui_window_current_style_bg = ptr_saved_style->style_bg;
|
||||
gui_window_current_color_attr = ptr_saved_style->color_attr;
|
||||
gui_window_current_emphasis = ptr_saved_style->emphasis;
|
||||
wattr_set (window, ptr_saved_style->attrs, ptr_saved_style->pair, NULL);
|
||||
/*
|
||||
* for unknown reason, the wattr_set function sometimes
|
||||
* fails to set the color pair under FreeBSD, so we force
|
||||
* it again with wcolor_set
|
||||
*/
|
||||
wcolor_set (window, ptr_saved_style->pair, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -248,7 +287,6 @@ gui_window_reset_style (WINDOW *window, int weechat_color)
|
||||
{
|
||||
gui_window_current_style_fg = -1;
|
||||
gui_window_current_style_bg = -1;
|
||||
gui_window_current_style_attr = 0;
|
||||
gui_window_current_color_attr = 0;
|
||||
|
||||
wattroff (window, A_BOLD | A_UNDERLINE | A_REVERSE);
|
||||
@@ -406,11 +444,10 @@ gui_window_set_custom_color_fg (WINDOW *window, int fg)
|
||||
void
|
||||
gui_window_set_custom_color_bg (WINDOW *window, int bg)
|
||||
{
|
||||
int current_attr, current_fg;
|
||||
int current_fg;
|
||||
|
||||
if (bg >= 0)
|
||||
{
|
||||
current_attr = gui_window_current_style_attr;
|
||||
current_fg = gui_window_current_style_fg;
|
||||
|
||||
if ((bg > 0) && (bg & GUI_COLOR_EXTENDED_FLAG))
|
||||
@@ -422,7 +459,6 @@ gui_window_set_custom_color_bg (WINDOW *window, int bg)
|
||||
else if ((bg & GUI_COLOR_EXTENDED_MASK) < GUI_CURSES_NUM_WEECHAT_COLORS)
|
||||
{
|
||||
bg &= GUI_COLOR_EXTENDED_MASK;
|
||||
gui_window_set_color_style (window, current_attr);
|
||||
gui_window_set_color (window, current_fg,
|
||||
(gui_color_term_colors >= 16) ?
|
||||
gui_weechat_colors[bg].background : gui_weechat_colors[bg].foreground);
|
||||
@@ -514,6 +550,56 @@ gui_window_set_custom_color_pair (WINDOW *window, int pair)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Toggles text emphasis.
|
||||
*/
|
||||
|
||||
void
|
||||
gui_window_toggle_emphasis ()
|
||||
{
|
||||
gui_window_current_emphasis ^= 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emphasizes some chars already displayed in a window, either using a color
|
||||
* (from config options), or by doing an exclusive or (XOR) with attributes
|
||||
* (like reverse video).
|
||||
*
|
||||
* It is used for example when searching a string in buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
gui_window_emphasize (WINDOW *window, int x, int y, int count)
|
||||
{
|
||||
attr_t attrs, *ptr_attrs;
|
||||
short pair, *ptr_pair;
|
||||
|
||||
if (config_emphasized_attributes == 0)
|
||||
{
|
||||
/* use color for emphasis (from config) */
|
||||
mvwchgat (window, y, x, count,
|
||||
gui_color[GUI_COLOR_EMPHASIS]->attributes,
|
||||
gui_color_weechat_get_pair (GUI_COLOR_EMPHASIS), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* exclusive or (XOR) with attributes */
|
||||
ptr_attrs = &attrs;
|
||||
ptr_pair = &pair;
|
||||
wattr_get (window, ptr_attrs, ptr_pair, NULL);
|
||||
if (config_emphasized_attributes & GUI_COLOR_EXTENDED_BOLD_FLAG)
|
||||
attrs ^= A_BOLD;
|
||||
if (config_emphasized_attributes & GUI_COLOR_EXTENDED_REVERSE_FLAG)
|
||||
attrs ^= A_REVERSE;
|
||||
if (config_emphasized_attributes & GUI_COLOR_EXTENDED_UNDERLINE_FLAG)
|
||||
attrs ^= A_UNDERLINE;
|
||||
mvwchgat (window, y, x, count, attrs, pair, NULL);
|
||||
}
|
||||
|
||||
/* move the cursor after the text (mvwchgat does not move cursor) */
|
||||
wmove (window, y, x + count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Applies foreground color code in string and moves string pointer after color
|
||||
* in string.
|
||||
|
||||
@@ -45,6 +45,16 @@ struct t_gui_bar_window;
|
||||
#define GUI_BAR_WINDOW_OBJECTS(bar_window) \
|
||||
((struct t_gui_bar_window_curses_objects *)(bar_window->gui_objects))
|
||||
|
||||
struct t_gui_window_saved_style
|
||||
{
|
||||
int style_fg;
|
||||
int style_bg;
|
||||
int color_attr;
|
||||
int emphasis;
|
||||
attr_t attrs;
|
||||
short pair;
|
||||
};
|
||||
|
||||
struct t_gui_window_curses_objects
|
||||
{
|
||||
WINDOW *win_chat; /* chat window (example: channel) */
|
||||
@@ -66,6 +76,7 @@ extern int gui_color_pairs_auto_reset;
|
||||
extern int gui_color_pairs_auto_reset_pending;
|
||||
extern time_t gui_color_pairs_auto_reset_last;
|
||||
extern int gui_color_buffer_refresh_needed;
|
||||
extern int gui_window_current_emphasis;
|
||||
|
||||
/* color functions */
|
||||
extern int gui_color_get_pair (int fg, int bg);
|
||||
@@ -88,6 +99,8 @@ extern void gui_window_read_terminal_size ();
|
||||
extern void gui_window_redraw_buffer (struct t_gui_buffer *buffer);
|
||||
extern void gui_window_clear (WINDOW *window, int fg, int bg);
|
||||
extern void gui_window_clrtoeol (WINDOW *window);
|
||||
extern void gui_window_save_style (WINDOW *window);
|
||||
extern void gui_window_restore_style (WINDOW *window);
|
||||
extern void gui_window_reset_style (WINDOW *window, int num_color);
|
||||
extern void gui_window_reset_color (WINDOW *window, int num_color);
|
||||
extern void gui_window_set_color_style (WINDOW *window, int style);
|
||||
@@ -98,6 +111,8 @@ extern void gui_window_set_custom_color_fg_bg (WINDOW *window, int fg, int bg);
|
||||
extern void gui_window_set_custom_color_pair (WINDOW *window, int pair);
|
||||
extern void gui_window_set_custom_color_fg (WINDOW *window, int fg);
|
||||
extern void gui_window_set_custom_color_bg (WINDOW *window, int bg);
|
||||
extern void gui_window_toggle_emphasis ();
|
||||
extern void gui_window_emphasize (WINDOW *window, int x, int y, int count);
|
||||
extern void gui_window_string_apply_color_fg (unsigned char **str,
|
||||
WINDOW *window);
|
||||
extern void gui_window_string_apply_color_bg (unsigned char **str,
|
||||
@@ -112,8 +127,6 @@ extern void gui_window_string_apply_color_set_attr (unsigned char **str,
|
||||
WINDOW *window);
|
||||
extern void gui_window_string_apply_color_remove_attr (unsigned char **str,
|
||||
WINDOW *window);
|
||||
extern void gui_window_apply_color (unsigned char **str, WINDOW *window,
|
||||
int apply_bar_colors);
|
||||
extern void gui_window_set_title (const char *title);
|
||||
|
||||
#endif /* __WEECHAT_GUI_CURSES_H */
|
||||
|
||||
@@ -241,6 +241,8 @@ gui_chat_string_add_offset_screen (const char *string, int offset_screen)
|
||||
/*
|
||||
* Gets real position in string (ignoring formatting chars like
|
||||
* colors/attributes).
|
||||
*
|
||||
* Returns real position, in bytes.
|
||||
*/
|
||||
|
||||
int
|
||||
@@ -275,6 +277,36 @@ gui_chat_string_real_pos (const char *string, int pos)
|
||||
return 0 + (real_pos - string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets real position in string (ignoring formatting chars like
|
||||
* colors/attributes).
|
||||
*
|
||||
* Returns position, in number of UTF-8 chars.
|
||||
*/
|
||||
|
||||
int
|
||||
gui_chat_string_pos (const char *string, int real_pos)
|
||||
{
|
||||
const char *ptr_string, *limit;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
ptr_string = string;
|
||||
limit = ptr_string + real_pos;
|
||||
while (ptr_string && ptr_string[0] && (ptr_string < limit))
|
||||
{
|
||||
ptr_string = gui_chat_string_next_char (NULL, NULL,
|
||||
(unsigned char *)ptr_string,
|
||||
0, 0, 0);
|
||||
if (ptr_string)
|
||||
{
|
||||
ptr_string = utf8_next_char (ptr_string);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns info about next word: beginning, end, length.
|
||||
*
|
||||
|
||||
@@ -71,6 +71,7 @@ extern char *gui_chat_string_add_offset (const char *string, int offset);
|
||||
extern char *gui_chat_string_add_offset_screen (const char *string,
|
||||
int offset_screen);
|
||||
extern int gui_chat_string_real_pos (const char *string, int pos);
|
||||
extern int gui_chat_string_pos (const char *string, int real_pos);
|
||||
extern void gui_chat_get_word_info (struct t_gui_window *window,
|
||||
const char *data, int *word_start_offset,
|
||||
int *word_end_offset,
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "../core/wee-utf8.h"
|
||||
#include "../plugins/plugin.h"
|
||||
#include "gui-color.h"
|
||||
#include "gui-chat.h"
|
||||
#include "gui-window.h"
|
||||
|
||||
|
||||
@@ -171,6 +172,13 @@ gui_color_get_custom (const char *color_name)
|
||||
GUI_COLOR_COLOR_CHAR,
|
||||
GUI_COLOR_RESET_CHAR);
|
||||
}
|
||||
else if (string_strcasecmp (color_name, "emphasis") == 0)
|
||||
{
|
||||
snprintf (color[index_color], sizeof (color[index_color]),
|
||||
"%c%c",
|
||||
GUI_COLOR_COLOR_CHAR,
|
||||
GUI_COLOR_EMPHASIS_CHAR);
|
||||
}
|
||||
else if (string_strcasecmp (color_name, "bold") == 0)
|
||||
{
|
||||
snprintf (color[index_color], sizeof (color[index_color]),
|
||||
@@ -518,6 +526,9 @@ gui_color_decode (const char *string, const char *replacement)
|
||||
&& (isdigit (ptr_string[5])))
|
||||
ptr_string += 6;
|
||||
break;
|
||||
case GUI_COLOR_EMPHASIS_CHAR:
|
||||
ptr_string++;
|
||||
break;
|
||||
case GUI_COLOR_BAR_CHAR:
|
||||
ptr_string++;
|
||||
switch (ptr_string[0])
|
||||
@@ -582,6 +593,155 @@ gui_color_decode (const char *string, const char *replacement)
|
||||
return (char *)out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emphasizes a string or regular expression in a string (which can contain
|
||||
* colors).
|
||||
*
|
||||
* Argument "case_sensitive" is used only for "search", if the "regex" is NULL.
|
||||
*
|
||||
* Returns string with the search string/regex emphasized, NULL if error.
|
||||
*
|
||||
* Note: result must be freed after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
gui_color_emphasize (const char *string,
|
||||
const char *search, int case_sensitive,
|
||||
regex_t *regex)
|
||||
{
|
||||
regmatch_t regex_match;
|
||||
char *result, *result2, *string_no_color, *pos;
|
||||
const char *ptr_string, *ptr_no_color, *color_emphasis;
|
||||
int rc, length_search, length_emphasis, length_result;
|
||||
int pos1, pos2, real_pos1, real_pos2, count_emphasis;
|
||||
|
||||
if (!string && !regex)
|
||||
return NULL;
|
||||
|
||||
color_emphasis = gui_color_get_custom ("emphasis");
|
||||
if (!color_emphasis)
|
||||
return NULL;
|
||||
length_emphasis = strlen (color_emphasis);
|
||||
|
||||
/*
|
||||
* allocate space for 8 emphasized strings (8 before + 8 after = 16);
|
||||
* more space will be allocated later (if there are more than 8 emphasized
|
||||
* strings)
|
||||
*/
|
||||
length_result = strlen (string) + (length_emphasis * 2 * 8) + 1;
|
||||
result = malloc (length_result);
|
||||
if (!result)
|
||||
return NULL;
|
||||
result[0] = '\0';
|
||||
|
||||
/*
|
||||
* build a string without color codes to search in this one (then with the
|
||||
* position of text found, we will retrieve position in original string,
|
||||
* which can contain color codes)
|
||||
*/
|
||||
string_no_color = gui_color_decode (string, NULL);
|
||||
if (!string_no_color)
|
||||
{
|
||||
free (result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length_search = (search) ? strlen (search) : 0;
|
||||
|
||||
ptr_string = string;
|
||||
ptr_no_color = string_no_color;
|
||||
|
||||
count_emphasis = 0;
|
||||
|
||||
while (ptr_no_color && ptr_no_color[0])
|
||||
{
|
||||
if (regex)
|
||||
{
|
||||
/* search next match using the regex */
|
||||
rc = regexec (regex, ptr_no_color, 1, ®ex_match, 0);
|
||||
|
||||
/*
|
||||
* no match found: exit the loop (if rm_no == 0, it is an empty
|
||||
* match at beginning of string: we consider there is no match, to
|
||||
* prevent an infinite loop)
|
||||
*/
|
||||
if ((rc != 0) || (regex_match.rm_so < 0) || (regex_match.rm_eo <= 0))
|
||||
{
|
||||
strcat (result, ptr_string);
|
||||
break;
|
||||
}
|
||||
pos1 = regex_match.rm_so;
|
||||
pos2 = regex_match.rm_eo;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* search next match in the string */
|
||||
if (case_sensitive)
|
||||
pos = strstr (ptr_no_color, search);
|
||||
else
|
||||
pos = string_strcasestr (ptr_no_color, search);
|
||||
if (!pos)
|
||||
{
|
||||
strcat (result, ptr_string);
|
||||
break;
|
||||
}
|
||||
pos1 = pos - ptr_no_color;
|
||||
pos2 = pos1 + length_search;
|
||||
if (pos2 <= 0)
|
||||
{
|
||||
strcat (result, ptr_string);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* find the position of match in the original string (which can contain
|
||||
* color codes)
|
||||
*/
|
||||
real_pos1 = gui_chat_string_real_pos (ptr_string,
|
||||
gui_chat_string_pos (ptr_no_color, pos1));
|
||||
real_pos2 = gui_chat_string_real_pos (ptr_string,
|
||||
gui_chat_string_pos (ptr_no_color, pos2));
|
||||
|
||||
/*
|
||||
* concatenate following strings to the result:
|
||||
* - beginning of string (before match)
|
||||
* - emphasis color code
|
||||
* - the matching string
|
||||
* - emphasis color code
|
||||
*/
|
||||
if (real_pos1 > 0)
|
||||
strncat (result, ptr_string, real_pos1);
|
||||
strcat (result, color_emphasis);
|
||||
strncat (result, ptr_string + real_pos1, real_pos2 - real_pos1);
|
||||
strcat (result, color_emphasis);
|
||||
|
||||
/* restart next loop after the matching string */
|
||||
ptr_string += real_pos2;
|
||||
ptr_no_color += pos2;
|
||||
|
||||
/* check if we should allocate more space for emphasis color codes */
|
||||
count_emphasis++;
|
||||
if (count_emphasis == 8)
|
||||
{
|
||||
/* allocate more space for emphasis color codes */
|
||||
length_result += (length_emphasis * 2 * 8);
|
||||
result2 = realloc (result, length_result);
|
||||
if (!result2)
|
||||
{
|
||||
free (result);
|
||||
return NULL;
|
||||
}
|
||||
result = result2;
|
||||
count_emphasis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free (string_no_color);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees a color.
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __WEECHAT_GUI_COLOR_H
|
||||
#define __WEECHAT_GUI_COLOR_H 1
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
/*
|
||||
* Color from configuration options.
|
||||
* When changing some colors below:
|
||||
@@ -78,6 +80,7 @@ enum t_gui_color_enum
|
||||
GUI_COLOR_CHAT_NICK_OFFLINE_HIGHLIGHT,
|
||||
GUI_COLOR_CHAT_NICK_PREFIX,
|
||||
GUI_COLOR_CHAT_NICK_SUFFIX,
|
||||
GUI_COLOR_EMPHASIS,
|
||||
|
||||
/* number of colors */
|
||||
GUI_COLOR_NUM_COLORS,
|
||||
@@ -112,6 +115,7 @@ enum t_gui_color_enum
|
||||
#define GUI_COLOR_EXTENDED_ITALIC_CHAR '/'
|
||||
#define GUI_COLOR_EXTENDED_UNDERLINE_CHAR '_'
|
||||
#define GUI_COLOR_EXTENDED_KEEPATTR_CHAR '|'
|
||||
#define GUI_COLOR_EMPHASIS_CHAR 'E'
|
||||
|
||||
/* color codes specific to bars */
|
||||
#define GUI_COLOR_BAR_CHAR 'b'
|
||||
@@ -165,6 +169,8 @@ extern int gui_color_attr_get_flag (char c);
|
||||
extern void gui_color_attr_build_string (int color, char *str_attr);
|
||||
extern const char *gui_color_get_custom (const char *color_name);
|
||||
extern char *gui_color_decode (const char *string, const char *replacement);
|
||||
extern char *gui_color_emphasize (const char *string, const char *search,
|
||||
int case_sensitive, regex_t *regex);
|
||||
extern void gui_color_free (struct t_gui_color *color);
|
||||
extern void gui_color_palette_alloc_structs ();
|
||||
extern int gui_color_palette_get_alias (const char *alias);
|
||||
|
||||
@@ -201,8 +201,6 @@ extern int gui_window_get_height ();
|
||||
extern int gui_window_objects_init (struct t_gui_window *window);
|
||||
extern void gui_window_objects_free (struct t_gui_window *window,
|
||||
int free_separators);
|
||||
extern void gui_window_save_style ();
|
||||
extern void gui_window_restore_style ();
|
||||
extern void gui_window_calculate_pos_size (struct t_gui_window *window);
|
||||
extern void gui_window_switch_to_buffer (struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
|
||||
Reference in New Issue
Block a user