From 7e2e2b5e7fa2739e8a4af76385ed1f8701bb6875 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Thu, 4 Jun 2026 09:51:43 +0200 Subject: [PATCH] improve colors and styles * improve curline_style handling * add completion for variable values --- color.h | 6 ++--- extras.c | 2 +- qe.c | 17 +++++++----- qe.h | 2 ++ qescript.c | 1 + variables.c | 77 ++++++++++++++++++++++++++++++++++++++++------------- variables.h | 1 + 7 files changed, 78 insertions(+), 28 deletions(-) diff --git a/color.h b/color.h index 7271729..5b601f1 100644 --- a/color.h +++ b/color.h @@ -68,11 +68,11 @@ typedef uint32_t QEColor; * to trace the display unit on the device surface */ -/* Style numbers are limited to 8 bits, the default set has 27 entries */ +/* Style numbers are limited to 8 bits, the default set has 30 entries */ /* Composite styles are 32-bit values that specify * - a style number - * - display attributes for underline, bold, blink - * - text and background colors as either palette numbers or 4096 rgb values + * - display attributes for underline, bold, italics, blink + * - text and background colors as either palette numbers or 8k rgb values */ #if 0 /* 25-bit color for FG and BG */ diff --git a/extras.c b/extras.c index f6ff14c..4f687fa 100644 --- a/extras.c +++ b/extras.c @@ -1578,7 +1578,7 @@ static int str_get_word7(char *buf, int size, const char *p, const char **pp) return len; } -static int qe_term_get_style(const char *str, QETermStyle *style) +int qe_term_get_style(const char *str, QETermStyle *style) { char buf[128]; QEColor fg_color, bg_color; diff --git a/qe.c b/qe.c index a1c3091..2052470 100644 --- a/qe.c +++ b/qe.c @@ -704,7 +704,7 @@ void do_cd(EditState *s, const char *path) } } -static void color_complete(CompleteState *cp, CompleteFunc enumerate) { +void color_complete(CompleteState *cp, CompleteFunc enumerate) { const char *name = cp->current; char buf[32]; int i, len; @@ -4095,9 +4095,11 @@ static void flush_line(DisplayState *ds, } x = ds->x_line; x1 = ds->width + ds->eol_width; + // XXX: handle curline_style and other line styles for (i = 0; i < nb_fragments && x < x1; i++) { frag = &fragments[i]; get_style(e, &styledef, frag->style); + // XXX: should not fill if transparent fill_rectangle(screen, e->xleft + x, e->ytop + y, frag->width, line_height, styledef.bg_color); x += frag->width; @@ -5090,11 +5092,14 @@ int text_display_line(EditState *s, DisplayState *ds, int offset) } } } else - if (s->curline_style && s->offset >= offset && s->offset <= offset0) { - /* XXX: only if qs->active_window == s ? */ - int i; - for (i = 0; i < colored_nb_chars; i++) - cp->sbuf[i] = s->curline_style; + if (s->curline_style && s->offset >= offset) { + if (s->offset < offset0 || offset == offset0 + || (offset0 == s->b->total_size && eb_peek_prevc(s->b, offset0) != '\n')) { + /* XXX: only if qs->active_window == s ? */ + int i; + for (i = 0; i < colored_nb_chars; i++) + cp->sbuf[i] = s->curline_style; + } } } #endif diff --git a/qe.h b/qe.h index 101773a..d929041 100644 --- a/qe.h +++ b/qe.h @@ -1576,6 +1576,7 @@ extern ModeDef text_mode; int text_backward_offset(EditState *s, int offset); int text_display_line(EditState *s, DisplayState *ds, int offset); +void color_complete(CompleteState *cp, CompleteFunc enumerate); void set_colorize_mode(EditState *s, ModeDef *mode); int get_colorized_line(QEColorizeContext *cp, int offset, int *offsetp, int line_num); @@ -1863,6 +1864,7 @@ void do_show_bindings(EditState *s, const char *cmd_name); void do_describe_bindings(EditState *s, int argval); void do_apropos(EditState *s, const char *str); +int qe_term_get_style(const char *str, QETermStyle *style); int color_print_entry(CompleteState *cp, EditState *s, const char *name); int style_print_entry(CompleteState *cp, EditState *s, const char *name); diff --git a/qescript.c b/qescript.c index 1067704..49539ca 100644 --- a/qescript.c +++ b/qescript.c @@ -475,6 +475,7 @@ static int qe_cfg_getvalue(QEmacsDataSource *ds, QEValue *sp) { qe_cfg_set_str(sp, buf, strlen(buf)); break; case VAR_NUMBER: + case VAR_STYLE: qe_cfg_set_num(sp, num); break; default: diff --git a/variables.c b/variables.c index bd78c14..f4142bd 100644 --- a/variables.c +++ b/variables.c @@ -29,6 +29,8 @@ static QVarType qe_variable_set_value_offset(EditState *s, VarDef *vp, void *ptr const char *value, int num); static QVarType qe_variable_set_value_generic(EditState *s, VarDef *vp, void *ptr, const char *value, int num); +static QVarType qe_variable_set_value_style(EditState *s, VarDef *vp, void *ptr, + const char *value, int num); const char * const var_domain[] = { "global", /* VAR_GLOBAL */ @@ -115,11 +117,11 @@ static VarDef var_table[] = { "Number of columns to indent by for a syntactic level." ) W_VAR( "indent-tabs-mode", indent_tabs_mode, VAR_NUMBER, VAR_RW, "Set if indentation can insert tabs." ) - W_VAR( "default-style", default_style, VAR_NUMBER, VAR_RW, // XXX: need set_value function + W_VAR_F( "default-style", default_style, VAR_STYLE, VAR_RW, qe_variable_set_value_style, "Default text style for this window." ) - W_VAR( "region-style", region_style, VAR_NUMBER, VAR_RW, // XXX: need set_value function + W_VAR_F( "region-style", region_style, VAR_STYLE, VAR_RW, qe_variable_set_value_style, "Text style for the current region in this window." ) - W_VAR( "curline-style", curline_style, VAR_NUMBER, VAR_RW, // XXX: need set_value function + W_VAR_F( "curline-style", curline_style, VAR_STYLE, VAR_RW, qe_variable_set_value_style, "Text style for the current line in this window." ) W_VAR( "window-width", width, VAR_NUMBER, VAR_RW, // XXX: need set_value function "Number of display columns in this window." ) @@ -262,6 +264,7 @@ QVarType qe_get_variable(EditState *s, const char *name, pstrcpy(buf, size, str); break; case VAR_NUMBER: + case VAR_STYLE: memcpy(&num, ptr, sizeof(num)); if (pnum) *pnum = num; @@ -289,6 +292,20 @@ static QVarType qe_variable_set_value_offset(EditState *s, VarDef *vp, void *ptr } } +static QVarType qe_variable_set_value_style(EditState *s, VarDef *vp, void *ptr, + const char *value, int num) +{ + QETermStyle style = num; + if (value && qe_term_get_style(value, &style)) { + const char *p; + style = strtol_c(value, &p, 0); + if (*p) + return VAR_INVALID; + } + memcpy(ptr, &style, sizeof(style)); + return VAR_STYLE; +} + static QVarType qe_variable_set_value_generic(EditState *s, VarDef *vp, void *ptr, const char *value, int num) { @@ -322,15 +339,19 @@ static QVarType qe_variable_set_value_generic(EditState *s, VarDef *vp, void *pt } break; case VAR_NUMBER: - if (!value) { - pnum = (int *)ptr; - if (*pnum != num) { - *pnum = num; - vp->modified = 1; + case VAR_STYLE: + /* XXX: should have default, min and max values? */ + if (value) { + const char *p; + num = strtol_c(value, &p, 0); + if (*p) { + return VAR_INVALID; } - } else { - /* XXX: should have default, min and max values */ - return VAR_INVALID; + } + pnum = (int *)ptr; + if (*pnum != num) { + *pnum = num; + vp->modified = 1; } break; default: @@ -391,12 +412,6 @@ QVarType qe_set_variable(EditState *s, const char *name, default: return VAR_UNKNOWN; } - if (vp->type == VAR_NUMBER && value) { - const char *p; - num = strtol_c(value, &p, 0); - if (!*p) - value = NULL; - } return vp->set_value(s, vp, ptr, value, num); } } @@ -481,6 +496,9 @@ void qe_list_variables(EditState *s, EditBuffer *b) case VAR_NUMBER: type = "int"; break; + case VAR_STYLE: + type = "style"; + break; case VAR_STRING: type = "string"; break; @@ -536,6 +554,9 @@ int eb_variable_print_entry(EditBuffer *b, VarDef *vp, EditState *s) { case VAR_NUMBER: type = "int"; break; + case VAR_STYLE: + type = "style"; + break; case VAR_STRING: type = "string"; break; @@ -588,6 +609,25 @@ static CompletionDef variable_completion = { .print_entry = variable_print_entry, }; +static void value_complete(CompleteState *cp, CompleteFunc enumerate) { + style_complete(cp, enumerate); + color_complete(cp, enumerate); +} + +static int value_print_entry(CompleteState *cp, EditState *s, const char *name) { + if (find_style(name)) + return style_print_entry(cp, s, name); + else + return color_print_entry(cp, s, name); +} + +static CompletionDef value_completion = { + .name = "value", + .enumerate = value_complete, + .print_entry = value_print_entry, + .flags = CF_SPACE_OK, +}; + /*---------------- commands ----------------*/ static const CmdDef var_commands[] = { @@ -598,7 +638,7 @@ static const CmdDef var_commands[] = { CMD2( "set-variable", "f8", "Set the value of a variable", do_set_variable, ESss, - "s{Set variable: }[variable]|variable|s{to value: }|value|") + "s{Set variable: }[variable]|variable|s{to value: }[value]|value|") CMD2( "describe-variable", "C-h v", "Show information for a variable", do_describe_variable, ESs, @@ -609,6 +649,7 @@ static int variables_init(QEmacsState *qs) { qe_register_variables(qs, var_table, countof(var_table)); qe_register_commands(qs, NULL, var_commands, countof(var_commands)); qe_register_completion(qs, &variable_completion); + qe_register_completion(qs, &value_completion); return 0; } diff --git a/variables.h b/variables.h index 0ff0e93..b1e0e4c 100644 --- a/variables.h +++ b/variables.h @@ -28,6 +28,7 @@ typedef enum QVarType { VAR_UNKNOWN = 0, VAR_NUMBER, + VAR_STYLE, VAR_STRING, VAR_CHARS, VAR_READONLY,