mirror of
https://github.com/weechat/weechat.git
synced 2026-07-01 23:36:37 +02:00
core: add modifier and infos to decode ANSI colors
New modifier: - color_decode_ansi: convert ANSI colors to WeeChat colors (or remove colors). New infos: - color_ansi_regex: regex used to parse ANSI colors in a string - color_term2rgb: convert a terminal color (0-255) to RGB - color_rgb2term: convert a RGB color to terminal color (0-255)
This commit is contained in:
@@ -9132,12 +9132,12 @@ List of modifiers used by WeeChat and plugins:
|
||||
| irc_color_decode |
|
||||
"1" to keep colors, "0" to remove colors |
|
||||
Any string |
|
||||
String with WeeChat color codes, or without color
|
||||
String with IRC colors converted to WeeChat colors (or IRC colors removed)
|
||||
|
||||
| irc_color_encode |
|
||||
"1" to keep colors, "0" to remove colors |
|
||||
Any string |
|
||||
String with IRC color codes, or without color
|
||||
String with IRC colors (or IRC colors removed)
|
||||
|
||||
| irc_command_auth +
|
||||
_(WeeChat ≥ 0.4.1)_ |
|
||||
@@ -9175,6 +9175,12 @@ List of modifiers used by WeeChat and plugins:
|
||||
fit in 512 bytes) |
|
||||
New content of message
|
||||
|
||||
| color_decode_ansi +
|
||||
_(WeeChat ≥ 0.4.4)_ |
|
||||
"1" to keep colors, "0" to remove colors |
|
||||
Any string |
|
||||
String with ANSI colors converted to WeeChat colors (or ANSI colors removed)
|
||||
|
||||
| bar_condition_yyy ^(2)^ |
|
||||
String with window pointer ("0x123..") |
|
||||
Empty string |
|
||||
|
||||
@@ -9300,12 +9300,13 @@ Liste des modificateurs utilisés par WeeChat et les extensions :
|
||||
| irc_color_decode |
|
||||
"1" pour garder les couleurs, "0" pour les supprimer |
|
||||
Toute chaîne |
|
||||
Chaîne avec des codes couleur WeeChat, ou sans couleur
|
||||
Chaîne avec les couleurs IRC converties en couleurs WeeChat (ou avec les
|
||||
couleurs IRC supprimées)
|
||||
|
||||
| irc_color_encode |
|
||||
"1" pour garder les couleurs, "0" pour les supprimer |
|
||||
Toute chaîne |
|
||||
Chaîne avec des codes couleur IRC, ou sans couleur
|
||||
Chaîne avec les couleurs IRC (ou avec les couleurs IRC supprimées)
|
||||
|
||||
| irc_command_auth +
|
||||
_(WeeChat ≥ 0.4.1)_ |
|
||||
@@ -9343,6 +9344,13 @@ Liste des modificateurs utilisés par WeeChat et les extensions :
|
||||
automatique pour tenir dans les 512 octets) |
|
||||
Nouveau contenu du message
|
||||
|
||||
| color_decode_ansi +
|
||||
_(WeeChat ≥ 0.4.4)_ |
|
||||
"1" pour garder les couleurs, "0" pour les supprimer |
|
||||
Toute chaîne |
|
||||
Chaîne avec les couleurs ANSI converties en couleurs WeeChat (ou avec les
|
||||
couleurs ANSI supprimées)
|
||||
|
||||
| bar_condition_yyy ^(2)^ |
|
||||
Chaîne avec un pointeur vers la fenêtre ("0x123..") |
|
||||
Chaîne vide |
|
||||
|
||||
@@ -9356,15 +9356,17 @@ List of modifiers used by WeeChat and plugins:
|
||||
Qualsiasi stringa |
|
||||
Stringa codificata da UTF-8 al set caratteri trovato per il plugin/buffer
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| irc_color_decode |
|
||||
"1" per mantenere i colori, "0" per rimuovere i colori |
|
||||
Qualsiasi stringa |
|
||||
Stringa con i codici colori di Weechat, o senza colore
|
||||
String with IRC colors converted to WeeChat colors (or IRC colors removed)
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| irc_color_encode |
|
||||
"1" per mantenere i colori, "0" per rimuovere i colori |
|
||||
Qualsiasi stringa |
|
||||
Stringa con i codici colori IRC, o senza colore
|
||||
String with IRC colors (or IRC colors removed)
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| irc_command_auth +
|
||||
@@ -9402,6 +9404,13 @@ List of modifiers used by WeeChat and plugins:
|
||||
Contenuto del messaggio che sta per essere inviato al server IRC (dopo la divisione automatica da adattare in 512 byte) |
|
||||
Nuovo contenuto del messaggio
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| color_decode_ansi +
|
||||
_(WeeChat ≥ 0.4.4)_ |
|
||||
"1" per mantenere i colori, "0" per rimuovere i colori |
|
||||
Qualsiasi stringa |
|
||||
String with ANSI colors converted to WeeChat colors (or ANSI colors removed)
|
||||
|
||||
| bar_condition_yyy ^(2)^ |
|
||||
Stringa con puntatore alla finestra ("0x123..") |
|
||||
Stringa vuota |
|
||||
|
||||
@@ -9148,15 +9148,17 @@ WeeChat とプラグインが使う修飾子のリスト:
|
||||
任意の文字列 |
|
||||
UTF-8 からプラグインおよびバッファの文字セットにエンコードされた文字列
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| irc_color_decode |
|
||||
色を保持する場合は "1"、削除する場合は "0" |
|
||||
任意の文字列 |
|
||||
WeeChat 色コードを含む文字列および含まない文字列
|
||||
String with IRC colors converted to WeeChat colors (or IRC colors removed)
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| irc_color_encode |
|
||||
色を保持する場合は "1"、削除する場合は "0" |
|
||||
任意の文字列 |
|
||||
IRC 色コードを含む文字列および含まない文字列
|
||||
String with IRC colors (or IRC colors removed)
|
||||
|
||||
| irc_command_auth +
|
||||
_(WeeChat バージョン 0.4.1 以上で利用可)_ |
|
||||
@@ -9192,6 +9194,13 @@ WeeChat とプラグインが使う修飾子のリスト:
|
||||
IRC サーバに送信するメッセージの内容 (512 バイトを超えないように自動分割した後) |
|
||||
メッセージの新しい内容
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| color_decode_ansi +
|
||||
_(WeeChat バージョン 0.4.4 以上で利用可)_ |
|
||||
色を保持する場合は "1"、削除する場合は "0" |
|
||||
任意の文字列 |
|
||||
String with ANSI colors converted to WeeChat colors (or ANSI colors removed)
|
||||
|
||||
| bar_condition_yyy ^(2)^ |
|
||||
ウィンドウへのポインタの文字列 ("0x123..") |
|
||||
空文字列 |
|
||||
|
||||
@@ -1539,20 +1539,3 @@ gui_color_dump ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ends GUI colors.
|
||||
*/
|
||||
|
||||
void
|
||||
gui_color_end ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GUI_COLOR_NUM_COLORS; i++)
|
||||
{
|
||||
gui_color_free (gui_color[i]);
|
||||
}
|
||||
gui_color_palette_free_structs ();
|
||||
gui_color_free_vars ();
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@ extern int gui_color_get_pair (int fg, int bg);
|
||||
extern int gui_color_weechat_get_pair (int weechat_color);
|
||||
extern void gui_color_pre_init ();
|
||||
extern void gui_color_init ();
|
||||
extern void gui_color_end ();
|
||||
|
||||
/* chat functions */
|
||||
extern void gui_chat_calculate_line_diff (struct t_gui_window *window,
|
||||
|
||||
@@ -100,6 +100,11 @@ int gui_color_term256[256] =
|
||||
0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee, /* 252-255 */
|
||||
};
|
||||
|
||||
/* ANSI colors */
|
||||
regex_t *gui_color_regex_ansi = NULL;
|
||||
char *gui_color_ansi[8] =
|
||||
{ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" };
|
||||
|
||||
|
||||
/*
|
||||
* Searches for a color with configuration option name.
|
||||
@@ -704,6 +709,216 @@ gui_color_decode (const char *string, const char *replacement)
|
||||
return (char *)out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts ANSI color codes to WeeChat colors (or removes them).
|
||||
*
|
||||
* This callback is called by gui_color_decode_ansi, it must not be called
|
||||
* directly.
|
||||
*/
|
||||
|
||||
char *
|
||||
gui_color_decode_ansi_cb (void *data, const char *text)
|
||||
{
|
||||
unsigned long keep_colors;
|
||||
char *text2, **items, *output, str_color[128];
|
||||
int i, length, num_items, value;
|
||||
|
||||
keep_colors = (unsigned long)data;
|
||||
|
||||
/* if we don't keep colors of if text is empty, just return empty string */
|
||||
if (!keep_colors || !text || !text[0])
|
||||
return strdup ("");
|
||||
|
||||
/* only sequences ending with 'm' are used, the others are discarded */
|
||||
length = strlen (text);
|
||||
if (text[length - 1] != 'm')
|
||||
return strdup ("");
|
||||
|
||||
/* sequence "\33[m" resets color */
|
||||
if (length < 4)
|
||||
return strdup (gui_color_get_custom ("reset"));
|
||||
|
||||
text2 = NULL;
|
||||
items = NULL;
|
||||
output = NULL;
|
||||
|
||||
/* extract text between "\33[" and "m" */
|
||||
text2 = string_strndup (text + 2, length - 3);
|
||||
if (!text2)
|
||||
goto end;
|
||||
|
||||
items = string_split (text2, ";", 0, 0, &num_items);
|
||||
if (!items)
|
||||
goto end;
|
||||
|
||||
output = malloc ((32 * num_items) + 1);
|
||||
if (!output)
|
||||
goto end;
|
||||
output[0] = '\0';
|
||||
|
||||
for (i = 0; i < num_items; i++)
|
||||
{
|
||||
value = atoi (items[i]);
|
||||
switch (value)
|
||||
{
|
||||
case 0: /* reset */
|
||||
strcat (output, gui_color_get_custom ("reset"));
|
||||
break;
|
||||
case 1: /* bold */
|
||||
strcat (output, gui_color_get_custom ("bold"));
|
||||
break;
|
||||
case 2: /* remove bold */
|
||||
case 21:
|
||||
case 22:
|
||||
strcat (output, gui_color_get_custom ("-bold"));
|
||||
break;
|
||||
case 3: /* italic */
|
||||
strcat (output, gui_color_get_custom ("italic"));
|
||||
break;
|
||||
case 4: /* underline */
|
||||
strcat (output, gui_color_get_custom ("underline"));
|
||||
break;
|
||||
case 23: /* remove italic */
|
||||
strcat (output, gui_color_get_custom ("-italic"));
|
||||
break;
|
||||
case 24: /* remove underline */
|
||||
strcat (output, gui_color_get_custom ("-underline"));
|
||||
break;
|
||||
case 30: /* text color */
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
case 36:
|
||||
case 37:
|
||||
strcat (output,
|
||||
gui_color_get_custom (gui_color_ansi[value - 30]));
|
||||
break;
|
||||
case 38: /* text color */
|
||||
if (i + 1 < num_items)
|
||||
{
|
||||
switch (atoi (items[i + 1]))
|
||||
{
|
||||
case 2: /* RGB color */
|
||||
if (i + 4 < num_items)
|
||||
{
|
||||
snprintf (str_color, sizeof (str_color),
|
||||
"|%d",
|
||||
gui_color_convert_rgb_to_term (
|
||||
(atoi (items[i + 2]) << 16) |
|
||||
(atoi (items[i + 3]) << 8) |
|
||||
atoi (items[i + 4]),
|
||||
256));
|
||||
strcat (output, gui_color_get_custom (str_color));
|
||||
i += 4;
|
||||
}
|
||||
break;
|
||||
case 5: /* terminal color (0-255) */
|
||||
if (i + 2 < num_items)
|
||||
{
|
||||
snprintf (str_color, sizeof (str_color),
|
||||
"|%d", atoi (items[i + 2]));
|
||||
strcat (output, gui_color_get_custom (str_color));
|
||||
i += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 39: /* default text color */
|
||||
strcat (output, gui_color_get_custom ("default"));
|
||||
break;
|
||||
case 40: /* background color */
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
snprintf (str_color, sizeof (str_color),
|
||||
"|,%s",
|
||||
gui_color_ansi[value - 40]);
|
||||
strcat (output, gui_color_get_custom (str_color));
|
||||
break;
|
||||
case 48: /* background color */
|
||||
if (i + 1 < num_items)
|
||||
{
|
||||
switch (atoi (items[i + 1]))
|
||||
{
|
||||
case 2: /* RGB color */
|
||||
if (i + 4 < num_items)
|
||||
{
|
||||
snprintf (str_color, sizeof (str_color),
|
||||
"|,%d",
|
||||
gui_color_convert_rgb_to_term (
|
||||
(atoi (items[i + 2]) << 16) |
|
||||
(atoi (items[i + 3]) << 8) |
|
||||
atoi (items[i + 4]),
|
||||
256));
|
||||
strcat (output, gui_color_get_custom (str_color));
|
||||
i += 4;
|
||||
}
|
||||
break;
|
||||
case 5: /* terminal color (0-255) */
|
||||
if (i + 2 < num_items)
|
||||
{
|
||||
snprintf (str_color, sizeof (str_color),
|
||||
"|,%d", atoi (items[i + 2]));
|
||||
strcat (output, gui_color_get_custom (str_color));
|
||||
i += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 49: /* default background color */
|
||||
strcat (output, gui_color_get_custom (",default"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (items)
|
||||
string_free_split (items);
|
||||
if (text2)
|
||||
free (text2);
|
||||
|
||||
return (output) ? output : strdup ("");
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts ANSI color codes to WeeChat colors (or removes them).
|
||||
*
|
||||
* Note: result must be freed after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
gui_color_decode_ansi (const char *string, int keep_colors)
|
||||
{
|
||||
/* allocate/compile regex if needed (first call) */
|
||||
if (!gui_color_regex_ansi)
|
||||
{
|
||||
gui_color_regex_ansi = malloc (sizeof (*gui_color_regex_ansi));
|
||||
if (!gui_color_regex_ansi)
|
||||
return NULL;
|
||||
if (string_regcomp (gui_color_regex_ansi,
|
||||
GUI_COLOR_REGEX_ANSI_DECODE,
|
||||
REG_EXTENDED) != 0)
|
||||
{
|
||||
free (gui_color_regex_ansi);
|
||||
gui_color_regex_ansi = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return string_replace_regex (string, gui_color_regex_ansi,
|
||||
"$0", '$',
|
||||
&gui_color_decode_ansi_cb,
|
||||
(void *)((unsigned long)keep_colors));
|
||||
}
|
||||
|
||||
/*
|
||||
* Emphasizes a string or regular expression in a string (which can contain
|
||||
* colors).
|
||||
@@ -1027,3 +1242,27 @@ gui_color_palette_free_structs ()
|
||||
if (gui_color_list_with_alias)
|
||||
weelist_free (gui_color_list_with_alias);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ends GUI colors.
|
||||
*/
|
||||
|
||||
void
|
||||
gui_color_end ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GUI_COLOR_NUM_COLORS; i++)
|
||||
{
|
||||
gui_color_free (gui_color[i]);
|
||||
}
|
||||
gui_color_palette_free_structs ();
|
||||
gui_color_free_vars ();
|
||||
|
||||
if (gui_color_regex_ansi)
|
||||
{
|
||||
regfree (gui_color_regex_ansi);
|
||||
free (gui_color_regex_ansi);
|
||||
gui_color_regex_ansi = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -138,6 +138,12 @@ enum t_gui_color_enum
|
||||
#define GUI_COLOR_EXTENDED_MASK 0x00FFFFF
|
||||
#define GUI_COLOR_EXTENDED_MAX 99999
|
||||
|
||||
#define GUI_COLOR_REGEX_ANSI_DECODE \
|
||||
"\33(" \
|
||||
"([()].)|" \
|
||||
"([<>])|" \
|
||||
"(\\[[0-9;?]*[A-Za-z]))"
|
||||
|
||||
/* color structure */
|
||||
|
||||
struct t_gui_color
|
||||
@@ -169,9 +175,10 @@ extern const char *gui_color_search_config (const char *color_name);
|
||||
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 int gui_color_convert_term_to_rgb (int color);
|
||||
extern int gui_color_convert_rgb_to_term (int rgb, int limit);
|
||||
extern char *gui_color_decode (const char *string, const char *replacement);
|
||||
extern char *gui_color_decode_ansi (const char *string, int keep_colors);
|
||||
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);
|
||||
@@ -180,7 +187,7 @@ extern int gui_color_palette_get_alias (const char *alias);
|
||||
extern struct t_gui_color_palette *gui_color_palette_get (int number);
|
||||
extern void gui_color_palette_add (int number, const char *value);
|
||||
extern void gui_color_palette_remove (int number);
|
||||
extern void gui_color_palette_free_structs ();
|
||||
extern void gui_color_end ();
|
||||
|
||||
/* color functions (GUI dependent) */
|
||||
|
||||
@@ -191,6 +198,7 @@ extern int gui_color_assign_by_diff (int *color, const char *color_name,
|
||||
extern int gui_color_get_weechat_colors_number ();
|
||||
extern int gui_color_get_term_colors ();
|
||||
extern const char *gui_color_get_name (int num_color);
|
||||
extern void gui_color_free_vars ();
|
||||
extern void gui_color_init_weechat ();
|
||||
extern void gui_color_display_terminal_colors ();
|
||||
extern void gui_color_info_term_colors (char *buffer, int size);
|
||||
|
||||
@@ -277,6 +277,25 @@ plugin_api_command (struct t_weechat_plugin *plugin,
|
||||
free (command2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Modifier to decode ANSI colors.
|
||||
*/
|
||||
|
||||
char *
|
||||
plugin_api_modifier_color_decode_ansi (void *data,
|
||||
const char *modifier,
|
||||
const char *modifier_data,
|
||||
const char *string)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) modifier;
|
||||
|
||||
return gui_color_decode_ansi (string,
|
||||
(modifier_data && (strcmp (modifier_data, "1") == 0)) ?
|
||||
1: 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets info about WeeChat.
|
||||
*/
|
||||
@@ -288,10 +307,11 @@ plugin_api_info_get_internal (void *data, const char *info_name,
|
||||
time_t inactivity;
|
||||
static char value[32], version_number[32] = { '\0' };
|
||||
static char weechat_dir_absolute_path[PATH_MAX] = { '\0' };
|
||||
int rgb, limit;
|
||||
char *pos, *color;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) arguments;
|
||||
|
||||
if (!info_name)
|
||||
return NULL;
|
||||
@@ -397,6 +417,43 @@ plugin_api_info_get_internal (void *data, const char *info_name,
|
||||
snprintf (value, sizeof (value), "%d", gui_window_get_height ());
|
||||
return value;
|
||||
}
|
||||
else if (string_strcasecmp (info_name, "color_ansi_regex") == 0)
|
||||
{
|
||||
return GUI_COLOR_REGEX_ANSI_DECODE;
|
||||
}
|
||||
else if (string_strcasecmp (info_name, "color_term2rgb") == 0)
|
||||
{
|
||||
if (arguments && arguments[0])
|
||||
{
|
||||
snprintf (value, sizeof (value),
|
||||
"%d",
|
||||
gui_color_convert_term_to_rgb (atoi (arguments)));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if (string_strcasecmp (info_name, "color_rgb2term") == 0)
|
||||
{
|
||||
if (arguments && arguments[0])
|
||||
{
|
||||
limit = 256;
|
||||
pos = strchr (arguments, ',');
|
||||
if (pos)
|
||||
{
|
||||
color = string_strndup (arguments, pos - arguments);
|
||||
if (!color)
|
||||
return NULL;
|
||||
rgb = atoi (color);
|
||||
limit = atoi (pos + 1);
|
||||
free (color);
|
||||
}
|
||||
else
|
||||
rgb = atoi (arguments);
|
||||
snprintf (value, sizeof (value),
|
||||
"%d",
|
||||
gui_color_convert_rgb_to_term (rgb, limit));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/* info not found */
|
||||
return NULL;
|
||||
@@ -1097,6 +1154,10 @@ plugin_api_infolist_free (struct t_infolist *infolist)
|
||||
void
|
||||
plugin_api_init ()
|
||||
{
|
||||
/* WeeChat core modifiers */
|
||||
hook_modifier (NULL, "color_decode_ansi",
|
||||
&plugin_api_modifier_color_decode_ansi, NULL);
|
||||
|
||||
/* WeeChat core info hooks */
|
||||
hook_info (NULL, "version", N_("WeeChat version"), NULL,
|
||||
&plugin_api_info_get_internal, NULL);
|
||||
@@ -1141,6 +1202,12 @@ plugin_api_init ()
|
||||
&plugin_api_info_get_internal, NULL);
|
||||
hook_info (NULL, "term_height", N_("height of terminal"), NULL,
|
||||
&plugin_api_info_get_internal, NULL);
|
||||
hook_info (NULL, "color_ansi_regex", N_("regular expression to match ANSI escape codes"), NULL,
|
||||
&plugin_api_info_get_internal, NULL);
|
||||
hook_info (NULL, "color_term2rgb", N_("terminal color (0-255) converted to RGB color"), NULL,
|
||||
&plugin_api_info_get_internal, NULL);
|
||||
hook_info (NULL, "color_rgb2term", N_("RGB color converted to terminal color (0-255)"), NULL,
|
||||
&plugin_api_info_get_internal, NULL);
|
||||
|
||||
/* WeeChat core infolist hooks */
|
||||
hook_infolist (NULL, "bar", N_("list of bars"),
|
||||
|
||||
Reference in New Issue
Block a user