add generic styles buffer from shell color mode
* styles_buffer hold static style info for each character in the buffer * new buffer flags to create styles buffers with 1, 2 or 4 bytes per char * copy static styles to the kill_ring and pasted them style enabled buffers * preserve static styles in convert-buffer-file-coding-system * display style bytes in bufed list * add commands set-region-color, set-region-style, drop-styles
This commit is contained in:
parent
51477bbc8b
commit
02da1bb7a1
10 changed files with 361 additions and 136 deletions
5
bufed.c
5
bufed.c
|
|
@ -86,8 +86,9 @@ static void build_bufed_list(EditState *s)
|
|||
}
|
||||
}
|
||||
|
||||
eb_printf(b, " %10d %-8s %-8s %s",
|
||||
b1->total_size, b1->charset->name, mode_name,
|
||||
eb_printf(b, " %10d %c %-8s %-8s %s",
|
||||
b1->total_size, " 1234567"[b1->style_bytes & 7],
|
||||
b1->charset->name, mode_name,
|
||||
make_user_path(path, sizeof(path), b1->filename));
|
||||
}
|
||||
eb_printf(b, "\n");
|
||||
|
|
|
|||
126
buffer.c
126
buffer.c
|
|
@ -475,7 +475,7 @@ EditBuffer *eb_new(const char *name, int flags)
|
|||
|
||||
// should ensure name uniqueness ?
|
||||
pstrcpy(b->name, sizeof(b->name), name);
|
||||
b->flags = flags;
|
||||
b->flags = flags & ~BF_STYLES;
|
||||
|
||||
/* set default data type */
|
||||
b->data_type = &raw_data_type;
|
||||
|
|
@ -509,6 +509,9 @@ EditBuffer *eb_new(const char *name, int flags)
|
|||
if (strequal(name, "*trace*"))
|
||||
qs->trace_buffer = b;
|
||||
|
||||
if (flags & BF_STYLES)
|
||||
eb_create_style_buffer(b, flags);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
|
@ -581,6 +584,8 @@ void eb_free(EditBuffer *b)
|
|||
if (b == qs->trace_buffer)
|
||||
qs->trace_buffer = NULL;
|
||||
|
||||
eb_free_style_buffer(b);
|
||||
|
||||
qe_free(&b);
|
||||
}
|
||||
|
||||
|
|
@ -754,6 +759,82 @@ void eb_offset_callback(__unused__ EditBuffer *b, void *opaque, int edge,
|
|||
}
|
||||
}
|
||||
|
||||
int eb_create_style_buffer(EditBuffer *b, int flags)
|
||||
{
|
||||
if (b->b_styles) {
|
||||
return 0;
|
||||
} else {
|
||||
b->b_styles = eb_new("*", BF_SYSTEM);
|
||||
b->flags |= flags & BF_STYLES;
|
||||
b->style_shift = ((flags & BF_STYLES) / BF_STYLE1) - 1;
|
||||
b->style_bytes = 1 << b->style_shift;
|
||||
eb_set_style(b, 0, LOGOP_INSERT, 0, b->total_size);
|
||||
eb_add_callback(b, eb_style_callback, NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void eb_free_style_buffer(EditBuffer *b)
|
||||
{
|
||||
if (b->b_styles) {
|
||||
eb_free(b->b_styles);
|
||||
b->b_styles = NULL;
|
||||
}
|
||||
b->style_shift = b->style_bytes = 0;
|
||||
eb_free_callback(b, eb_style_callback, NULL);
|
||||
}
|
||||
|
||||
/* XXX: should compress styles buffer with run length encoding */
|
||||
void eb_set_style(EditBuffer *b, int style, enum LogOperation op,
|
||||
int offset, int size)
|
||||
{
|
||||
unsigned char buf[256];
|
||||
int i, len;
|
||||
|
||||
if (!b->b_styles || !size)
|
||||
return;
|
||||
|
||||
offset = (offset >> b->char_shift) << b->style_shift;
|
||||
size = (size >> b->char_shift) << b->style_shift;
|
||||
|
||||
switch (op) {
|
||||
case LOGOP_WRITE:
|
||||
case LOGOP_INSERT:
|
||||
while (size > 0) {
|
||||
len = min(size, ssizeof(buf));
|
||||
if (b->style_shift == 2) {
|
||||
for (i = 0; i < len; i += 4) {
|
||||
*(uint32_t*)(buf + i) = style;
|
||||
}
|
||||
} else
|
||||
if (b->style_shift == 1) {
|
||||
for (i = 0; i < len; i += 2) {
|
||||
*(uint16_t*)(buf + i) = style;
|
||||
}
|
||||
} else {
|
||||
memset(buf, style, len);
|
||||
}
|
||||
if (op == LOGOP_WRITE)
|
||||
eb_write(b->b_styles, offset, buf, len);
|
||||
else
|
||||
eb_insert(b->b_styles, offset, buf, len);
|
||||
size -= len;
|
||||
offset += len;
|
||||
}
|
||||
break;
|
||||
case LOGOP_DELETE:
|
||||
eb_delete(b->b_styles, offset, size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void eb_style_callback(EditBuffer *b, void *opaque, int arg,
|
||||
enum LogOperation op, int offset, int size)
|
||||
{
|
||||
eb_set_style(b, b->cur_style, op, offset, size);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************/
|
||||
|
|
@ -1031,6 +1112,16 @@ void eb_set_charset(EditBuffer *b, QECharset *charset)
|
|||
b->flags |= BF_UTF8;
|
||||
charset_decode_init(&b->charset_state, charset);
|
||||
|
||||
b->char_bytes = 1;
|
||||
b->char_shift = 0;
|
||||
if (charset) {
|
||||
b->char_bytes = charset->char_size;
|
||||
if (charset->char_size == 4)
|
||||
b->char_shift = 2;
|
||||
else
|
||||
b->char_shift = charset->char_size - 1;
|
||||
}
|
||||
|
||||
/* Reset page cache flags */
|
||||
for (n = 0; n < b->nb_pages; n++) {
|
||||
Page *p = &b->page_table[n];
|
||||
|
|
@ -1044,6 +1135,22 @@ int eb_nextc(EditBuffer *b, int offset, int *next_ptr)
|
|||
u8 buf[MAX_CHAR_BYTES];
|
||||
int ch;
|
||||
|
||||
if (b->b_styles) {
|
||||
if (b->style_shift == 2) {
|
||||
*(uint32_t*)buf = 0;
|
||||
eb_read(b->b_styles, (offset >> b->char_shift) << 2, buf, 4);
|
||||
b->cur_style = *(uint32_t*)buf;
|
||||
} else
|
||||
if (b->style_shift == 1) {
|
||||
*(uint16_t*)buf = 0;
|
||||
eb_read(b->b_styles, (offset >> b->char_shift) << 1, buf, 2);
|
||||
b->cur_style = *(uint16_t*)buf;
|
||||
} else {
|
||||
*(uint8_t*)buf = 0;
|
||||
eb_read(b->b_styles, (offset >> b->char_shift), buf, 1);
|
||||
b->cur_style = *(uint8_t*)buf;
|
||||
}
|
||||
}
|
||||
if (eb_read(b, offset, buf, 1) <= 0) {
|
||||
ch = '\n';
|
||||
if (offset < 0)
|
||||
|
|
@ -1758,16 +1865,20 @@ int eb_insert_buffer_convert(EditBuffer *dest, int dest_offset,
|
|||
EditBuffer *src, int src_offset,
|
||||
int size)
|
||||
{
|
||||
if (dest->charset == src->charset) {
|
||||
int styles_flags = min((dest->flags & BF_STYLES), (src->flags & BF_STYLES));
|
||||
|
||||
if (dest->charset == src->charset && !styles_flags) {
|
||||
return eb_insert_buffer(dest, dest_offset, src, src_offset, size);
|
||||
} else {
|
||||
EditBuffer *b;
|
||||
int offset, offset_max;
|
||||
int offset, offset_max, offset1 = dest_offset;
|
||||
|
||||
b = dest;
|
||||
if ((b->flags & BF_SAVELOG) || dest_offset != b->total_size) {
|
||||
b = eb_new("*tmp*", 0);
|
||||
if (!styles_flags
|
||||
&& ((b->flags & BF_SAVELOG) || dest_offset != b->total_size)) {
|
||||
b = eb_new("*tmp*", BF_SYSTEM);
|
||||
eb_set_charset(b, dest->charset);
|
||||
offset1 = 0;
|
||||
}
|
||||
|
||||
/* well, not very fast, but simple */
|
||||
|
|
@ -1778,7 +1889,8 @@ int eb_insert_buffer_convert(EditBuffer *dest, int dest_offset,
|
|||
char buf[MAX_CHAR_BYTES];
|
||||
int c = eb_nextc(src, offset, &offset);
|
||||
int len = unicode_to_charset(buf, c, b->charset);
|
||||
eb_write(b, b->total_size, buf, len);
|
||||
b->cur_style = src->cur_style;
|
||||
eb_insert(b, offset1 + size, buf, len);
|
||||
size += len;
|
||||
}
|
||||
|
||||
|
|
@ -1810,7 +1922,7 @@ int eb_get_line(EditBuffer *b, unsigned int *buf, int buf_size,
|
|||
if (c == '\n')
|
||||
break;
|
||||
if (buf_ptr < buf_end)
|
||||
*buf_ptr++ = c;
|
||||
*buf_ptr++ = c & CHAR_MASK;
|
||||
}
|
||||
*buf_ptr = '\0';
|
||||
*offset_ptr = offset;
|
||||
|
|
|
|||
|
|
@ -24,12 +24,6 @@
|
|||
#define MAX_SCREEN_WIDTH 1024 /* in chars */
|
||||
#define MAX_SCREEN_LINES 256 /* in text lines */
|
||||
|
||||
typedef unsigned int QEColor;
|
||||
#define QEARGB(a,r,g,b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
|
||||
#define QERGB(r,g,b) QEARGB(0xff, r, g, b)
|
||||
#define COLOR_TRANSPARENT 0
|
||||
#define QECOLOR_XOR 1
|
||||
|
||||
/* XXX: use different name prefix to avoid conflict */
|
||||
#define QE_STYLE_NORM 0x0001
|
||||
#define QE_STYLE_BOLD 0x0002
|
||||
|
|
|
|||
69
extras.c
69
extras.c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* QEmacs, extra commands non full version
|
||||
*
|
||||
* Copyright (c) 2000-2008 Charlie Gordon.
|
||||
* Copyright (c) 2000-2014 Charlie Gordon.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -575,6 +575,64 @@ static void do_about_qemacs(EditState *s)
|
|||
show_popup(b);
|
||||
}
|
||||
|
||||
static void do_set_region_color(EditState *s, const char *str)
|
||||
{
|
||||
int offset, size, style;
|
||||
|
||||
/* deactivate region hilite */
|
||||
s->region_style = 0;
|
||||
|
||||
style = get_tty_style(str);
|
||||
if (style < 0) {
|
||||
put_status(s, "Invalid color '%s'", str);
|
||||
return;
|
||||
}
|
||||
|
||||
offset = s->b->mark;
|
||||
size = s->offset - offset;
|
||||
if (size < 0) {
|
||||
offset += size;
|
||||
size = -size;
|
||||
}
|
||||
if (size > 0) {
|
||||
eb_create_style_buffer(s->b, BF_STYLE2);
|
||||
eb_set_style(s->b, style, LOGOP_WRITE, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_set_region_style(EditState *s, const char *str)
|
||||
{
|
||||
int offset, size, style;
|
||||
QEStyleDef *st;
|
||||
|
||||
/* deactivate region hilite */
|
||||
s->region_style = 0;
|
||||
|
||||
st = find_style(str);
|
||||
if (!st) {
|
||||
put_status(s, "Invalid style '%s'", str);
|
||||
return;
|
||||
}
|
||||
style = st - qe_styles;
|
||||
|
||||
offset = s->b->mark;
|
||||
size = s->offset - offset;
|
||||
if (size < 0) {
|
||||
offset += size;
|
||||
size = -size;
|
||||
}
|
||||
if (size > 0) {
|
||||
eb_create_style_buffer(s->b, BF_STYLE2);
|
||||
eb_set_style(s->b, style, LOGOP_WRITE, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_drop_styles(EditState *s)
|
||||
{
|
||||
eb_free_style_buffer(s->b);
|
||||
s->b->flags &= ~BF_STYLES;
|
||||
}
|
||||
|
||||
static CmdDef extra_commands[] = {
|
||||
CMD2( KEY_META('='), KEY_NONE,
|
||||
"compare-windows", do_compare_windows, ESi, "ui" )
|
||||
|
|
@ -622,6 +680,15 @@ static CmdDef extra_commands[] = {
|
|||
"show-bindings", do_show_bindings, ESs,
|
||||
"s{Show bindings of command: }[command]|command|")
|
||||
|
||||
CMD2( KEY_CTRLC('c'), KEY_NONE,
|
||||
"set-region-color", do_set_region_color, ESs,
|
||||
"s{Select color: }[color]|color|")
|
||||
CMD2( KEY_CTRLC('s'), KEY_NONE,
|
||||
"set-region-style", do_set_region_style, ESs,
|
||||
"s{Select style: }[style]|style|")
|
||||
CMD0( KEY_NONE, KEY_NONE,
|
||||
"drop-styles", do_drop_styles)
|
||||
|
||||
CMD_DEF_END,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -672,13 +672,13 @@ static void do_org_move_subtree(EditState *s, int dir)
|
|||
}
|
||||
offset2 = org_next_heading(s, offset1, level, &level2);
|
||||
}
|
||||
b1 = eb_new("*tmp*", 0);
|
||||
b1 = eb_new("*tmp*", BF_SYSTEM | (s->b->flags & BF_STYLES));
|
||||
eb_set_charset(b1, s->b->charset);
|
||||
eb_insert_buffer(b1, 0, s->b, offset, size);
|
||||
eb_insert_buffer_convert(b1, 0, s->b, offset, size);
|
||||
eb_delete(s->b, offset, size);
|
||||
if (offset2 > offset)
|
||||
offset2 -= size;
|
||||
eb_insert_buffer(s->b, offset2, b1, 0, size);
|
||||
eb_insert_buffer_convert(s->b, offset2, b1, 0, b1->total_size);
|
||||
eb_free(b1);
|
||||
s->offset = offset2;
|
||||
}
|
||||
|
|
|
|||
62
qe.c
62
qe.c
|
|
@ -1445,7 +1445,7 @@ EditBuffer *new_yank_buffer(QEmacsState *qs, EditBuffer *base)
|
|||
}
|
||||
}
|
||||
snprintf(bufname, sizeof(bufname), "*kill-%d*", qs->yank_current + 1);
|
||||
b = eb_new(bufname, base->flags & BF_UTF8);
|
||||
b = eb_new(bufname, base->flags & (BF_STYLES | BF_UTF8));
|
||||
eb_set_charset(b, base->charset);
|
||||
qs->yank_buffers[qs->yank_current] = b;
|
||||
return b;
|
||||
|
|
@ -1824,7 +1824,7 @@ void do_convert_buffer_file_coding_system(EditState *s,
|
|||
|
||||
b = s->b;
|
||||
|
||||
b1 = eb_new("*tmp*", 0);
|
||||
b1 = eb_new("*tmp*", b->flags & BF_STYLES);
|
||||
eb_set_charset(b1, charset);
|
||||
|
||||
/* preserve positions */
|
||||
|
|
@ -1840,13 +1840,19 @@ void do_convert_buffer_file_coding_system(EditState *s,
|
|||
for (offset = 0; offset < b->total_size;) {
|
||||
c = eb_nextc(b, offset, &offset);
|
||||
len = unicode_to_charset(buf, c, charset);
|
||||
b1->cur_style = b->cur_style;
|
||||
eb_write(b1, b1->total_size, buf, len);
|
||||
}
|
||||
|
||||
/* replace current buffer with conversion */
|
||||
/* quick hack to transfer styles from tmp buffer to b */
|
||||
eb_free(b->b_styles);
|
||||
b->b_styles = NULL;
|
||||
eb_delete(b, 0, b->total_size);
|
||||
eb_set_charset(b, charset);
|
||||
eb_insert_buffer(b, 0, b1, 0, b1->total_size);
|
||||
b->b_styles = b1->b_styles;
|
||||
b1->b_styles = NULL;
|
||||
|
||||
/* restore positions */
|
||||
cb = b->first_callback;
|
||||
|
|
@ -3232,14 +3238,42 @@ void set_colorize_func(EditState *s, ColorizeFunc colorize_func)
|
|||
|
||||
#endif /* CONFIG_TINY */
|
||||
|
||||
int get_staticly_colorized_line(EditState *s, unsigned int *buf, int buf_size,
|
||||
int *offset_ptr, int line_num)
|
||||
{
|
||||
EditBuffer *b = s->b;
|
||||
unsigned int *buf_ptr, *buf_end;
|
||||
int c, offset;
|
||||
|
||||
offset = *offset_ptr;
|
||||
|
||||
buf_ptr = buf;
|
||||
buf_end = buf + buf_size - 1;
|
||||
b->cur_style = 0;
|
||||
for (;;) {
|
||||
c = eb_nextc(b, offset, &offset);
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (buf_ptr < buf_end) {
|
||||
c |= b->cur_style << STYLE_SHIFT;
|
||||
*buf_ptr++ = c;
|
||||
}
|
||||
}
|
||||
*buf_ptr = '\0';
|
||||
*offset_ptr = offset;
|
||||
return buf_ptr - buf;
|
||||
}
|
||||
|
||||
int get_non_colorized_line(EditState *s, unsigned int *buf, int buf_size,
|
||||
int *offsetp, int line_num)
|
||||
{
|
||||
/* compute line color */
|
||||
if (s->b->b_styles) {
|
||||
return get_staticly_colorized_line(s, buf, buf_size, offsetp, line_num);
|
||||
}
|
||||
|
||||
int len = eb_get_line(s->b, buf, buf_size, offsetp);
|
||||
// XXX: should force \0 instead of \n
|
||||
buf[len] = '\n';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -3256,7 +3290,8 @@ int text_display(EditState *s, DisplayState *ds, int offset)
|
|||
unsigned int colored_chars[COLORED_MAX_LINE_SIZE];
|
||||
int char_index, colored_nb_chars;
|
||||
|
||||
line_num = 0; /* avoid warning */
|
||||
line_num = 0;
|
||||
/* XXX: should test a flag, to avoid this call in hex/binary */
|
||||
if (s->line_numbers || s->get_colorized_line != get_non_colorized_line) {
|
||||
eb_get_pos(s->b, &line_num, &col_num, offset);
|
||||
}
|
||||
|
|
@ -3305,7 +3340,9 @@ int text_display(EditState *s, DisplayState *ds, int offset)
|
|||
/* colorize */
|
||||
colored_nb_chars = 0;
|
||||
offset0 = offset;
|
||||
if (s->get_colorized_line != get_non_colorized_line) {
|
||||
if (s->get_colorized_line != get_non_colorized_line
|
||||
|| s->curline_style || s->region_style
|
||||
|| s->b->b_styles) {
|
||||
colored_nb_chars = s->get_colorized_line(s, colored_chars,
|
||||
countof(colored_chars),
|
||||
&offset0, line_num);
|
||||
|
|
@ -3314,11 +3351,6 @@ int text_display(EditState *s, DisplayState *ds, int offset)
|
|||
#if 1
|
||||
/* colorize regions */
|
||||
if (s->curline_style || s->region_style) {
|
||||
if (s->get_colorized_line == get_non_colorized_line) {
|
||||
offset0 = offset;
|
||||
colored_nb_chars = eb_get_line(s->b, colored_chars,
|
||||
countof(colored_chars), &offset0);
|
||||
}
|
||||
/* CG: Should combine styles instead of replacing */
|
||||
if (s->region_style) {
|
||||
int line, start, stop;
|
||||
|
|
@ -4533,6 +4565,9 @@ void switch_to_buffer(EditState *s, EditBuffer *b)
|
|||
ModeSavedData *saved_data, **psaved_data;
|
||||
ModeDef *mode;
|
||||
|
||||
/* remove region hilite */
|
||||
s->region_style = 0;
|
||||
|
||||
b1 = s->b;
|
||||
if (b1) {
|
||||
/* save mode data if no other window uses the buffer */
|
||||
|
|
@ -4870,6 +4905,8 @@ void do_completion(EditState *s)
|
|||
* through the window, if at end, should remove focus from
|
||||
* completion_popup_window or close it.
|
||||
*/
|
||||
/* check completion window */
|
||||
completion_popup_window = check_window(completion_popup_window);
|
||||
if (completion_popup_window && qs->last_cmd_func == qs->this_cmd_func) {
|
||||
edit_close(completion_popup_window);
|
||||
completion_popup_window = NULL;
|
||||
|
|
@ -4952,7 +4989,7 @@ void do_completion(EditState *s)
|
|||
e->offset = 0;
|
||||
}
|
||||
}
|
||||
complete_end(&cs);
|
||||
complete_end(&cs);
|
||||
}
|
||||
|
||||
void do_electric_filename(EditState *s, int key)
|
||||
|
|
@ -5107,6 +5144,7 @@ void do_minibuffer_exit(EditState *s, int do_abort)
|
|||
|
||||
/* restore active window */
|
||||
qs->active_window = check_window(minibuffer_saved_active);
|
||||
minibuffer_saved_active = NULL;
|
||||
|
||||
/* force status update */
|
||||
//pstrcpy(qs->status_shadow, sizeof(qs->status_shadow), " ");
|
||||
|
|
|
|||
26
qe.h
26
qe.h
|
|
@ -193,6 +193,12 @@ typedef struct CSSRect {
|
|||
int x1, y1, x2, y2;
|
||||
} CSSRect;
|
||||
|
||||
typedef unsigned int QEColor;
|
||||
#define QEARGB(a,r,g,b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
|
||||
#define QERGB(r,g,b) QEARGB(0xff, r, g, b)
|
||||
#define COLOR_TRANSPARENT 0
|
||||
#define QECOLOR_XOR 1
|
||||
|
||||
typedef struct FindFileState FindFileState;
|
||||
|
||||
FindFileState *find_file_open(const char *path, const char *pattern);
|
||||
|
|
@ -302,7 +308,7 @@ const char *keys_to_str(char *buf, int buf_size,
|
|||
int to_hex(int key);
|
||||
void color_completion(CompleteState *cp);
|
||||
int css_define_color(const char *name, const char *value);
|
||||
int css_get_color(unsigned int *color_ptr, const char *p);
|
||||
int css_get_color(QEColor *color_ptr, const char *p);
|
||||
int css_get_font_family(const char *str);
|
||||
void css_union_rect(CSSRect *a, const CSSRect *b);
|
||||
static inline int css_is_null_rect(const CSSRect *a) {
|
||||
|
|
@ -712,6 +718,10 @@ typedef struct EditBufferCallbackList {
|
|||
#define BF_UTF8 0x0200 /* buffer charset is utf-8 */
|
||||
#define BF_RAW 0x0400 /* buffer charset is raw (same as latin1) */
|
||||
#define BF_TRANSIENT 0x0800 /* buffer is deleted upon window close */
|
||||
#define BF_STYLES 0x3000 /* buffer has styles */
|
||||
#define BF_STYLE1 0x1000 /* buffer has 1 byte styles */
|
||||
#define BF_STYLE2 0x2000 /* buffer has 2 byte styles */
|
||||
#define BF_STYLE4 0x3000 /* buffer has 4 byte styles */
|
||||
|
||||
struct EditBuffer {
|
||||
Page *page_table;
|
||||
|
|
@ -734,6 +744,7 @@ struct EditBuffer {
|
|||
/* charset handling */
|
||||
CharsetDecodeState charset_state;
|
||||
QECharset *charset;
|
||||
int char_bytes, char_shift;
|
||||
|
||||
/* undo system */
|
||||
int save_log; /* if true, each buffer operation is logged */
|
||||
|
|
@ -743,6 +754,12 @@ struct EditBuffer {
|
|||
EditBuffer *log_buffer;
|
||||
int nb_logs;
|
||||
|
||||
/* style system */
|
||||
EditBuffer *b_styles;
|
||||
int cur_style;
|
||||
int style_bytes;
|
||||
int style_shift;
|
||||
|
||||
/* modification callbacks */
|
||||
EditBufferCallbackList *first_callback;
|
||||
|
||||
|
|
@ -846,6 +863,12 @@ int eb_add_callback(EditBuffer *b, EditBufferCallback cb, void *opaque, int arg)
|
|||
void eb_free_callback(EditBuffer *b, EditBufferCallback cb, void *opaque);
|
||||
void eb_offset_callback(EditBuffer *b, void *opaque, int edge,
|
||||
enum LogOperation op, int offset, int size);
|
||||
int eb_create_style_buffer(EditBuffer *b, int flags);
|
||||
void eb_free_style_buffer(EditBuffer *b);
|
||||
void eb_set_style(EditBuffer *b, int style, enum LogOperation op,
|
||||
int offset, int size);
|
||||
void eb_style_callback(EditBuffer *b, void *opaque, int arg,
|
||||
enum LogOperation op, int offset, int size);
|
||||
int eb_delete_uchar(EditBuffer *b, int offset);
|
||||
int eb_insert_uchar(EditBuffer *b, int offset, int c);
|
||||
int eb_insert_utf8_buf(EditBuffer *b, int offset, const char *buf, int len);
|
||||
|
|
@ -1141,6 +1164,7 @@ extern int tty_bg_colors_count;
|
|||
extern unsigned int const *tty_fg_colors;
|
||||
extern int tty_fg_colors_count;
|
||||
int get_tty_color(QEColor color, unsigned int const *colors, int count);
|
||||
int get_tty_style(const char *style);
|
||||
|
||||
/* special selection style (cumulative with another style) */
|
||||
#define QE_STYLE_SEL 0x400
|
||||
|
|
|
|||
|
|
@ -291,10 +291,10 @@ static CmdDef basic_commands[] = {
|
|||
|
||||
CMD2( KEY_CTRLXRET('f'), KEY_NONE,
|
||||
"set-buffer-file-coding-system", do_set_buffer_file_coding_system, ESs,
|
||||
"s{Charset: }[charset]")
|
||||
"s{Charset: }[charset]|charset|")
|
||||
CMD2( KEY_NONE, KEY_NONE,
|
||||
"convert-buffer-file-coding-system", do_convert_buffer_file_coding_system, ESs,
|
||||
"*" "s{Charset: }[charset]")
|
||||
"*" "s{Charset: }[charset]|charset|")
|
||||
CMD0( KEY_CTRLXRET('b'), KEY_NONE,
|
||||
"toggle-bidir", do_toggle_bidir)
|
||||
CMD2( KEY_CTRLXRET(KEY_CTRL('\\')), KEY_NONE,
|
||||
|
|
|
|||
120
shell.c
120
shell.c
|
|
@ -465,6 +465,8 @@ static void tty_goto_xy(ShellState *s, int x, int y, int relative)
|
|||
line_num += y;
|
||||
/* add lines if necessary */
|
||||
while (line_num >= total_lines) {
|
||||
/* XXX: color may be wrong */
|
||||
s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
|
||||
eb_insert_uchar(s->b, s->b->total_size, '\n');
|
||||
total_lines++;
|
||||
}
|
||||
|
|
@ -473,6 +475,7 @@ static void tty_goto_xy(ShellState *s, int x, int y, int relative)
|
|||
c = eb_nextc(s->b, offset, &offset1);
|
||||
if (c == '\n') {
|
||||
for (; x > 0; x--) {
|
||||
/* duplicate style of last char */
|
||||
offset += eb_insert_uchar(s->b, offset, ' ');
|
||||
}
|
||||
break;
|
||||
|
|
@ -492,6 +495,7 @@ static int tty_put_char(ShellState *s, int c)
|
|||
offset = s->cur_offset;
|
||||
buf[0] = c;
|
||||
c1 = eb_nextc(s->b, offset, &offset1);
|
||||
s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
|
||||
if (c1 == '\n') {
|
||||
/* insert */
|
||||
eb_insert(s->b, offset, buf, 1);
|
||||
|
|
@ -793,6 +797,7 @@ static void tty_emulate(ShellState *s, int c)
|
|||
if (offset == s->b->total_size) {
|
||||
/* add a new line */
|
||||
/* CG: XXX: ignoring charset */
|
||||
s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
|
||||
buf1[0] = '\n';
|
||||
eb_insert(s->b, offset, buf1, 1);
|
||||
offset = s->b->total_size;
|
||||
|
|
@ -874,6 +879,7 @@ static void tty_emulate(ShellState *s, int c)
|
|||
len = 1;
|
||||
}
|
||||
c1 = eb_nextc(s->b, offset, &offset1);
|
||||
s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
|
||||
/* Should simplify with tty_put_char */
|
||||
if (c1 == '\n') {
|
||||
/* insert */
|
||||
|
|
@ -899,6 +905,7 @@ static void tty_emulate(ShellState *s, int c)
|
|||
|
||||
len = s->utf8_len;
|
||||
c1 = eb_nextc(s->b, offset, &offset1);
|
||||
s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
|
||||
if (c1 == '\n') {
|
||||
/* insert */
|
||||
eb_insert(s->b, offset, s->utf8_buf, len);
|
||||
|
|
@ -1123,6 +1130,7 @@ static void tty_emulate(ShellState *s, int c)
|
|||
case '@': /* ICH: insert chars (no cursor update) */
|
||||
buf1[0] = ' ';
|
||||
offset1 = offset;
|
||||
s->b->cur_style = QE_STYLE_TTY | s->color | s->attr;
|
||||
for (n = s->esc_params[0]; n > 0; n--) {
|
||||
/* XXX: incorrect for non 8 bit charsets */
|
||||
eb_insert(s->b, offset1, buf1, 1);
|
||||
|
|
@ -1208,86 +1216,6 @@ static void tty_emulate(ShellState *s, int c)
|
|||
tty_update_cursor(s);
|
||||
}
|
||||
|
||||
/* modify the color according to the current one (may be incorrect if
|
||||
we are editing because we should write default color) */
|
||||
static void shell_color_callback(__unused__ EditBuffer *b,
|
||||
void *opaque, int arg,
|
||||
enum LogOperation op, int offset, int size)
|
||||
{
|
||||
ShellState *s = opaque;
|
||||
unsigned char buf[256];
|
||||
int len;
|
||||
|
||||
switch (op) {
|
||||
case LOGOP_WRITE:
|
||||
while (size > 0) {
|
||||
len = size;
|
||||
if (len > ssizeof(buf))
|
||||
len = ssizeof(buf);
|
||||
memset(buf, s->color | s->attr, len);
|
||||
eb_write(s->b_color, offset, buf, len);
|
||||
size -= len;
|
||||
offset += len;
|
||||
}
|
||||
break;
|
||||
case LOGOP_INSERT:
|
||||
while (size > 0) {
|
||||
len = size;
|
||||
if (len > ssizeof(buf))
|
||||
len = ssizeof(buf);
|
||||
memset(buf, s->color | s->attr, len);
|
||||
eb_insert(s->b_color, offset, buf, len);
|
||||
size -= len;
|
||||
offset += len;
|
||||
}
|
||||
break;
|
||||
case LOGOP_DELETE:
|
||||
eb_delete(s->b_color, offset, size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int shell_get_colorized_line(EditState *e,
|
||||
unsigned int *buf, int buf_size,
|
||||
int *offsetp, __unused__ int line_num)
|
||||
{
|
||||
EditBuffer *b = e->b;
|
||||
ShellState *s = b->priv_data;
|
||||
EditBuffer *b_color = s->b_color;
|
||||
int color, offset, offset1, c;
|
||||
unsigned int *buf_ptr, *buf_end;
|
||||
unsigned char buf1[1];
|
||||
|
||||
/* record line */
|
||||
offset = *offsetp;
|
||||
buf_ptr = buf;
|
||||
buf_end = buf + buf_size - 1;
|
||||
for (;;) {
|
||||
c = eb_nextc(b, offset, &offset1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (buf_ptr < buf_end) {
|
||||
if (b_color) {
|
||||
eb_read(b_color, offset, buf1, 1);
|
||||
color = buf1[0];
|
||||
/* XXX: test */
|
||||
//if (color != s->def_color)
|
||||
{
|
||||
c |= (QE_STYLE_TTY | color) << STYLE_SHIFT;
|
||||
}
|
||||
}
|
||||
*buf_ptr++ = c;
|
||||
}
|
||||
offset = offset1;
|
||||
}
|
||||
*buf_ptr = '\0';
|
||||
*offsetp = offset1;
|
||||
|
||||
return buf_ptr - buf;
|
||||
}
|
||||
|
||||
/* buffer related functions */
|
||||
|
||||
/* called when characters are available on the tty */
|
||||
|
|
@ -1414,15 +1342,20 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, const char *bufname,
|
|||
{
|
||||
QEmacsState *qs = &qe_state;
|
||||
ShellState *s;
|
||||
EditBuffer *b, *b_color;
|
||||
EditBuffer *b;
|
||||
const char *lang;
|
||||
int rows, cols;
|
||||
|
||||
b = b0;
|
||||
if (!b)
|
||||
b = eb_new("", BF_SAVELOG);
|
||||
if (!b)
|
||||
return NULL;
|
||||
if (!b) {
|
||||
int bf_flags = BF_SAVELOG;
|
||||
if (shell_flags & SF_COLOR)
|
||||
bf_flags |= BF_STYLE2;
|
||||
b = eb_new("", bf_flags);
|
||||
if (!b)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eb_set_buffer_name(b, bufname); /* ensure that the name is unique */
|
||||
|
||||
/* Select shell output buffer encoding from LANG setting */
|
||||
|
|
@ -1451,21 +1384,6 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, const char *bufname,
|
|||
s->shell_flags = shell_flags;
|
||||
tty_init(s);
|
||||
|
||||
/* add color buffer */
|
||||
if (shell_flags & SF_COLOR) {
|
||||
b_color = eb_new("*color*", BF_SYSTEM);
|
||||
if (!b_color) {
|
||||
if (!b0)
|
||||
eb_free(b);
|
||||
qe_free(&s);
|
||||
return NULL;
|
||||
}
|
||||
/* no undo info in this color buffer */
|
||||
b_color->save_log = 0;
|
||||
eb_add_callback(b, shell_color_callback, s, 0);
|
||||
s->b_color = b_color;
|
||||
}
|
||||
|
||||
/* launch shell */
|
||||
cols = TTY_XSIZE;
|
||||
rows = TTY_YSIZE;
|
||||
|
|
@ -1901,7 +1819,6 @@ static int shell_mode_init(EditState *s, __unused__ ModeSavedData *saved_data)
|
|||
text_mode_init(s, saved_data);
|
||||
s->tab_size = 8;
|
||||
s->wrap = WRAP_TRUNCATE;
|
||||
s->get_colorized_line = shell_get_colorized_line;
|
||||
s->interactive = 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1911,7 +1828,6 @@ static int pager_mode_init(EditState *s, __unused__ ModeSavedData *saved_data)
|
|||
text_mode_init(s, saved_data);
|
||||
s->tab_size = 8;
|
||||
s->wrap = WRAP_TRUNCATE;
|
||||
s->get_colorized_line = shell_get_colorized_line;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
73
tty.c
73
tty.c
|
|
@ -857,6 +857,79 @@ static void tty_term_fill_rectangle(QEditScreen *s,
|
|||
}
|
||||
}
|
||||
|
||||
int str_get_word(char *buf, int size, const char *p, const char **pp)
|
||||
{
|
||||
int len;
|
||||
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
|
||||
for (len = 0; *p != '\0' && *p != ' ' && *p != '/'; p++, len++) {
|
||||
if (len < size - 1)
|
||||
buf[len] = *p;
|
||||
}
|
||||
if (len < size - 1)
|
||||
buf[len] = '\0';
|
||||
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
|
||||
if (pp)
|
||||
*pp = p;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* match a keyword, ignore case, check word boundary */
|
||||
int str_match_word(const char *str, const char *val, const char **pp)
|
||||
{
|
||||
if (stristart(str, val, &str) && (*str == '\0' || *str == ' ')) {
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
if (pp)
|
||||
*pp = str;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_tty_style(const char *str)
|
||||
{
|
||||
char buf[128];
|
||||
QEColor fg_color, bg_color;
|
||||
int fg, bg, style;
|
||||
const char *p = str;
|
||||
|
||||
style = 0;
|
||||
for (;;) {
|
||||
if (str_match_word(p, "bold", &p)) {
|
||||
style |= TTY_BOLD;
|
||||
continue;
|
||||
}
|
||||
if (str_match_word(p, "blinking", &p)
|
||||
|| str_match_word(p, "blink", &p)) {
|
||||
style |= TTY_BLINK;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fg_color = QERGB(0xbb, 0xbb, 0xbb);
|
||||
bg_color = QERGB(0x00, 0x00, 0x00);
|
||||
if (str_get_word(buf, sizeof(buf), p, &p)) {
|
||||
if (css_get_color(&fg_color, buf))
|
||||
return -1;
|
||||
if (str_match_word(p, "on", &p) || (*p == '/' && p++)) {
|
||||
str_get_word(buf, sizeof(buf), p, &p);
|
||||
if (css_get_color(&bg_color, buf))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fg = get_tty_color(fg_color, tty_fg_colors, tty_fg_colors_count);
|
||||
bg = get_tty_color(bg_color, tty_fg_colors, tty_fg_colors_count);
|
||||
|
||||
return QE_STYLE_TTY | style | TTY_MAKE_COLOR(fg, bg);
|
||||
}
|
||||
|
||||
/* XXX: could alloc font in wrapper */
|
||||
static QEFont *tty_term_open_font(__unused__ QEditScreen *s,
|
||||
__unused__ int style, __unused__ int size)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue