Improve completion system
- rename and extend CompletionEntry as CompletionDef - create xxx_completion CompletionDef structures - rename xxx_completion() functions to xxx_complete() - register CompletionDef structs with qe_register_completion() - add (start, end) range in CompleteState - use eb_puts() and eb_putc() instead of eb_printf() - simplify eb_delete_chars() - ignore left pane in compare-windows() - simplify qe_list_bindings() - improve command and variable completion popup
This commit is contained in:
parent
2fa0120472
commit
9d967ad29c
15 changed files with 371 additions and 158 deletions
5
bufed.c
5
bufed.c
|
|
@ -152,11 +152,10 @@ static void build_bufed_list(BufedState *bs, EditState *s)
|
|||
b->cur_style = BUFED_STYLE_DIRECTORY;
|
||||
else
|
||||
b->cur_style = BUFED_STYLE_FILENAME;
|
||||
eb_printf(b, "%s",
|
||||
make_user_path(path, sizeof(path), b1->filename));
|
||||
eb_puts(b, make_user_path(path, sizeof(path), b1->filename));
|
||||
b->cur_style = style0;
|
||||
}
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
}
|
||||
b->modified = 0;
|
||||
b->flags |= BF_READONLY;
|
||||
|
|
|
|||
11
buffer.c
11
buffer.c
|
|
@ -1531,16 +1531,7 @@ int eb_delete_uchar(EditBuffer *b, int offset)
|
|||
*/
|
||||
int eb_delete_chars(EditBuffer *b, int offset, int n)
|
||||
{
|
||||
int offset1 = eb_skip_chars(b, offset, n);
|
||||
int size = offset1 - offset;
|
||||
|
||||
if (size < 0) {
|
||||
offset += size;
|
||||
offset1 -= size;
|
||||
size = -size;
|
||||
}
|
||||
|
||||
return eb_delete(b, offset, size);
|
||||
return eb_delete_range(b, offset, eb_skip_chars(b, offset, n));
|
||||
}
|
||||
|
||||
/* XXX: only stateless charsets are supported */
|
||||
|
|
|
|||
|
|
@ -1130,7 +1130,7 @@ void qe_register_charset(struct QECharset *charset)
|
|||
*pp = charset;
|
||||
}
|
||||
|
||||
void charset_completion(CompleteState *cp)
|
||||
void charset_complete(CompleteState *cp)
|
||||
{
|
||||
QECharset *charset;
|
||||
char name[32];
|
||||
|
|
|
|||
14
dired.c
14
dired.c
|
|
@ -683,11 +683,11 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s,
|
|||
if (DIRED_HEADER) {
|
||||
int seq = ' ';
|
||||
b->cur_style = DIRED_STYLE_HEADER;
|
||||
eb_printf(b, " Directory of ");
|
||||
eb_puts(b, " Directory of ");
|
||||
b->cur_style = DIRED_STYLE_DIRECTORY;
|
||||
eb_printf(b, "%s", ds->path);
|
||||
eb_puts(b, ds->path);
|
||||
b->cur_style = DIRED_STYLE_HEADER;
|
||||
eb_printf(b, "\n ");
|
||||
eb_puts(b, "\n ");
|
||||
if (ds->ndirs) {
|
||||
eb_printf(b, "%c %d %s", seq, ds->ndirs,
|
||||
inflect(ds->ndirs, "directory", "directories"));
|
||||
|
|
@ -717,7 +717,7 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s,
|
|||
if (ds->ndirs + ds->ndirs_hidden + ds->nfiles + ds->nfiles_hidden == 0) {
|
||||
eb_printf(b, "%c empty", seq);
|
||||
}
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
}
|
||||
b->cur_style = DIRED_STYLE_NORMAL;
|
||||
|
||||
|
|
@ -767,12 +767,12 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s,
|
|||
else
|
||||
b->cur_style = DIRED_STYLE_FILENAME;
|
||||
|
||||
eb_printf(b, "%s", dip->name);
|
||||
eb_puts(b, dip->name);
|
||||
|
||||
if (1) {
|
||||
int trailchar = get_trailchar(dip->mode);
|
||||
if (trailchar) {
|
||||
eb_printf(b, "%c", trailchar);
|
||||
eb_putc(b, trailchar);
|
||||
}
|
||||
}
|
||||
if (S_ISLNK(dip->mode)
|
||||
|
|
@ -780,7 +780,7 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s,
|
|||
eb_printf(b, " -> %s", buf);
|
||||
}
|
||||
b->cur_style = DIRED_STYLE_NORMAL;
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
}
|
||||
b->modified = 0;
|
||||
b->flags |= BF_READONLY;
|
||||
|
|
|
|||
82
extras.c
82
extras.c
|
|
@ -123,21 +123,24 @@ void do_compare_windows(EditState *s, int argval)
|
|||
|
||||
s1 = s;
|
||||
/* Should use same internal function as for next_window */
|
||||
if (s1->next_window)
|
||||
s2 = s1->next_window;
|
||||
else
|
||||
s2 = qs->first_window;
|
||||
|
||||
for (s2 = s1;;) {
|
||||
s2 = s2->next_window;
|
||||
if (s2 == NULL)
|
||||
s2 = qs->first_window;
|
||||
if (s2 == s1) {
|
||||
/* single window: bail out */
|
||||
return;
|
||||
}
|
||||
if (s2->b->flags & BF_DIRED)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (argval != NO_ARG) {
|
||||
if (argval & 4)
|
||||
qs->ignore_spaces ^= 1;
|
||||
if (argval & 16)
|
||||
qs->ignore_comments ^= 1;
|
||||
}
|
||||
if (s1 == s2) {
|
||||
/* single window: bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
size1 = s1->b->total_size;
|
||||
size2 = s2->b->total_size;
|
||||
|
|
@ -867,8 +870,7 @@ static void do_unset_key(EditState *s, const char *keystr, int local)
|
|||
|
||||
/*---------------- help ----------------*/
|
||||
|
||||
static int qe_list_bindings(char *buf, int size, CmdDef *d,
|
||||
ModeDef *mode, int inherit)
|
||||
int qe_list_bindings(CmdDef *d, ModeDef *mode, int inherit, char *buf, int size)
|
||||
{
|
||||
int pos;
|
||||
buf_t outbuf, *out;
|
||||
|
|
@ -904,7 +906,7 @@ void do_show_bindings(EditState *s, const char *cmd_name)
|
|||
put_status(s, "No command %s", cmd_name);
|
||||
return;
|
||||
}
|
||||
if (qe_list_bindings(buf, sizeof(buf), d, s->mode, 1)) {
|
||||
if (qe_list_bindings(d, s->mode, 1, buf, sizeof(buf))) {
|
||||
put_status(s, "%s is bound to %s", cmd_name, buf);
|
||||
} else {
|
||||
put_status(s, "%s is not bound to any key", cmd_name);
|
||||
|
|
@ -916,18 +918,21 @@ static void print_bindings(EditBuffer *b, ModeDef *mode)
|
|||
char buf[256];
|
||||
CmdDef *d;
|
||||
int gfound;
|
||||
//int start = b->total_size;
|
||||
|
||||
/* XXX: should sort matches */
|
||||
gfound = 0;
|
||||
d = qe_state.first_cmd;
|
||||
while (d != NULL) {
|
||||
while (d->name != NULL) {
|
||||
if (qe_list_bindings(buf, sizeof(buf), d, mode, 0)) {
|
||||
if (qe_list_bindings(d, mode, 0, buf, sizeof(buf))) {
|
||||
if (!gfound) {
|
||||
if (mode) {
|
||||
eb_printf(b, "\n%s mode bindings:\n\n", mode->name);
|
||||
} else {
|
||||
eb_printf(b, "\nGlobal bindings:\n\n");
|
||||
}
|
||||
//start = b->total_size;
|
||||
gfound = 1;
|
||||
}
|
||||
eb_printf(b, "%24s : %s\n", d->name, buf);
|
||||
|
|
@ -936,6 +941,7 @@ static void print_bindings(EditBuffer *b, ModeDef *mode)
|
|||
}
|
||||
d = d->action.next;
|
||||
}
|
||||
//do_sort_span(b, start, b->total_size, 0, NO_ARG);
|
||||
}
|
||||
|
||||
void do_describe_bindings(EditState *s)
|
||||
|
|
@ -966,7 +972,10 @@ void do_apropos(EditState *s, const char *str)
|
|||
if (!b)
|
||||
return;
|
||||
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
|
||||
/* XXX: should sort matches */
|
||||
/* XXX: should print description */
|
||||
|
||||
found = 0;
|
||||
d = qs->first_cmd;
|
||||
|
|
@ -975,12 +984,12 @@ void do_apropos(EditState *s, const char *str)
|
|||
if (strstr(d->name, str)) {
|
||||
/* print name and prototype */
|
||||
qe_get_prototype(d, buf, sizeof(buf));
|
||||
eb_printf(b, "command: %s(%s)", d->name, buf);
|
||||
if (qe_list_bindings(buf, sizeof(buf), d, s->mode, 1))
|
||||
eb_printf(b, "command: %s%s", d->name, buf);
|
||||
if (qe_list_bindings(d, s->mode, 1, buf, sizeof(buf)))
|
||||
eb_printf(b, " bound to %s", buf);
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
/* TODO: print short description */
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
found = 1;
|
||||
}
|
||||
d++;
|
||||
|
|
@ -994,7 +1003,7 @@ void do_apropos(EditState *s, const char *str)
|
|||
eb_printf(b, "%s variable: %s -> %s\n",
|
||||
var_domain[vp->domain], vp->name, buf);
|
||||
/* TODO: print short description */
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1023,7 +1032,7 @@ static void do_about_qemacs(EditState *s)
|
|||
b = eb_scratch("*About QEmacs*", BF_UTF8);
|
||||
eb_printf(b, "\n %s\n\n%s\n", str_version, str_credits);
|
||||
|
||||
/* list commands */
|
||||
/* list current bindings */
|
||||
print_bindings(b, s->mode);
|
||||
print_bindings(b, NULL);
|
||||
|
||||
|
|
@ -1035,11 +1044,13 @@ static void do_about_qemacs(EditState *s)
|
|||
|
||||
/* list commands */
|
||||
eb_printf(b, "\nCommands:\n\n");
|
||||
|
||||
/* XXX: should sort commands */
|
||||
d = qs->first_cmd;
|
||||
while (d != NULL) {
|
||||
while (d->name != NULL) {
|
||||
qe_get_prototype(d, buf, sizeof(buf));
|
||||
eb_printf(b, " %s(%s);\n", d->name, buf);
|
||||
eb_printf(b, " %s%s\n", d->name, buf);
|
||||
d++;
|
||||
}
|
||||
d = d->action.next;
|
||||
|
|
@ -1052,6 +1063,7 @@ static void do_about_qemacs(EditState *s)
|
|||
char **envp;
|
||||
|
||||
eb_printf(b, "\nEnvironment:\n\n");
|
||||
/* XXX: should sort environment variables */
|
||||
for (envp = environ; *envp; envp++) {
|
||||
eb_printf(b, " %s\n", *envp);
|
||||
}
|
||||
|
|
@ -1226,7 +1238,7 @@ static void do_describe_buffer(EditState *s, int argval)
|
|||
if (!b1)
|
||||
return;
|
||||
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
|
||||
eb_printf(b1, " name: %s\n", b->name);
|
||||
eb_printf(b1, " filename: %s\n", b->filename);
|
||||
|
|
@ -1370,12 +1382,12 @@ static void do_describe_buffer(EditState *s, int argval)
|
|||
col += eb_printf(b1, " 0x%02x", i);
|
||||
|
||||
if (col >= 60) {
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
if (col) {
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1402,14 +1414,14 @@ static void do_describe_buffer(EditState *s, int argval)
|
|||
if (c < 32 || c >= 127)
|
||||
eb_printf(b1, "\\%03o", c);
|
||||
else
|
||||
eb_printf(b1, "%c", c);
|
||||
eb_putc(b1, c);
|
||||
continue;
|
||||
}
|
||||
eb_printf(b1, "\\%c", c);
|
||||
}
|
||||
eb_printf(b1, "|%s\n", p->size > 16 ? "..." : "");
|
||||
}
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
}
|
||||
|
||||
b1->flags |= BF_READONLY;
|
||||
|
|
@ -1425,7 +1437,7 @@ static void do_describe_window(EditState *s, int argval)
|
|||
if (!b1)
|
||||
return;
|
||||
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
|
||||
w = 28;
|
||||
eb_printf(b1, "%*s: %d, %d\n", w, "xleft, ytop", s->xleft, s->ytop);
|
||||
|
|
@ -1479,7 +1491,7 @@ static void do_describe_window(EditState *s, int argval)
|
|||
eb_printf(b1, "%*s: %d\n", w, "show_selection", s->show_selection);
|
||||
eb_printf(b1, "%*s: %d\n", w, "region_style", s->region_style);
|
||||
eb_printf(b1, "%*s: %d\n", w, "curline_style", s->curline_style);
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
|
||||
b1->flags |= BF_READONLY;
|
||||
show_popup(s, b1, "Window Description");
|
||||
|
|
@ -1495,7 +1507,7 @@ static void do_describe_screen(EditState *e, int argval)
|
|||
if (!b1)
|
||||
return;
|
||||
|
||||
eb_printf(b1, "\n");
|
||||
eb_putc(b1, '\n');
|
||||
|
||||
w = 16;
|
||||
eb_printf(b1, "%*s: %s\n", w, "dpy.name", s->dpy.name);
|
||||
|
|
@ -1627,6 +1639,8 @@ static void do_sort_span(EditState *s, int p1, int p2, int flags, int argval) {
|
|||
struct chunk *chunk_array;
|
||||
|
||||
s->region_style = 0;
|
||||
if (argval != NO_ARG)
|
||||
flags |= argval;
|
||||
|
||||
if (p1 > p2) {
|
||||
int tmp = p1;
|
||||
|
|
@ -1634,8 +1648,6 @@ static void do_sort_span(EditState *s, int p1, int p2, int flags, int argval) {
|
|||
p2 = tmp;
|
||||
}
|
||||
ctx.b = s->b;
|
||||
if (argval != NO_ARG)
|
||||
flags |= argval;
|
||||
ctx.flags = flags;
|
||||
ctx.col = 0;
|
||||
eb_get_pos(s->b, &line1, &col1, p1); /* line1 is included */
|
||||
|
|
@ -1703,7 +1715,7 @@ static void tag_buffer(EditState *s) {
|
|||
}
|
||||
}
|
||||
|
||||
static void tag_completion(CompleteState *cp) {
|
||||
static void tag_complete(CompleteState *cp) {
|
||||
/* XXX: only support current buffer */
|
||||
QEProperty *p;
|
||||
|
||||
|
|
@ -1876,6 +1888,10 @@ static CmdDef extra_commands[] = {
|
|||
CMD_DEF_END,
|
||||
};
|
||||
|
||||
static CompletionDef tag_completion = {
|
||||
"tag", tag_complete,
|
||||
};
|
||||
|
||||
static int extras_init(void)
|
||||
{
|
||||
int key;
|
||||
|
|
@ -1884,7 +1900,7 @@ static int extras_init(void)
|
|||
for (key = KEY_META('0'); key <= KEY_META('9'); key++) {
|
||||
qe_register_binding(key, "numeric-argument", NULL);
|
||||
}
|
||||
register_completion("tag", tag_completion);
|
||||
qe_register_completion(&tag_completion);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
10
image.c
10
image.c
|
|
@ -846,7 +846,7 @@ void image_mode_line(EditState *s, buf_t *out)
|
|||
ib->interleaved ? 'I' : ' ');
|
||||
}
|
||||
|
||||
static void pixel_format_completion(CompleteState *cp)
|
||||
static void pixel_format_complete(CompleteState *cp)
|
||||
{
|
||||
int i;
|
||||
const char *name;
|
||||
|
|
@ -863,7 +863,7 @@ static CmdDef image_commands[] = {
|
|||
"image-rotate", image_rotate)
|
||||
CMD2( 'c', KEY_NONE,
|
||||
"image-convert", image_convert, ESs,
|
||||
"s{New pixel format: }[pixel_format]|pixel_format|")
|
||||
"s{New pixel format: }[pixel-format]|pixel-format|")
|
||||
CMD2( 'b', KEY_NONE,
|
||||
"image-set-background-color", image_set_background_color, ESs,
|
||||
"s{Background color (use 'transparent' for tiling): }")
|
||||
|
|
@ -909,13 +909,17 @@ static ModeDef image_mode = {
|
|||
.get_mode_line = image_mode_line,
|
||||
};
|
||||
|
||||
static CompletionDef pixel_format_completion = {
|
||||
"pixel-format", pixel_format_complete
|
||||
};
|
||||
|
||||
static int image_init(void)
|
||||
{
|
||||
av_register_all();
|
||||
eb_register_data_type(&image_data_type);
|
||||
qe_register_mode(&image_mode, MODEF_DATATYPE | MODEF_VIEW);
|
||||
qe_register_cmd_table(image_commands, &image_mode);
|
||||
register_completion("pixel_format", pixel_format_completion);
|
||||
qe_register_completion(&pixel_format_completion);
|
||||
/* additional mode specific keys */
|
||||
qe_register_binding('f', "toggle-full-screen", &image_mode);
|
||||
return 0;
|
||||
|
|
|
|||
8
input.c
8
input.c
|
|
@ -80,7 +80,7 @@ void register_input_method(InputMethod *m)
|
|||
*p = m;
|
||||
}
|
||||
|
||||
static void input_completion(CompleteState *cp)
|
||||
static void input_complete(CompleteState *cp)
|
||||
{
|
||||
QEmacsState *qs = cp->s->qe_state;
|
||||
InputMethod *m;
|
||||
|
|
@ -122,9 +122,13 @@ void do_switch_input_method(EditState *s)
|
|||
s->input_method = s->selected_input_method;
|
||||
}
|
||||
|
||||
static CompletionDef input_completion = {
|
||||
"input", input_complete,
|
||||
};
|
||||
|
||||
void init_input_methods(void)
|
||||
{
|
||||
register_input_method(&default_input_method);
|
||||
register_input_method(&unicode_input_method);
|
||||
register_completion("input", input_completion);
|
||||
qe_register_completion(&input_completion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ static struct latex_function {
|
|||
#undef INIT_TAIL
|
||||
};
|
||||
|
||||
static void latex_completion(CompleteState *cp)
|
||||
static void latex_complete(CompleteState *cp)
|
||||
{
|
||||
struct latex_function *func;
|
||||
|
||||
|
|
@ -344,12 +344,16 @@ static ModeDef texinfo_mode = {
|
|||
.colorize_flags = TEX_TEXINFO,
|
||||
};
|
||||
|
||||
static CompletionDef latex_completion = {
|
||||
"latex", latex_complete,
|
||||
};
|
||||
|
||||
static int latex_init(void)
|
||||
{
|
||||
qe_register_mode(&latex_mode, MODEF_SYNTAX);
|
||||
qe_register_mode(&texinfo_mode, MODEF_SYNTAX);
|
||||
qe_register_cmd_table(latex_commands, &latex_mode);
|
||||
register_completion("latex", latex_completion);
|
||||
qe_register_completion(&latex_completion);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
264
qe.c
264
qe.c
|
|
@ -62,7 +62,6 @@ static void display1(DisplayState *ds);
|
|||
#ifndef CONFIG_TINY
|
||||
static void save_selection(void);
|
||||
#endif
|
||||
static CompletionFunc find_completion(const char *name);
|
||||
|
||||
QEmacsState qe_state;
|
||||
/* should handle multiple screens, and multiple sessions */
|
||||
|
|
@ -206,7 +205,7 @@ void qe_register_mode(ModeDef *m, int flags)
|
|||
}
|
||||
}
|
||||
|
||||
void mode_completion(CompleteState *cp)
|
||||
void mode_complete(CompleteState *cp)
|
||||
{
|
||||
QEmacsState *qs = cp->s->qe_state;
|
||||
ModeDef *m;
|
||||
|
|
@ -218,6 +217,10 @@ void mode_completion(CompleteState *cp)
|
|||
}
|
||||
}
|
||||
|
||||
static CompletionDef mode_completion = {
|
||||
"mode", mode_complete
|
||||
};
|
||||
|
||||
/* commands handling */
|
||||
|
||||
CmdDef *qe_find_cmd(const char *cmd_name)
|
||||
|
|
@ -237,7 +240,7 @@ CmdDef *qe_find_cmd(const char *cmd_name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void command_completion(CompleteState *cp)
|
||||
void command_complete(CompleteState *cp)
|
||||
{
|
||||
QEmacsState *qs = cp->s->qe_state;
|
||||
CmdDef *d;
|
||||
|
|
@ -252,6 +255,51 @@ void command_completion(CompleteState *cp)
|
|||
}
|
||||
}
|
||||
|
||||
int command_print_entry(EditState *s, const char *name)
|
||||
{
|
||||
EditBuffer *b = s->b;
|
||||
CmdDef *d = qe_find_cmd(name);
|
||||
if (d) {
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
b->cur_style = QE_STYLE_FUNCTION;
|
||||
len = eb_puts(b, d->name);
|
||||
b->cur_style = QE_STYLE_DEFAULT;
|
||||
qe_get_prototype(d, buf, sizeof buf);
|
||||
len += eb_puts(b, buf);
|
||||
#ifndef CONFIG_TINY
|
||||
if (qe_list_bindings(d, s->mode, 1, buf, sizeof buf)) {
|
||||
b->cur_style = QE_STYLE_COMMENT;
|
||||
if (2 + len < 40) {
|
||||
b->tab_width = max(2 + len, b->tab_width);
|
||||
len += eb_putc(b, '\t');
|
||||
} else {
|
||||
b->tab_width = 40;
|
||||
}
|
||||
len += eb_printf(b, " bound to %s", buf);
|
||||
b->cur_style = QE_STYLE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
return len;
|
||||
} else {
|
||||
return eb_puts(b, name);
|
||||
}
|
||||
}
|
||||
|
||||
int command_get_entry(EditState *s, char *dest, int size, int offset)
|
||||
{
|
||||
int len;
|
||||
eb_fgets(s->b, dest, size, offset, &offset);
|
||||
len = strcspn(dest, " \t\n(");
|
||||
dest[len] = '\0'; /* strip the TAB or trailing newline if any */
|
||||
return len;
|
||||
}
|
||||
|
||||
static CompletionDef command_completion = {
|
||||
"command", command_complete, command_print_entry, command_get_entry
|
||||
};
|
||||
|
||||
static int qe_register_binding1(unsigned int *keys, int nb_keys,
|
||||
CmdDef *d, ModeDef *m)
|
||||
{
|
||||
|
|
@ -2958,7 +3006,7 @@ void get_style(EditState *e, QEStyleDef *stp, QETermStyle style)
|
|||
apply_style(stp, style);
|
||||
}
|
||||
|
||||
void style_completion(CompleteState *cp)
|
||||
void style_complete(CompleteState *cp)
|
||||
{
|
||||
int i;
|
||||
QEStyleDef *stp;
|
||||
|
|
@ -2997,6 +3045,10 @@ QEStyleDef *find_style(const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static CompletionDef style_completion = {
|
||||
"style", style_complete
|
||||
};
|
||||
|
||||
static const char * const qe_style_properties[] = {
|
||||
#define CSS_PROP_COLOR 0
|
||||
"color", /* color */
|
||||
|
|
@ -3015,7 +3067,7 @@ static const char * const qe_style_properties[] = {
|
|||
"text-decoration", /* text_decoration: none / underline */
|
||||
};
|
||||
|
||||
void style_property_completion(CompleteState *cp)
|
||||
void style_property_complete(CompleteState *cp)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -3024,6 +3076,10 @@ void style_property_completion(CompleteState *cp)
|
|||
}
|
||||
}
|
||||
|
||||
static CompletionDef style_property_completion = {
|
||||
"style-property", style_property_complete
|
||||
};
|
||||
|
||||
int find_style_property(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -4721,6 +4777,8 @@ int qe_get_prototype(CmdDef *d, char *buf, int size)
|
|||
|
||||
out = buf_init(&outbuf, buf, size);
|
||||
|
||||
buf_put_byte(out, '(');
|
||||
|
||||
/* construct argument type list */
|
||||
r = d->name + strlen(d->name) + 1;
|
||||
if (*r == '*') {
|
||||
|
|
@ -4763,6 +4821,7 @@ int qe_get_prototype(CmdDef *d, char *buf, int size)
|
|||
buf_puts(out, *history ? history : completion);
|
||||
}
|
||||
}
|
||||
buf_put_byte(out, ')');
|
||||
return out->len;
|
||||
}
|
||||
|
||||
|
|
@ -4874,6 +4933,7 @@ static void parse_args(ExecCmdState *es)
|
|||
char def_input[1024];
|
||||
|
||||
/* XXX: currently, default input is handled non generically */
|
||||
/* XXX: should use completion function for default input? */
|
||||
def_input[0] = '\0';
|
||||
es->default_input[0] = '\0';
|
||||
if (strequal(completion_name, "file")) {
|
||||
|
|
@ -5010,6 +5070,7 @@ void do_execute_command(EditState *s, const char *cmd, int argval)
|
|||
{
|
||||
CmdDef *d;
|
||||
|
||||
/* XXX: should test for '(' and '=' and evaluate script instead */
|
||||
d = qe_find_cmd(cmd);
|
||||
if (d) {
|
||||
exec_command(s, d, argval, 0);
|
||||
|
|
@ -5917,7 +5978,7 @@ static const char *file_completion_ignore_extensions = {
|
|||
"|"
|
||||
};
|
||||
|
||||
void file_completion(CompleteState *cp)
|
||||
void file_complete(CompleteState *cp)
|
||||
{
|
||||
char path[MAX_FILENAME_SIZE];
|
||||
char file[MAX_FILENAME_SIZE];
|
||||
|
|
@ -5969,7 +6030,11 @@ void file_completion(CompleteState *cp)
|
|||
find_file_close(&ffst);
|
||||
}
|
||||
|
||||
void buffer_completion(CompleteState *cp)
|
||||
static CompletionDef file_completion = {
|
||||
"file", file_complete
|
||||
};
|
||||
|
||||
void buffer_complete(CompleteState *cp)
|
||||
{
|
||||
QEmacsState *qs = cp->s->qe_state;
|
||||
EditBuffer *b;
|
||||
|
|
@ -5980,45 +6045,69 @@ void buffer_completion(CompleteState *cp)
|
|||
}
|
||||
}
|
||||
|
||||
/* register a new completion method */
|
||||
void register_completion(const char *name, CompletionFunc completion_func)
|
||||
{
|
||||
QEmacsState *qs = &qe_state;
|
||||
CompletionEntry **lp, *p;
|
||||
static CompletionDef buffer_completion = {
|
||||
"buffer", buffer_complete
|
||||
};
|
||||
|
||||
p = qe_mallocz(CompletionEntry);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
p->name = name;
|
||||
p->completion_func = completion_func;
|
||||
p->next = NULL;
|
||||
|
||||
lp = &qs->first_completion;
|
||||
while (*lp != NULL)
|
||||
lp = &(*lp)->next;
|
||||
*lp = p;
|
||||
static int default_completion_window_print_entry(EditState *s, const char *name) {
|
||||
return eb_puts(s->b, name);
|
||||
}
|
||||
|
||||
static CompletionFunc find_completion(const char *name)
|
||||
static int default_completion_window_get_entry(EditState *s, char *dest, int size, int offset) {
|
||||
int len = eb_fgets(s->b, dest, size, offset, &offset);
|
||||
char *p = strchr(dest, '\t');
|
||||
if (p != NULL)
|
||||
len = p - dest;
|
||||
dest[len] = '\0'; /* strip the TAB or trailing newline if any */
|
||||
return len;
|
||||
}
|
||||
|
||||
/* register a new completion method */
|
||||
void qe_register_completion(CompletionDef *cp)
|
||||
{
|
||||
CompletionEntry *p;
|
||||
QEmacsState *qs = &qe_state;
|
||||
CompletionDef **p;
|
||||
|
||||
for (p = &qs->first_completion;; p = &(*p)->next) {
|
||||
if (*p == cp) {
|
||||
/* completion is already registered, do nothing */
|
||||
return;
|
||||
}
|
||||
if (*p == NULL) {
|
||||
cp->next = NULL;
|
||||
*p = cp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cp->print_entry)
|
||||
cp->print_entry = default_completion_window_print_entry;
|
||||
if (!cp->get_entry)
|
||||
cp->get_entry = default_completion_window_get_entry;
|
||||
}
|
||||
|
||||
static CompletionDef *find_completion(const char *name)
|
||||
{
|
||||
CompletionDef *p;
|
||||
|
||||
if (name[0] != '\0') {
|
||||
for (p = qe_state.first_completion; p != NULL; p = p->next) {
|
||||
if (strequal(p->name, name))
|
||||
return p->completion_func;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void complete_start(CompleteState *cp, EditState *s, EditState *target)
|
||||
static void complete_start(CompleteState *cp, EditState *s, int start, int end,
|
||||
EditState *target)
|
||||
{
|
||||
memset(cp, 0, sizeof(*cp));
|
||||
cp->s = s;
|
||||
cp->target = target;
|
||||
cp->len = eb_get_contents(s->b, cp->current, sizeof(cp->current));
|
||||
cp->start = start;
|
||||
cp->end = end;
|
||||
cp->len = eb_get_region_contents(s->b, cp->start, cp->end,
|
||||
cp->current, sizeof(cp->current));
|
||||
}
|
||||
|
||||
/* XXX: should have a globbing option */
|
||||
|
|
@ -6065,8 +6154,10 @@ typedef struct MinibufState {
|
|||
void *opaque;
|
||||
|
||||
EditState *completion_popup_window; /* XXX: should have a popup_window member */
|
||||
OWNED char *completion_name;
|
||||
CompletionFunc completion_function;
|
||||
int completion_flags;
|
||||
int completion_start;
|
||||
int completion_end;
|
||||
CompletionDef *completion;
|
||||
|
||||
StringArray *history;
|
||||
int history_index;
|
||||
|
|
@ -6082,7 +6173,7 @@ static inline MinibufState *minibuffer_get_state(EditState *e, int status) {
|
|||
void do_minibuffer_complete(EditState *s, int type)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
int count, i, match_len, c;
|
||||
int count, i, match_len, c, start, end;
|
||||
CompleteState cs;
|
||||
StringItem **outputs;
|
||||
EditState *e;
|
||||
|
|
@ -6093,7 +6184,7 @@ void do_minibuffer_complete(EditState *s, int type)
|
|||
if ((mb = minibuffer_get_state(s, 1)) == NULL)
|
||||
return;
|
||||
|
||||
if (!mb->completion_function)
|
||||
if (!mb->completion)
|
||||
return;
|
||||
|
||||
/* Remove highlighted selection. */
|
||||
|
|
@ -6117,8 +6208,21 @@ void do_minibuffer_complete(EditState *s, int type)
|
|||
return;
|
||||
}
|
||||
|
||||
complete_start(&cs, s, s->target_window);
|
||||
(*mb->completion_function)(&cs);
|
||||
start = 0;
|
||||
end = s->offset;
|
||||
if (mb->completion_flags) {
|
||||
/* XXX: completion select? */
|
||||
int offset = end;
|
||||
while ((start = offset) > 0) {
|
||||
int c = eb_prevc(s->b, offset, &offset);
|
||||
if (!qe_isalnum_(c) && c != '-')
|
||||
break;
|
||||
}
|
||||
}
|
||||
mb->completion_start = start;
|
||||
mb->completion_end = end;
|
||||
complete_start(&cs, s, start, end, s->target_window);
|
||||
(*mb->completion->enumerate)(&cs);
|
||||
count = cs.cs.nb_items;
|
||||
outputs = cs.cs.items;
|
||||
#if 0
|
||||
|
|
@ -6150,10 +6254,12 @@ void do_minibuffer_complete(EditState *s, int type)
|
|||
if (match_len > cs.len) {
|
||||
/* add the possible chars */
|
||||
// XXX: potential utf-8 issue?
|
||||
eb_write(s->b, 0, outputs[0]->str, match_len);
|
||||
s->offset = match_len;
|
||||
// XXX: replace the completed part, not necessarily at the start (use mark?)
|
||||
// XXX: should delete region and insert as utf-8
|
||||
eb_replace(s->b, cs.start, cs.end - cs.start, outputs[0]->str, match_len);
|
||||
s->offset = cs.start + match_len;
|
||||
if (type == COMPLETION_OTHER) {
|
||||
do_mark_region(s, match_len, cs.len);
|
||||
do_mark_region(s, cs.start + match_len, cs.start + cs.len); // XXX: ???
|
||||
}
|
||||
} else {
|
||||
if (count > 1) {
|
||||
|
|
@ -6170,7 +6276,7 @@ void do_minibuffer_complete(EditState *s, int type)
|
|||
w = (w1 * 3) / 4;
|
||||
h = (h1 * 3) / 4;
|
||||
e = edit_new(b, (w1 - w) / 2, (h1 - h) / 2, w, h, WF_POPUP);
|
||||
snprintf(buf, sizeof buf, "Select a %s:", mb->completion_name);
|
||||
snprintf(buf, sizeof buf, "Select a %s:", mb->completion->name);
|
||||
e->caption = qe_strdup(buf);
|
||||
e->target_window = s;
|
||||
mb->completion_popup_window = e;
|
||||
|
|
@ -6190,10 +6296,12 @@ void do_minibuffer_complete(EditState *s, int type)
|
|||
qsort(outputs, count, sizeof(StringItem *), completion_sort_func);
|
||||
b->flags &= ~BF_READONLY;
|
||||
eb_delete(b, 0, b->total_size);
|
||||
b->tab_width = 4;
|
||||
for (i = 0; i < count; i++) {
|
||||
eb_printf(b, " %s", outputs[i]->str);
|
||||
eb_putc(b, ' '); /* XXX: should use window margins */
|
||||
mb->completion->print_entry(e, outputs[i]->str);
|
||||
if (i != count - 1)
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
}
|
||||
b->flags |= BF_READONLY;
|
||||
e->mouse_force_highlight = 1;
|
||||
|
|
@ -6221,7 +6329,7 @@ void do_minibuffer_electric(EditState *s, int key)
|
|||
int c, offset, stop;
|
||||
MinibufState *mb = minibuffer_get_state(s, 0);
|
||||
|
||||
if (mb && mb->completion_function == file_completion) {
|
||||
if (mb && mb->completion == &file_completion) {
|
||||
stop = s->offset;
|
||||
c = eb_prevc(s->b, s->offset, &offset);
|
||||
if (c == '/') {
|
||||
|
|
@ -6242,7 +6350,7 @@ void do_minibuffer_complete_space(EditState *s)
|
|||
QEmacsState *qs = s->qe_state;
|
||||
MinibufState *mb = minibuffer_get_state(s, 0);
|
||||
|
||||
if (!mb || !mb->completion_function) {
|
||||
if (!mb || !mb->completion) {
|
||||
do_char(s, ' ', 1);
|
||||
} else
|
||||
if (check_window(&mb->completion_popup_window)
|
||||
|
|
@ -6278,15 +6386,15 @@ void minibuf_complete_scroll_up_down(qe__unused__ EditState *s, int dir)
|
|||
}
|
||||
}
|
||||
|
||||
static void minibuf_set_str(EditState *s, const char *str)
|
||||
static void minibuf_set_str(EditState *s, int start, int end, const char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
eb_delete(s->b, 0, s->b->total_size);
|
||||
/* Replace the completion trigger zone */
|
||||
/* XXX: should insert utf-8? */
|
||||
len = strlen(str);
|
||||
eb_write(s->b, 0, str, len);
|
||||
s->offset = len;
|
||||
eb_replace(s->b, start, end - start, str, len);
|
||||
s->offset = start + len;
|
||||
}
|
||||
|
||||
/* CG: should use buffer of responses */
|
||||
|
|
@ -6347,7 +6455,7 @@ void do_minibuffer_history(EditState *s, int dir)
|
|||
/* insert history text */
|
||||
mb->history_index = index;
|
||||
str = hist->items[index]->str;
|
||||
minibuf_set_str(s, str);
|
||||
minibuf_set_str(s, 0, s->b->total_size, str);
|
||||
if (index == hist->nb_items - 1) {
|
||||
s->offset = mb->history_saved_offset;
|
||||
}
|
||||
|
|
@ -6383,12 +6491,11 @@ void do_minibuffer_exit(EditState *s, int do_abort)
|
|||
/* if completion is activated, then select current file only if
|
||||
the selection is highlighted */
|
||||
if (cw && cw->force_highlight) {
|
||||
int offset, len;
|
||||
|
||||
len = eb_fgets(cw->b, buf, sizeof(buf), list_get_offset(cw), &offset);
|
||||
buf[len] = '\0'; /* strip the trailing newline if any */
|
||||
int len;
|
||||
len = mb->completion->get_entry(cw, buf, sizeof(buf), list_get_offset(cw) + 1);
|
||||
if (len > 0) {
|
||||
minibuf_set_str(s, buf + 1);
|
||||
eb_delete_range(s->b, s->b->mark, s->offset); // delete highlighted completion
|
||||
minibuf_set_str(s, mb->completion_start, mb->completion_end, buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6417,7 +6524,6 @@ void do_minibuffer_exit(EditState *s, int do_abort)
|
|||
target = s->target_window;
|
||||
mb->cb = NULL;
|
||||
mb->opaque = NULL;
|
||||
qe_free(&mb->completion_name);
|
||||
|
||||
/* Close the minibuffer window */
|
||||
s->b->flags |= BF_TRANSIENT;
|
||||
|
|
@ -6477,11 +6583,13 @@ void minibuffer_edit(EditState *e, const char *input, const char *prompt,
|
|||
mb = minibuffer_get_state(s, 0);
|
||||
if (mb) {
|
||||
mb->completion_popup_window = NULL;
|
||||
mb->completion_name = NULL;
|
||||
mb->completion_function = NULL;
|
||||
mb->completion = NULL;
|
||||
if (completion_name) {
|
||||
mb->completion_name = qe_strdup(completion_name);
|
||||
mb->completion_function = find_completion(completion_name);
|
||||
if (*completion_name == '.') {
|
||||
mb->completion_flags = 1;
|
||||
completion_name++;
|
||||
}
|
||||
mb->completion = find_completion(completion_name);
|
||||
}
|
||||
mb->history = hist;
|
||||
mb->history_saved_offset = 0;
|
||||
|
|
@ -8039,13 +8147,13 @@ void do_help_for_help(EditState *s)
|
|||
if (!b)
|
||||
return;
|
||||
|
||||
eb_printf(b,
|
||||
"QEmacs help for help - Press q to quit:\n"
|
||||
"\n"
|
||||
"C-h C-h Show this help\n"
|
||||
"C-h b Display table of all key bindings\n"
|
||||
"C-h c Describe key briefly\n"
|
||||
);
|
||||
eb_puts(b,
|
||||
"QEmacs help for help - Press q to quit:\n"
|
||||
"\n"
|
||||
"C-h C-h Show this help\n"
|
||||
"C-h b Display table of all key bindings\n"
|
||||
"C-h c Describe key briefly\n"
|
||||
);
|
||||
b->flags |= BF_READONLY;
|
||||
show_popup(s, b, "QEmacs help for help - Press q to quit:");
|
||||
}
|
||||
|
|
@ -8952,6 +9060,14 @@ typedef struct QEArgs {
|
|||
char **argv;
|
||||
} QEArgs;
|
||||
|
||||
static CompletionDef charset_completion = {
|
||||
"charset", charset_complete
|
||||
};
|
||||
|
||||
static CompletionDef color_completion = {
|
||||
"color", color_complete
|
||||
};
|
||||
|
||||
/* init function */
|
||||
static void qe_init(void *opaque)
|
||||
{
|
||||
|
|
@ -8998,14 +9114,14 @@ static void qe_init(void *opaque)
|
|||
qe_register_cmd_table(basic_commands, NULL);
|
||||
qe_register_cmd_line_options(cmd_options);
|
||||
|
||||
register_completion("command", command_completion);
|
||||
register_completion("charset", charset_completion);
|
||||
register_completion("mode", mode_completion);
|
||||
register_completion("style", style_completion);
|
||||
register_completion("style-property", style_property_completion);
|
||||
register_completion("file", file_completion);
|
||||
register_completion("buffer", buffer_completion);
|
||||
register_completion("color", color_completion);
|
||||
qe_register_completion(&command_completion);
|
||||
qe_register_completion(&charset_completion);
|
||||
qe_register_completion(&mode_completion);
|
||||
qe_register_completion(&style_completion);
|
||||
qe_register_completion(&style_property_completion);
|
||||
qe_register_completion(&file_completion);
|
||||
qe_register_completion(&buffer_completion);
|
||||
qe_register_completion(&color_completion);
|
||||
|
||||
minibuffer_init();
|
||||
popup_init();
|
||||
|
|
@ -9216,7 +9332,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
while (qs->first_completion) {
|
||||
CompletionEntry *cp = qs->first_completion;
|
||||
CompletionDef *cp = qs->first_completion;
|
||||
qs->first_completion = cp->next;
|
||||
qe_free(&cp);
|
||||
}
|
||||
|
|
|
|||
39
qe.h
39
qe.h
|
|
@ -194,7 +194,7 @@ typedef struct CompleteState {
|
|||
StringArray cs;
|
||||
struct EditState *s;
|
||||
struct EditState *target;
|
||||
int len;
|
||||
int start, end, len;
|
||||
char current[MAX_FILENAME_SIZE];
|
||||
} CompleteState;
|
||||
|
||||
|
|
@ -502,7 +502,7 @@ unsigned int qe_map_color(QEColor color, QEColor const *colors, int count, int *
|
|||
/* Convert a composite color to an RGB triplet */
|
||||
QEColor qe_unmap_color(int color, int count);
|
||||
|
||||
void color_completion(CompleteState *cp);
|
||||
void color_complete(CompleteState *cp);
|
||||
int css_define_color(const char *name, const char *value);
|
||||
int css_get_color(QEColor *color_ptr, const char *p);
|
||||
void css_free_colors(void);
|
||||
|
|
@ -810,7 +810,7 @@ int utf8_decode(const char **pp);
|
|||
char *utf8_char_to_string(char *buf, int c);
|
||||
int utf8_to_unicode(unsigned int *dest, int dest_length, const char *str);
|
||||
|
||||
void charset_completion(CompleteState *cp);
|
||||
void charset_complete(CompleteState *cp);
|
||||
QECharset *find_charset(const char *str);
|
||||
void charset_decode_init(CharsetDecodeState *s, QECharset *charset,
|
||||
EOLType eol_type);
|
||||
|
|
@ -1637,7 +1637,7 @@ struct QEmacsState {
|
|||
struct ModeDef *first_mode;
|
||||
struct KeyDef *first_key;
|
||||
struct CmdDef *first_cmd;
|
||||
struct CompletionEntry *first_completion;
|
||||
struct CompletionDef *first_completion;
|
||||
struct HistoryEntry *first_history;
|
||||
//struct QECharset *first_charset;
|
||||
//struct QETimer *first_timer;
|
||||
|
|
@ -1819,11 +1819,12 @@ typedef struct CmdDef {
|
|||
ModeDef *qe_find_mode(const char *name, int flags);
|
||||
ModeDef *qe_find_mode_filename(const char *filename, int flags);
|
||||
void qe_register_mode(ModeDef *m, int flags);
|
||||
void mode_completion(CompleteState *cp);
|
||||
void mode_complete(CompleteState *cp);
|
||||
void qe_register_cmd_table(CmdDef *cmds, ModeDef *m);
|
||||
int qe_register_binding(int key, const char *cmd_name, ModeDef *m);
|
||||
CmdDef *qe_find_cmd(const char *cmd_name);
|
||||
int qe_get_prototype(CmdDef *d, char *buf, int size);
|
||||
int qe_list_bindings(CmdDef *d, ModeDef *mode, int inherit, char *buf, int size);
|
||||
|
||||
/* text display system */
|
||||
|
||||
|
|
@ -1998,25 +1999,29 @@ void minibuffer_init(void);
|
|||
extern CmdDef minibuffer_commands[];
|
||||
extern CmdDef popup_commands[];
|
||||
|
||||
typedef void (*CompletionFunc)(CompleteState *cp);
|
||||
|
||||
typedef struct CompletionEntry {
|
||||
typedef struct CompletionDef {
|
||||
const char *name;
|
||||
CompletionFunc completion_func;
|
||||
struct CompletionEntry *next;
|
||||
} CompletionEntry;
|
||||
void (*enumerate)(CompleteState *cp);
|
||||
int (*print_entry)(EditState *s, const char *name);
|
||||
int (*get_entry)(EditState *s, char *dest, int size, int offset);
|
||||
int flags;
|
||||
struct CompletionDef *next;
|
||||
} CompletionDef;
|
||||
|
||||
void qe_register_completion(CompletionDef *cp);
|
||||
|
||||
void complete_test(CompleteState *cp, const char *str);
|
||||
|
||||
void register_completion(const char *name, CompletionFunc completion_func);
|
||||
void put_status(EditState *s, const char *fmt, ...) qe__attr_printf(2,3);
|
||||
void put_error(EditState *s, const char *fmt, ...) qe__attr_printf(2,3);
|
||||
void minibuffer_edit(EditState *e, const char *input, const char *prompt,
|
||||
StringArray *hist, const char *completion_name,
|
||||
void (*cb)(void *opaque, char *buf), void *opaque);
|
||||
void command_completion(CompleteState *cp);
|
||||
void file_completion(CompleteState *cp);
|
||||
void buffer_completion(CompleteState *cp);
|
||||
void command_complete(CompleteState *cp);
|
||||
int command_print_entry(EditState *s, const char *name);
|
||||
int command_get_entry(EditState *s, char *dest, int size, int offset);
|
||||
void file_complete(CompleteState *cp);
|
||||
void buffer_complete(CompleteState *cp);
|
||||
|
||||
#ifdef CONFIG_WIN32
|
||||
static inline int is_user_input_pending(void) {
|
||||
|
|
@ -2223,9 +2228,9 @@ void do_set_indent_tabs_mode(EditState *s, int val);
|
|||
void display_window_borders(EditState *e);
|
||||
int find_style_index(const char *name);
|
||||
QEStyleDef *find_style(const char *name);
|
||||
void style_completion(CompleteState *cp);
|
||||
void style_complete(CompleteState *cp);
|
||||
void get_style(EditState *e, QEStyleDef *stp, QETermStyle style);
|
||||
void style_property_completion(CompleteState *cp);
|
||||
void style_property_complete(CompleteState *cp);
|
||||
int find_style_property(const char *name);
|
||||
void do_define_color(EditState *e, const char *name, const char *value);
|
||||
void do_set_style(EditState *e, const char *stylestr,
|
||||
|
|
|
|||
22
qscript.c
22
qscript.c
|
|
@ -112,6 +112,7 @@ static inline void qe_cfg_set_str(QEValue *sp, const char *str, int len) {
|
|||
sp->u.str = qe_malloc_array(char, len + 1);
|
||||
memcpy(sp->u.str, str, len);
|
||||
sp->u.str[len] = '\0';
|
||||
sp->len = len;
|
||||
sp->type = TOK_STRING;
|
||||
}
|
||||
|
||||
|
|
@ -1163,11 +1164,29 @@ void do_save_session(EditState *s, int popup)
|
|||
}
|
||||
#endif
|
||||
|
||||
void script_complete(CompleteState *cp) {
|
||||
command_complete(cp);
|
||||
variable_complete(cp);
|
||||
}
|
||||
|
||||
int script_print_entry(EditState *s, const char *name) {
|
||||
CmdDef *d = qe_find_cmd(name);
|
||||
if (d) {
|
||||
return command_print_entry(s, name);
|
||||
} else {
|
||||
return variable_print_entry(s, name);
|
||||
}
|
||||
}
|
||||
|
||||
static CompletionDef script_completion = {
|
||||
"script", script_complete, script_print_entry, command_get_entry
|
||||
};
|
||||
|
||||
static CmdDef parser_commands[] = {
|
||||
|
||||
CMD2( KEY_META(':'), KEY_NONE,
|
||||
"eval-expression", do_eval_expression, ESsi,
|
||||
"s{Eval: }|expression|ui")
|
||||
"s{Eval: }[.script]|expression|ui")
|
||||
CMD0( KEY_NONE, KEY_NONE,
|
||||
"eval-region", do_eval_region)
|
||||
CMD0( KEY_NONE, KEY_NONE,
|
||||
|
|
@ -1182,6 +1201,7 @@ static CmdDef parser_commands[] = {
|
|||
static int parser_init(void)
|
||||
{
|
||||
qe_register_cmd_table(parser_commands, NULL);
|
||||
qe_register_completion(&script_completion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
tty.c
4
tty.c
|
|
@ -906,7 +906,7 @@ static void comb_cache_describe(QEditScreen *s, EditBuffer *b) {
|
|||
eb_printf(b, "%*s: fg:%d, bg:%d\n", w, "virtual tty colors",
|
||||
ts->tty_fg_colors_count, ts->tty_bg_colors_count);
|
||||
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
eb_printf(b, "Unicode combination cache:\n\n");
|
||||
|
||||
for (ip = ts->comb_cache; *ip != 0; ip += *ip & 0xFFFF) {
|
||||
|
|
@ -919,7 +919,7 @@ static void comb_cache_describe(QEditScreen *s, EditBuffer *b) {
|
|||
for (i = 1; i < (*ip & 0xFFFF); i++) {
|
||||
eb_printf(b, " %04X", ip[i]);
|
||||
}
|
||||
eb_printf(b, "\n");
|
||||
eb_putc(b, '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
util.c
2
util.c
|
|
@ -1811,7 +1811,7 @@ QEColor qe_unmap_color(int color, int count) {
|
|||
return color & 0xFFFFFF;
|
||||
}
|
||||
|
||||
void color_completion(CompleteState *cp)
|
||||
void color_complete(CompleteState *cp)
|
||||
{
|
||||
ColorDef const *def;
|
||||
int count;
|
||||
|
|
|
|||
61
variables.c
61
variables.c
|
|
@ -115,7 +115,7 @@ VarDef *qe_find_variable(const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void qe_complete_variable(CompleteState *cp)
|
||||
void variable_complete(CompleteState *cp)
|
||||
{
|
||||
QEmacsState *qs = cp->s->qe_state;
|
||||
const VarDef *vp;
|
||||
|
|
@ -369,6 +369,7 @@ void qe_list_variables(EditState *s, EditBuffer *b)
|
|||
|
||||
eb_puts(b, "\n variables:\n\n");
|
||||
for (vp = qs->first_variable; vp; vp = vp->next) {
|
||||
/* XXX: merge with variable_print_entry() */
|
||||
switch (vp->type) {
|
||||
case VAR_NUMBER:
|
||||
type = "int";
|
||||
|
|
@ -415,15 +416,67 @@ void qe_save_variables(EditState *s, EditBuffer *b)
|
|||
eb_putc(b, '\n');
|
||||
}
|
||||
|
||||
int variable_print_entry(EditState *s, const char *name)
|
||||
{
|
||||
char buf[256];
|
||||
char typebuf[32];
|
||||
const char *type = typebuf;
|
||||
int len;
|
||||
VarDef *vp = qe_find_variable(name);
|
||||
EditBuffer *b = s->b;
|
||||
|
||||
len = eb_puts(b, name);
|
||||
if (!vp)
|
||||
return len;
|
||||
|
||||
switch (vp->type) {
|
||||
case VAR_NUMBER:
|
||||
type = "int";
|
||||
break;
|
||||
case VAR_STRING:
|
||||
type = "string";
|
||||
break;
|
||||
case VAR_CHARS:
|
||||
snprintf(typebuf, sizeof(typebuf), "char[%d]", vp->size);
|
||||
break;
|
||||
default:
|
||||
type = "var";
|
||||
break;
|
||||
}
|
||||
len += eb_printf(b, " = ");
|
||||
qe_get_variable(s, vp->name, buf, sizeof(buf), NULL, 1);
|
||||
if (*buf == '\"')
|
||||
b->cur_style = QE_STYLE_STRING;
|
||||
else
|
||||
b->cur_style = QE_STYLE_NUMBER;
|
||||
len += eb_puts(b, buf);
|
||||
b->cur_style = QE_STYLE_COMMENT;
|
||||
if (2 + len < 40) {
|
||||
b->tab_width = max(2 + len, b->tab_width);
|
||||
len += eb_putc(b, '\t');
|
||||
} else {
|
||||
b->tab_width = 40;
|
||||
}
|
||||
len += eb_printf(b, " %s%s %s",
|
||||
vp->rw ? "" : "read-only ",
|
||||
var_domain[vp->domain], type);
|
||||
b->cur_style = QE_STYLE_DEFAULT;
|
||||
return len;
|
||||
}
|
||||
|
||||
static CompletionDef variable_completion = {
|
||||
"variable", variable_complete, variable_print_entry, command_get_entry
|
||||
};
|
||||
|
||||
/*---------------- commands ----------------*/
|
||||
|
||||
static CmdDef var_commands[] = {
|
||||
CMD2( KEY_NONE, KEY_NONE,
|
||||
"show-variable", do_show_variable, ESs,
|
||||
"s{Show variable: }[var]|var|")
|
||||
"s{Show variable: }[variable]|variable|")
|
||||
CMD2( KEY_F8, KEY_NONE,
|
||||
"set-variable", do_set_variable, ESss,
|
||||
"s{Set variable: }[var]|var|s{to value: }|value|")
|
||||
"s{Set variable: }[variable]|variable|s{to value: }|value|")
|
||||
|
||||
CMD_DEF_END,
|
||||
};
|
||||
|
|
@ -432,7 +485,7 @@ static int vars_init(void)
|
|||
{
|
||||
qe_register_variables(var_table, countof(var_table));
|
||||
qe_register_cmd_table(var_commands, NULL);
|
||||
register_completion("var", qe_complete_variable);
|
||||
qe_register_completion(&variable_completion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ struct VarDef {
|
|||
|
||||
void qe_register_variables(VarDef *vars, int count);
|
||||
VarDef *qe_find_variable(const char *name);
|
||||
void qe_complete_variable(CompleteState *cp);
|
||||
void variable_complete(CompleteState *cp);
|
||||
int variable_print_entry(EditState *s, const char *name);
|
||||
|
||||
QVarType qe_get_variable(EditState *s, const char *name,
|
||||
char *buf, int size, int *pnum, int as_source);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue