improve colors and styles

* improve curline_style handling
* add completion for variable values
This commit is contained in:
Charlie Gordon 2026-06-04 09:51:43 +02:00
commit 7e2e2b5e7f
7 changed files with 78 additions and 28 deletions

View file

@ -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 */

View file

@ -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;

17
qe.c
View file

@ -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

2
qe.h
View file

@ -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);

View file

@ -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:

View file

@ -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;
}

View file

@ -28,6 +28,7 @@
typedef enum QVarType {
VAR_UNKNOWN = 0,
VAR_NUMBER,
VAR_STYLE,
VAR_STRING,
VAR_CHARS,
VAR_READONLY,