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:
Charlie Gordon 2014-01-15 19:44:24 +00:00
commit 02da1bb7a1
10 changed files with 361 additions and 136 deletions

View file

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

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

View file

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

View file

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

View file

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

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

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

View file

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

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

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