From e89e07e318edb2750f3e46a38c93ea7dbda72884 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Mon, 18 May 2026 12:26:57 +0200 Subject: [PATCH] bufed/dired: fix layout for non printing characters * add `eb_put_filename()` to encode buffer or file names with non-ASCII characters according to PF_xxx flags * add `CF_SAVE_LIST` flag for completions to store the list of matches in `MinibufState` * fix bufed and dired layout issues * fix buffer and filename completion popup layout * add commands to control display of Unicode and non printing charcaters in buffer or file names: - U toggles unicode display - \ cycles through 4 possible encodings: ? ^J \x10 \010 * use `(*fp)()` syntax for indirect function calls --- charset.c | 4 +- extras.c | 23 ++---------- input.c | 2 +- modes/bufed.c | 72 ++++++++++++++++++++++++++++++----- modes/dired.c | 94 +++++++++++++++++++++++++++++++++++++++++----- modes/image.c | 2 +- modes/latex-mode.c | 2 +- qe.c | 73 ++++++++++++++++------------------- qe.h | 10 +++++ search.c | 6 +-- variables.c | 2 +- 11 files changed, 203 insertions(+), 87 deletions(-) diff --git a/charset.c b/charset.c index 45e2072..f7d5921 100644 --- a/charset.c +++ b/charset.c @@ -992,13 +992,13 @@ void charset_complete(CompleteState *cp, CompleteFunc enumerate) { const char *p, *q; for (charset = first_charset; charset != NULL; charset = charset->next) { - enumerate(cp, charset->name, CT_STRX); + (*enumerate)(cp, charset->name, CT_STRX); if (charset->aliases) { for (q = p = charset->aliases;; q++) { if (*q == '\0' || *q == '|') { if (q > p) { pstrncpy(name, sizeof(name), p, q - p); - enumerate(cp, name, CT_STRX); + (*enumerate)(cp, name, CT_STRX); } if (*q == '\0') break; diff --git a/extras.c b/extras.c index cd75cf9..e5b593b 100644 --- a/extras.c +++ b/extras.c @@ -2349,7 +2349,7 @@ static void tag_complete(CompleteState *cp, CompleteFunc enumerate) { for (p = cp->target->b->property_list; p; p = p->next) { if (p->type == QE_PROP_TAG) { - enumerate(cp, p->data, CT_GLOB); + (*enumerate)(cp, p->data, CT_GLOB); } } } @@ -2374,21 +2374,6 @@ static int tag_print_entry(CompleteState *cp, EditState *s, const char *name) { return eb_puts(s->b, name); } -static int tag_get_entry(EditState *s, char *dest, int size, int offset) -{ - int len = eb_fgets(s->b, dest, size, offset, &offset); - int p2 = strcspn(dest, "=[{(,;"); - int p1; - while (p2 > 0 && !qe_isalnum_(dest[p2 - 1])) - p2--; - p1 = p2; - while (p1 > 0 && (qe_isalnum_(dest[p1 - 1]) || dest[p1 - 1] == '-')) - p1--; - memmove(dest, dest + p1, len = p2 - p1); - dest[len] = '\0'; /* strip the prototype or trailing newline if any */ - return len; -} - static void do_find_tag(EditState *s, const char *str) { QEmacsState *qs = s->qs; QEProperty *p; @@ -2469,7 +2454,7 @@ static CompletionDef tag_completion = { .name = "tag", .enumerate = tag_complete, .print_entry = tag_print_entry, - .get_entry = tag_get_entry, + .flags = CF_SAVE_LIST, }; /*---------------- Unicode character name completion ----------------*/ @@ -2497,7 +2482,7 @@ static void charname_complete(CompleteState *cp, CompleteFunc enumerate) { if (p3) *p3 = '\0'; snprintf(entry, sizeof entry, "%s\t%5.6s", p1, buf); - enumerate(cp, entry, CT_IGLOB); + (*enumerate)(cp, entry, CT_IGLOB); } } fclose(fp); @@ -2513,7 +2498,7 @@ static void charname_complete(CompleteState *cp, CompleteFunc enumerate) { *p1++ = '\0'; *p2 = '\0'; snprintf(entry, sizeof entry, "%s\t%5.6s", p1, buf); - enumerate(cp, entry, CT_IGLOB); + (*enumerate)(cp, entry, CT_IGLOB); } } fclose(fp); diff --git a/input.c b/input.c index 13fb862..b2990a1 100644 --- a/input.c +++ b/input.c @@ -88,7 +88,7 @@ static void input_complete(CompleteState *cp, CompleteFunc enumerate) { InputMethod *m; for (m = qs->input_methods; m != NULL; m = m->next) { - enumerate(cp, m->name, CT_IGLOB); + (*enumerate)(cp, m->name, CT_IGLOB); } } diff --git a/modes/bufed.c b/modes/bufed.c index d1d2ab7..49c2abc 100644 --- a/modes/bufed.c +++ b/modes/bufed.c @@ -35,6 +35,7 @@ enum { }; static int bufed_sort_order; // XXX: should be a variable +static int bufed_pf_flags; enum { BUFED_HIDE_SYSTEM = 0, @@ -56,6 +57,7 @@ typedef struct BufedState { int flags; int last_index; int sort_mode; + int pf_flags; EditState *cur_window; EditBuffer *cur_buffer; EditBuffer *last_buffer; @@ -146,6 +148,7 @@ static void build_bufed_list(EditState *s, BufedState *bs) } } bs->sort_mode = bufed_sort_order; + bs->pf_flags = bufed_pf_flags; if (bufed_sort_order) { qe_qsort_r(bs->items.items, bs->items.nb_items, @@ -164,6 +167,7 @@ static void build_bufed_list(EditState *s, BufedState *bs) eb_clear(b); line = 0; + b->tab_width = 20; for (i = 0; i < bs->items.nb_items; i++) { char flags[4]; char *flagp = flags; @@ -193,15 +197,9 @@ static void build_bufed_list(EditState *s, BufedState *bs) b->cur_style = style0; eb_printf(b, " %-2s", flags); b->cur_style = BUFED_STYLE_BUFNAME; - len = strlen(item->str); - /* simplistic column fitting, does not work for wide characters */ -#define COLWIDTH 20 - if (len > COLWIDTH) { - eb_printf(b, "%.*s...%s", - COLWIDTH - 5 - 3, item->str, item->str + len - 5); - } else { - eb_printf(b, "%-*s", COLWIDTH, item->str); - } + len = eb_put_filename(b, item->str, bufed_pf_flags); + eb_putc(b, '\t'); + b->tab_width = max_int(3 + len + 1, b->tab_width); if (b1) { char path[MAX_FILENAME_SIZE]; char mode_buf[64]; @@ -248,7 +246,7 @@ static void build_bufed_list(EditState *s, BufedState *bs) } else { make_user_path(path, sizeof(path), b1->filename); } - eb_puts(b, path); + eb_put_filename(b, path, bs->pf_flags); b->cur_style = style0; } eb_putc(b, '\n'); @@ -500,6 +498,31 @@ static void bufed_set_sort(EditState *s, int order) build_bufed_list(s, bs); } +static void bufed_cycle_encoding(EditState *s) +{ + BufedState *bs; + int encoding = bufed_pf_flags & PF_ENCODING; + bufed_pf_flags &= ~PF_ENCODING; + bufed_pf_flags |= (encoding + 1) & PF_ENCODING; + + if (!(bs = bufed_get_state(s, 1))) + return; + + build_bufed_list(s, bs); +} + +static void bufed_toggle_unicode(EditState *s) +{ + BufedState *bs; + + bufed_pf_flags ^= PF_NO_UNICODE; + + if (!(bs = bufed_get_state(s, 1))) + return; + + build_bufed_list(s, bs); +} + static void bufed_display_hook(EditState *s) { /* Prevent point from going beyond list */ @@ -578,6 +601,12 @@ static const CmdDef bufed_commands[] = { CMD1( "bufed-sort-modified", "m", "Sort the buffer list with modified buffers first", bufed_set_sort, BUFED_SORT_MODIFIED) + CMD0( "bufed-cycle-encoding", "\\", + "Cycle display of non printing characters in filenames", + bufed_cycle_encoding) + CMD0( "bufed-toggle-unicode", "U", + "Toggle display of Unicode characters in filenames", + bufed_toggle_unicode) CMD2( "bufed-summary", "?", "Display a summary of bufed commands", do_apropos, ESs, "@{bufed}") @@ -617,4 +646,27 @@ static int bufed_init(QEmacsState *qs) return 0; } +int buffer_print_entry(CompleteState *cp, EditState *s, const char *name) +{ + EditBuffer *b = s->b; + QEmacsState *qs = s->qs; + EditBuffer *b1 = qe_find_buffer_name(qs, name); + int len; + + if (b1) { + b->cur_style = QE_STYLE_KEYWORD; + len = eb_put_filename(b, b1->name, bufed_pf_flags); + b->tab_width = max3_int(16, len + 2, b->tab_width); + len += eb_putc(b, '\t'); + if (*b1->filename) { + b->cur_style = QE_STYLE_COMMENT; + len += eb_put_filename(b, b1->filename, bufed_pf_flags); + } + b->cur_style = QE_STYLE_DEFAULT; + } else { + return eb_put_filename(b, name, bufed_pf_flags); + } + return len; +} + qe_module_init(bufed_init); diff --git a/modes/dired.c b/modes/dired.c index e8f97cb..d9a2841 100644 --- a/modes/dired.c +++ b/modes/dired.c @@ -77,7 +77,7 @@ struct DiredState { enum time_format time_format; int show_dot_files; int show_ds_store; - int hflag, nflag; + int hflag, nflag, pf_flags; int details_flag, last_details_flag; int sort_mode; DiredItem *last_cur; @@ -137,6 +137,7 @@ static int dired_hflag = 0; /* 0=exact, 1=human-decimal, 2=human-binary */ #define DIRED_DETAILS_HIDE 1 #define DIRED_DETAILS_SHOW 2 static int dired_sort_mode = DIRED_SORT_GROUP | DIRED_SORT_FULLNAME; +static int dired_pf_flags; // XXX: could use a regexp and make it extendable static const char *dired_ignore_extensions = { "|bak" @@ -355,6 +356,60 @@ static int dired_sort_func(void *opaque, const void *p1, const void *p2) return (sort_mode & DIRED_SORT_DESCENDING) ? -res : res; } +int eb_put_filename(EditBuffer *b, const char *name, int flags) { + // write a filename to a buffer, encoding special characters according + // to flags + int len = 0; + char buf[8]; + u8 cc; + while ((cc = *name++) != '\0') { + if (cc > 0x7F && !(flags & PF_NO_UNICODE)) { + const char *p = name - 1; + char32_t c = utf8_decode(&p); + if (c >= 128 && c <= 0x10FFFF) { + int nc = utf8_encode(buf, c); + if (nc == p - name + 1 && !memcmp(buf, name - 1, nc)) { + // valid UTF-8 encoded codepoint + buf[nc] = '\0'; + eb_puts(b, buf); + len += qe_wcwidth(c); + name = p; + continue; + } + } + } + if (cc < ' ' || cc >= 0x7F) { + switch (flags & PF_ENCODING) { + case PF_QUESTION: + eb_putc(b, '?'); + len += 1; + break; + case PF_OCTAL: + eb_printf(b, "\\%03o", cc); + len += 4; + break; + case PF_HEX: + eb_printf(b, "\\x%02X", cc); + len += 4; + break; + case PF_CARET: + if (cc < 32 || cc == 127) { + eb_printf(b, "\\^%c", (cc + '@') & 127); + len += 3; + break; + } + eb_printf(b, "\\x%02X", cc); + len += 4; + break; + } + } else { + eb_putc(b, cc); + len += 1; + } + } + return len; +} + static int format_number(char *buf, int size, int human, off_t number) { if (human == 0) { @@ -675,6 +730,7 @@ static void dired_compute_columns(DiredState *ds) ds->time_format = dired_time_format; ds->hflag = dired_hflag; ds->nflag = dired_nflag; + ds->pf_flags = dired_pf_flags; ds->blockslen = ds->modelen = ds->linklen = 0; ds->uidlen = ds->gidlen = 0; ds->sizelen = ds->datelen = ds->namelen = 0; @@ -821,6 +877,7 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s, if (ds->time_format != dired_time_format || ds->nflag != dired_nflag || ds->hflag != dired_hflag + || ds->pf_flags != dired_pf_flags || ds->details_flag != ds->last_details_flag) { flags |= DIRED_UPDATE_COLUMNS; } @@ -870,7 +927,7 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s, b->cur_style = DIRED_STYLE_HEADER; eb_puts(b, " Directory of "); b->cur_style = DIRED_STYLE_DIRECTORY; - eb_puts(b, ds->path); + eb_put_filename(b, ds->path, ds->pf_flags); b->cur_style = DIRED_STYLE_HEADER; eb_puts(b, "\n "); if (ds->ndirs) { @@ -939,7 +996,7 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s, else b->cur_style = DIRED_STYLE_FILENAME; - eb_puts(b, fname); + eb_put_filename(b, fname, ds->pf_flags); if (*fname != '/' || fname[1]) { int trailchar = get_trailchar(dip->mode); @@ -949,7 +1006,8 @@ static void dired_update_buffer(DiredState *ds, EditBuffer *b, EditState *s, } if (S_ISLNK(dip->mode) && getentryslink(buf, sizeof(buf), dip->fullname)) { - eb_printf(b, " -> %s", buf); + eb_puts(b, " -> "); + eb_put_filename(b, buf, ds->pf_flags); } b->cur_style = DIRED_STYLE_NORMAL; eb_putc(b, '\n'); @@ -1023,7 +1081,7 @@ static void sortkey_complete(CompleteState *cp, CompleteFunc enumerate) { current[len + 1] = '\0'; for (p = "fnesdug+-r"; *p; p++) { current[len] = *p; - enumerate(cp, current, CT_GLOB); + (*enumerate)(cp, current, CT_GLOB); } } } @@ -1064,7 +1122,7 @@ static int sortkey_print_entry(CompleteState *cp, EditState *s, const char *name msg = "sort by descending"; break; } - return eb_printf(s->b, "%c %s", c, msg); + return eb_printf(s->b, "%c\t%s", c, msg); } return 0; } @@ -1493,6 +1551,18 @@ static void dired_toggle_nflag(EditState *s) dired_nflag = (dired_nflag + 1) % 3; } +static void dired_cycle_encoding(EditState *s) +{ + int encoding = dired_pf_flags & PF_ENCODING; + dired_pf_flags &= ~PF_ENCODING; + dired_pf_flags |= (encoding + 1) & PF_ENCODING; +} + +static void dired_toggle_unicode(EditState *s) +{ + dired_pf_flags ^= PF_NO_UNICODE; +} + static void dired_hide_details_mode(EditState *s) { DiredState *ds; @@ -1867,6 +1937,12 @@ static const CmdDef dired_commands[] = { CMD0( "dired-hide-details-mode", "(", "Toggle visibility of detailed information in current Dired buffer)", dired_hide_details_mode) + CMD0( "dired-cycle-encoding", "\\", + "Cycle display of non printing characters in filenames", + dired_cycle_encoding) + CMD0( "dired-toggle-unicode", "U", + "Toggle display of Unicode characters in filenames", + dired_toggle_unicode) CMD2( "dired-summary", "?", "Display a summary of dired commands", do_apropos, ESs, "@{dired}") @@ -1943,8 +2019,8 @@ int file_print_entry(CompleteState *cp, EditState *s, const char *name) { if (!stat(name, &st)) { b->cur_style = S_ISDIR(st.st_mode) ? DIRED_STYLE_DIRECTORY : DIRED_STYLE_FILENAME; - len = eb_puts(b, name); - b->tab_width = max3_int(16, 2 + len, b->tab_width); + len = eb_put_filename(b, name, dired_pf_flags); + b->tab_width = max3_int(16, len + 2, b->tab_width); b->cur_style = DIRED_STYLE_NORMAL; format_size(buf, sizeof(buf), dired_hflag, st.st_mode, st.st_dev, st.st_size); len += eb_printf(b, "\t%*s", sizelen, buf); @@ -1957,7 +2033,7 @@ int file_print_entry(CompleteState *cp, EditState *s, const char *name) { len += eb_printf(b, " %-*s", gidlen, buf); len += eb_printf(b, " %*d", linklen, (int)st.st_nlink); } else { - return eb_puts(b, name); + len = eb_put_filename(b, name, dired_pf_flags); } return len; } diff --git a/modes/image.c b/modes/image.c index 853071f..d0680de 100644 --- a/modes/image.c +++ b/modes/image.c @@ -856,7 +856,7 @@ static void pixel_format_complete(CompleteState *cp, CompleteFunc enumerate) { for (i = 0; i < PIX_FMT_NB; i++) { name = avcodec_get_pix_fmt_name(i); - enumerate(cp, name, CT_IGLOB); + (*enumerate)(cp, name, CT_IGLOB); } } diff --git a/modes/latex-mode.c b/modes/latex-mode.c index 5aa64a7..451d5d6 100644 --- a/modes/latex-mode.c +++ b/modes/latex-mode.c @@ -220,7 +220,7 @@ static void latex_complete(CompleteState *cp, CompleteFunc enumerate) { struct latex_function *func; for (func = latex_funcs; func->name; func++) { - enumerate(cp, func->name, CT_STRX); + (*enumerate)(cp, func->name, CT_STRX); } } diff --git a/qe.c b/qe.c index 35d4f8c..2b67fdc 100644 --- a/qe.c +++ b/qe.c @@ -220,9 +220,9 @@ void mode_complete(CompleteState *cp, CompleteFunc enumerate) { ModeDef *m; for (m = qs->first_mode; m != NULL; m = m->next) { - enumerate(cp, m->name, CT_GLOB); + (*enumerate)(cp, m->name, CT_GLOB); if (m->alt_name && !strequal(m->name, m->alt_name)) - enumerate(cp, m->alt_name, CT_GLOB); + (*enumerate)(cp, m->alt_name, CT_GLOB); } } @@ -254,7 +254,7 @@ void command_complete(CompleteState *cp, CompleteFunc enumerate) { for (i = 0; i < qs->cmd_array_count; i++) { for (j = qs->cmd_array[i].count, d = qs->cmd_array[i].array; j-- > 0; d++) { - enumerate(cp, d->name, CT_GLOB); + (*enumerate)(cp, d->name, CT_GLOB); } } } @@ -718,23 +718,23 @@ static void color_complete(CompleteState *cp, CompleteFunc enumerate) { rgb <<= shift; for (i = 0; i < (0x1 << shift); i++) { snprintf(buf, sizeof buf, "#%06x", rgb + i); - enumerate(cp, buf, CT_GLOB); + (*enumerate)(cp, buf, CT_GLOB); } } else { for (i = 0; i < 8192; i++) { QEColor rgb = qe_unmap_color(i, 8192); snprintf(buf, sizeof buf, "#%06x", rgb & 0xFFFFFF); - enumerate(cp, buf, CT_GLOB); + (*enumerate)(cp, buf, CT_GLOB); } } } else #if 0 if (name[0] == 'g' && name[1] == 'r' && (name[2] == 'a' || name[2] == 'e') && name[3] == 'y') { snprintf(buf, sizeof buf, "%.4s", name); - enumerate(cp, buf, CT_GLOB); + (*enumerate)(cp, buf, CT_GLOB); for (i = 0; i < 100; i++) { snprintf(buf + 4, sizeof(buf) - 4, "%d", i); - enumerate(cp, buf, CT_GLOB); + (*enumerate)(cp, buf, CT_GLOB); } } else #endif @@ -742,14 +742,14 @@ static void color_complete(CompleteState *cp, CompleteFunc enumerate) { ColorDef const *def = qe_colors; int count = nb_qe_colors; while (count > 0) { - enumerate(cp, def->name, CT_STRX); + (*enumerate)(cp, def->name, CT_STRX); def++; count--; } if (name[0] == 'p' && !qe_isalpha(name[1])) { for (i = 0; i < 8192; i++) { snprintf(buf, sizeof buf, "p%d", i); - enumerate(cp, buf, CT_GLOB); + (*enumerate)(cp, buf, CT_GLOB); } } } @@ -3613,7 +3613,7 @@ void style_complete(CompleteState *cp, CompleteFunc enumerate) { stp = qe_styles; for (i = 0; i < QE_STYLE_NB; i++, stp++) { - enumerate(cp, stp->name, CT_GLOB); + (*enumerate)(cp, stp->name, CT_GLOB); } } @@ -3675,7 +3675,7 @@ void style_property_complete(CompleteState *cp, CompleteFunc enumerate) { int i; for (i = 0; i < countof(qe_style_properties); i++) { - enumerate(cp, qe_style_properties[i], CT_STRX); + (*enumerate)(cp, qe_style_properties[i], CT_STRX); } } @@ -7315,7 +7315,7 @@ void file_complete(CompleteState *cp, CompleteFunc enumerate) * should check and ignore binary executable files. */ } - enumerate(cp, filename, CT_SET); + (*enumerate)(cp, filename, CT_SET); } find_file_close(&ffst); } @@ -7326,7 +7326,7 @@ static CompletionDef file_completion = { #ifndef CONFIG_TINY .print_entry = file_print_entry, #endif - .flags = CF_FILENAME, + .flags = CF_FILENAME | CF_SAVE_LIST, }; #ifndef CONFIG_TINY @@ -7334,14 +7334,14 @@ static CompletionDef dir_completion = { .name = "dir", .enumerate = file_complete, .print_entry = file_print_entry, - .flags = CF_DIRNAME | CF_NO_FUZZY, + .flags = CF_DIRNAME | CF_NO_FUZZY | CF_SAVE_LIST, }; static CompletionDef resource_completion = { .name = "resource", .enumerate = file_complete, .print_entry = file_print_entry, - .flags = CF_RESOURCE | CF_NO_FUZZY, + .flags = CF_RESOURCE | CF_NO_FUZZY | CF_SAVE_LIST, }; #endif @@ -7351,37 +7351,17 @@ void buffer_complete(CompleteState *cp, CompleteFunc enumerate) { for (b = qs->first_buffer; b != NULL; b = b->next) { if (!(b->flags & BF_SYSTEM)) - enumerate(cp, b->name, CT_GLOB); + (*enumerate)(cp, b->name, CT_GLOB); } } -static int buffer_print_entry(CompleteState *cp, EditState *s, const char *name) -{ - EditBuffer *b = s->b; - QEmacsState *qs = s->qs; - EditBuffer *b1 = qe_find_buffer_name(qs, name); - int len; - - if (b1) { - b->cur_style = QE_STYLE_KEYWORD; - len = eb_puts(b, b1->name); - b->tab_width = max3_int(16, 2 + len, b->tab_width); - len += eb_putc(b, '\t'); - if (*b1->filename) { - b->cur_style = QE_STYLE_COMMENT; - len += eb_puts(b, b1->filename); - } - b->cur_style = QE_STYLE_DEFAULT; - } else { - return eb_puts(b, name); - } - return len; -} - static CompletionDef buffer_completion = { .name = "buffer", .enumerate = buffer_complete, +#ifndef CONFIG_TINY .print_entry = buffer_print_entry, +#endif + .flags = CF_SAVE_LIST, }; static int default_completion_window_print_entry(CompleteState *cp, EditState *s, const char *name) { @@ -7511,6 +7491,7 @@ typedef struct MinibufState { int completion_end; int completion_count; CompletionDef *completion; + StringArray completion_list; StringArray *history; int history_index; @@ -7697,6 +7678,11 @@ void do_minibuffer_complete(EditState *s, int type, int key, int argval) { e->mouse_force_highlight = 1; e->force_highlight = 1; e->offset = 0; + free_strings(&mb->completion_list); + if (mb->completion->flags & CF_SAVE_LIST) { + mb->completion_list = cs.cs; + memset(&cs.cs, 0, sizeof(cs.cs)); + } } complete_end(&cs); } @@ -7929,8 +7915,14 @@ 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 index = list_get_pos(cw); int len; - len = mb->completion->get_entry(cw, buf, sizeof(buf), list_get_offset(cw) + 1); + if (index < mb->completion_list.nb_items) { + pstrcpy(buf, sizeof(buf), mb->completion_list.items[index]->str); + len = strlen(buf); + } else { + len = mb->completion->get_entry(cw, buf, sizeof(buf), list_get_offset(cw) + 1); + } if (len > 0) { // insert completion string (delete highlighted part) minibuffer_set_str(s, mb->completion_start, mb->completion_end, buf); @@ -7958,6 +7950,7 @@ void do_minibuffer_exit(EditState *s, int do_abort) if (cw) { edit_close(&mb->completion_popup_window); cw = NULL; + free_strings(&mb->completion_list); do_refresh(s); } diff --git a/qe.h b/qe.h index 0062a03..afcf17f 100644 --- a/qe.h +++ b/qe.h @@ -1430,6 +1430,7 @@ typedef struct CompletionDef { #define CF_NO_AUTO_SUBMIT 8 #define CF_DIRNAME 16 #define CF_RESOURCE 32 +#define CF_SAVE_LIST 64 int flags; /* custom handlers to start and end minibuffer edit session */ void (*start_edit)(EditState *s); @@ -1457,6 +1458,7 @@ int command_get_entry(EditState *s, char *dest, int size, int offset); void file_complete(CompleteState *cp, CompleteFunc enumerate); int file_print_entry(CompleteState *cp, EditState *s, const char *name); void buffer_complete(CompleteState *cp, CompleteFunc enumerate); +int buffer_print_entry(CompleteState *cp, EditState *s, const char *name); #ifdef CONFIG_WIN32 static inline int is_user_input_pending(void) { @@ -1898,6 +1900,14 @@ int list_get_offset(EditState *s); /* dired.c */ +#define PF_QUESTION 0 +#define PF_CARET 1 +#define PF_HEX 2 +#define PF_OCTAL 3 +#define PF_ENCODING 3 +#define PF_NO_UNICODE 8 +int eb_put_filename(EditBuffer *b, const char *name, int flags); + void do_dired(EditState *s, int argval); void do_dired_path(EditState *s, const char *path); void do_filelist(EditState *s, int argval); diff --git a/search.c b/search.c index 1a367a2..951c8bc 100644 --- a/search.c +++ b/search.c @@ -154,7 +154,7 @@ static int eb_search(EditBuffer *b, int dir, int flags, } if ((offset & 0xfffff) == 0) { /* check for search abort every megabyte */ - if (abort_func && abort_func(abort_opaque)) + if (abort_func && (*abort_func)(abort_opaque)) return -1; } @@ -225,7 +225,7 @@ static int eb_search(EditBuffer *b, int dir, int flags, } if ((offset & 0xffff) == 0) { /* check for search abort every 64K */ - if (abort_func && abort_func(abort_opaque)) { + if (abort_func && (*abort_func)(abort_opaque)) { res = -1; break; } @@ -275,7 +275,7 @@ static int eb_search(EditBuffer *b, int dir, int flags, } if ((offset & 0xfffff) == 0) { /* check for search abort every megabyte */ - if (abort_func && abort_func(abort_opaque)) + if (abort_func && (*abort_func)(abort_opaque)) return -1; } diff --git a/variables.c b/variables.c index 3c06328..e5a6e8d 100644 --- a/variables.c +++ b/variables.c @@ -186,7 +186,7 @@ void variable_complete(CompleteState *cp, CompleteFunc enumerate) { const VarDef *vp; for (vp = qs->first_variable; vp; vp = vp->next) { - enumerate(cp, vp->name, CT_STRX); + (*enumerate)(cp, vp->name, CT_STRX); } }