degesch: unfuck terminal attribute handling
This commit is contained in:
parent
21656d462f
commit
101ab90100
135
degesch.c
135
degesch.c
|
@ -21,23 +21,37 @@
|
|||
/// Some arbitrary limit for the history file
|
||||
#define HISTORY_LIMIT 10000
|
||||
|
||||
// String constants for all attributes we use for output
|
||||
#define ATTR_PROMPT "attr_prompt"
|
||||
#define ATTR_RESET "attr_reset"
|
||||
#define ATTR_WARNING "attr_warning"
|
||||
#define ATTR_ERROR "attr_error"
|
||||
#define ATTR_TABLE(XX) \
|
||||
XX( PROMPT, "prompt", "Terminal attributes for the prompt" ) \
|
||||
XX( RESET, "reset", "String to reset terminal attributes" ) \
|
||||
XX( WARNING, "warning", "Terminal attributes for warnings" ) \
|
||||
XX( ERROR, "error", "Terminal attributes for errors" ) \
|
||||
XX( EXTERNAL, "external", "Terminal attributes for external lines" ) \
|
||||
XX( TIMESTAMP, "timestamp", "Terminal attributes for timestamps" ) \
|
||||
XX( HIGHLIGHT, "highlight", "Terminal attributes for highlights" ) \
|
||||
XX( ACTION, "action", "Terminal attributes for user actions" ) \
|
||||
XX( JOIN, "join", "Terminal attributes for joins" ) \
|
||||
XX( PART, "part", "Terminal attributes for parts" )
|
||||
|
||||
#define ATTR_EXTERNAL "attr_external"
|
||||
#define ATTR_TIMESTAMP "attr_timestamp"
|
||||
#define ATTR_HIGHLIGHT "attr_highlight"
|
||||
#define ATTR_ACTION "attr_action"
|
||||
#define ATTR_JOIN "attr_join"
|
||||
#define ATTR_PART "attr_part"
|
||||
enum
|
||||
{
|
||||
#define XX(x, y, z) ATTR_ ## x,
|
||||
ATTR_TABLE (XX)
|
||||
#undef XX
|
||||
ATTR_COUNT
|
||||
};
|
||||
|
||||
static const char *g_attr_table[ATTR_COUNT] =
|
||||
{
|
||||
#define XX(x, y, z) [ATTR_ ## x] = "attr_" y,
|
||||
ATTR_TABLE (XX)
|
||||
#undef XX
|
||||
};
|
||||
|
||||
// User data for logger functions to enable formatted logging
|
||||
#define print_fatal_data ATTR_ERROR
|
||||
#define print_error_data ATTR_ERROR
|
||||
#define print_warning_data ATTR_WARNING
|
||||
#define print_fatal_data ((void *) ATTR_ERROR)
|
||||
#define print_error_data ((void *) ATTR_ERROR)
|
||||
#define print_warning_data ((void *) ATTR_WARNING)
|
||||
|
||||
#include "config.h"
|
||||
#undef PROGRAM_NAME
|
||||
|
@ -89,17 +103,9 @@ static struct config_item g_config_table[] =
|
|||
|
||||
{ "isolate_buffers", "off", "Isolate global/server buffers" },
|
||||
|
||||
{ ATTR_PROMPT, NULL, "Terminal attributes for the prompt" },
|
||||
{ ATTR_RESET, NULL, "String to reset terminal attributes" },
|
||||
{ ATTR_WARNING, NULL, "Terminal attributes for warnings" },
|
||||
{ ATTR_ERROR, NULL, "Terminal attributes for errors" },
|
||||
|
||||
{ ATTR_EXTERNAL, NULL, "Terminal attributes for external lines" },
|
||||
{ ATTR_TIMESTAMP, NULL, "Terminal attributes for timestamps" },
|
||||
{ ATTR_HIGHLIGHT, NULL, "Terminal attributes for highlights" },
|
||||
{ ATTR_ACTION, NULL, "Terminal attributes for user actions" },
|
||||
{ ATTR_JOIN, NULL, "Terminal attributes for joins" },
|
||||
{ ATTR_PART, NULL, "Terminal attributes for parts" },
|
||||
#define XX(x, y, z) { "attr_" y, NULL, z },
|
||||
ATTR_TABLE (XX)
|
||||
#undef XX
|
||||
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
@ -419,19 +425,12 @@ buffer_destroy (struct buffer *self)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
enum color_mode
|
||||
{
|
||||
COLOR_AUTO, ///< Autodetect if colours are available
|
||||
COLOR_ALWAYS, ///< Always use coloured output
|
||||
COLOR_NEVER ///< Never use coloured output
|
||||
};
|
||||
|
||||
struct app_context
|
||||
{
|
||||
// Configuration:
|
||||
|
||||
struct str_map config; ///< User configuration
|
||||
enum color_mode color_mode; ///< Colour output mode
|
||||
bool no_colors; ///< Colour output mode
|
||||
bool reconnect; ///< Whether to reconnect on conn. fail.
|
||||
unsigned long reconnect_delay; ///< Reconnect delay in seconds
|
||||
bool isolate_buffers; ///< Isolate global/server buffers
|
||||
|
@ -724,7 +723,7 @@ get_attribute_printer (FILE *stream)
|
|||
|
||||
static void
|
||||
vprint_attributed (struct app_context *ctx,
|
||||
FILE *stream, const char *attribute, const char *fmt, va_list ap)
|
||||
FILE *stream, intptr_t attribute, const char *fmt, va_list ap)
|
||||
{
|
||||
terminal_printer_fn printer = get_attribute_printer (stream);
|
||||
if (!attribute)
|
||||
|
@ -732,7 +731,8 @@ vprint_attributed (struct app_context *ctx,
|
|||
|
||||
if (printer)
|
||||
{
|
||||
const char *value = str_map_find (&ctx->config, attribute);
|
||||
const char *value = str_map_find
|
||||
(&ctx->config, g_attr_table[attribute]);
|
||||
tputs (value, 1, printer);
|
||||
}
|
||||
|
||||
|
@ -740,14 +740,15 @@ vprint_attributed (struct app_context *ctx,
|
|||
|
||||
if (printer)
|
||||
{
|
||||
const char *value = str_map_find (&ctx->config, ATTR_RESET);
|
||||
const char *value = str_map_find
|
||||
(&ctx->config, g_attr_table[ATTR_RESET]);
|
||||
tputs (value, 1, printer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_attributed (struct app_context *ctx,
|
||||
FILE *stream, const char *attribute, const char *fmt, ...)
|
||||
FILE *stream, intptr_t attribute, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
|
@ -765,8 +766,8 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt,
|
|||
if (g_ctx->readline_prompt_shown)
|
||||
app_readline_hide (&state);
|
||||
|
||||
print_attributed (g_ctx, stream, user_data, "%s", quote);
|
||||
vprint_attributed (g_ctx, stream, user_data, fmt, ap);
|
||||
print_attributed (g_ctx, stream, (intptr_t) user_data, "%s", quote);
|
||||
vprint_attributed (g_ctx, stream, (intptr_t) user_data, fmt, ap);
|
||||
fputs ("\n", stream);
|
||||
|
||||
if (g_ctx->readline_prompt_shown)
|
||||
|
@ -779,42 +780,33 @@ init_colors (struct app_context *ctx)
|
|||
bool have_ti = init_terminal ();
|
||||
|
||||
// Use escape sequences from terminfo if possible, and SGR as a fallback
|
||||
#define INIT_ATTR(id, ti, vt100) \
|
||||
str_map_set (&ctx->config, (id), xstrdup (have_ti ? (ti) : (vt100)));
|
||||
#define INIT_ATTR(id, ti) \
|
||||
str_map_set (&ctx->config, g_attr_table[id], xstrdup (have_ti ? (ti) : ""))
|
||||
|
||||
INIT_ATTR (ATTR_PROMPT, enter_bold_mode, "\x1b[1m");
|
||||
INIT_ATTR (ATTR_RESET, exit_attribute_mode, "\x1b[0m");
|
||||
INIT_ATTR (ATTR_WARNING, g_terminal.color_set_fg[3], "\x1b[33m");
|
||||
INIT_ATTR (ATTR_ERROR, g_terminal.color_set_fg[1], "\x1b[31m");
|
||||
INIT_ATTR (ATTR_PROMPT, enter_bold_mode);
|
||||
INIT_ATTR (ATTR_RESET, exit_attribute_mode);
|
||||
INIT_ATTR (ATTR_WARNING, g_terminal.color_set_fg[3]);
|
||||
INIT_ATTR (ATTR_ERROR, g_terminal.color_set_fg[1]);
|
||||
|
||||
INIT_ATTR (ATTR_EXTERNAL, g_terminal.color_set_fg[7], "\x1b[37m");
|
||||
INIT_ATTR (ATTR_TIMESTAMP, g_terminal.color_set_fg[7], "\x1b[37m");
|
||||
INIT_ATTR (ATTR_ACTION, g_terminal.color_set_fg[1], "\x1b[31m");
|
||||
INIT_ATTR (ATTR_JOIN, g_terminal.color_set_fg[2], "\x1b[32m");
|
||||
INIT_ATTR (ATTR_PART, g_terminal.color_set_fg[1], "\x1b[31m");
|
||||
INIT_ATTR (ATTR_EXTERNAL, g_terminal.color_set_fg[7]);
|
||||
INIT_ATTR (ATTR_TIMESTAMP, g_terminal.color_set_fg[7]);
|
||||
INIT_ATTR (ATTR_ACTION, g_terminal.color_set_fg[1]);
|
||||
INIT_ATTR (ATTR_JOIN, g_terminal.color_set_fg[2]);
|
||||
INIT_ATTR (ATTR_PART, g_terminal.color_set_fg[1]);
|
||||
|
||||
char *highlight = xstrdup_printf ("%s%s%s",
|
||||
g_terminal.color_set_fg[3],
|
||||
g_terminal.color_set_bg[5],
|
||||
enter_bold_mode);
|
||||
INIT_ATTR (ATTR_HIGHLIGHT, highlight, "\x1b[33;47;1m");
|
||||
INIT_ATTR (ATTR_HIGHLIGHT, highlight);
|
||||
free (highlight);
|
||||
|
||||
#undef INIT_ATTR
|
||||
|
||||
switch (ctx->color_mode)
|
||||
if (ctx->no_colors)
|
||||
{
|
||||
case COLOR_ALWAYS:
|
||||
g_terminal.stdout_is_tty = true;
|
||||
g_terminal.stderr_is_tty = true;
|
||||
break;
|
||||
case COLOR_AUTO:
|
||||
if (!g_terminal.initialized)
|
||||
{
|
||||
case COLOR_NEVER:
|
||||
g_terminal.stdout_is_tty = false;
|
||||
g_terminal.stderr_is_tty = false;
|
||||
}
|
||||
g_terminal.stdout_is_tty = false;
|
||||
g_terminal.stderr_is_tty = false;
|
||||
}
|
||||
|
||||
g_log_message_real = log_message_attributed;
|
||||
|
@ -985,14 +977,15 @@ formatter_add_reset (struct formatter *self)
|
|||
}
|
||||
|
||||
static void
|
||||
formatter_add_attr (struct formatter *self, const char *attr_name)
|
||||
formatter_add_attr (struct formatter *self, int attr_id)
|
||||
{
|
||||
if (self->ignore_new_attributes)
|
||||
return;
|
||||
|
||||
struct formatter_item *item = formatter_add_blank (self);
|
||||
item->type = FORMATTER_ITEM_ATTR;
|
||||
item->data = xstrdup (str_map_find (&self->ctx->config, attr_name));
|
||||
item->data = xstrdup (str_map_find
|
||||
(&self->ctx->config, g_attr_table[attr_id]));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1047,7 +1040,7 @@ restart:
|
|||
break;
|
||||
|
||||
case 'a':
|
||||
formatter_add_attr (self, va_arg (*ap, const char *));
|
||||
formatter_add_attr (self, va_arg (*ap, int));
|
||||
break;
|
||||
case 'c':
|
||||
formatter_add_fg_color (self, va_arg (*ap, int));
|
||||
|
@ -1117,7 +1110,8 @@ formatter_flush (struct formatter *self, FILE *stream)
|
|||
return;
|
||||
}
|
||||
|
||||
const char *attr_reset = str_map_find (&self->ctx->config, ATTR_RESET);
|
||||
const char *attr_reset = str_map_find
|
||||
(&self->ctx->config, g_attr_table[ATTR_RESET]);
|
||||
tputs (attr_reset, 1, printer);
|
||||
|
||||
bool is_attributed = false;
|
||||
|
@ -2148,8 +2142,10 @@ refresh_prompt (struct app_context *ctx)
|
|||
else
|
||||
{
|
||||
// XXX: to be completely correct, we should use tputs, but we cannot
|
||||
const char *prompt_attrs = str_map_find (&ctx->config, ATTR_PROMPT);
|
||||
const char *reset_attrs = str_map_find (&ctx->config, ATTR_RESET);
|
||||
const char *prompt_attrs = str_map_find
|
||||
(&ctx->config, g_attr_table[ATTR_PROMPT]);
|
||||
const char *reset_attrs = str_map_find
|
||||
(&ctx->config, g_attr_table[ATTR_RESET]);
|
||||
ctx->readline_prompt = xstrdup_printf ("%c%s%c%s%c%s%c",
|
||||
RL_PROMPT_START_IGNORE, prompt_attrs, RL_PROMPT_END_IGNORE,
|
||||
prompt.str,
|
||||
|
@ -4553,6 +4549,7 @@ main (int argc, char *argv[])
|
|||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// FIXME: this overwrites all custom attribute settings
|
||||
init_colors (&ctx);
|
||||
init_poller_events (&ctx);
|
||||
init_buffers (&ctx);
|
||||
|
|
Loading…
Reference in New Issue