commit dfd1efcc0cf22803275753d2e0b80b9a4ef8b3b0 from: Omar Polo date: Sun Jun 23 21:18:58 2024 UTC minibuffer: redesign enter_minibuffer and fix regression use a struct to pass the arguments to enter_minibuffer since they're so many. While here, also allow to pass a printf(3)-like format string for the prompt and specify the initial input. Also, fix a regression: if we don't set vline.cplen we can't properly handle the input, so do that in enter_minibuffer to avoid having to fix all the callers. commit - 0d82c695b43613c6508e266c083e619188143d6d commit + dfd1efcc0cf22803275753d2e0b80b9a4ef8b3b0 blob - 04250afb914714d4ed340644da020f3da8c3479e blob + 5166bb92007b10bf358f59ffe7e3566e82816bed --- cmd.c +++ cmd.c @@ -429,23 +429,19 @@ cmd_clear_minibuf(struct buffer *buffer) void cmd_execute_extended_command(struct buffer *buffer) { - size_t len; + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = eecmd_select, + .abort = exit_minibuffer, + .history = eecmd_history, + .complfn = compl_eecmd, + .must_select = 1, + }; GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, eecmd_select, exit_minibuffer, - eecmd_history, compl_eecmd, NULL, 1); - - len = sizeof(ministate.prompt); - strlcpy(ministate.prompt, "", len); - - if (thiskey.meta) - strlcat(ministate.prompt, "M-", len); - - strlcat(ministate.prompt, ui_keyname(thiskey.key), len); - - if (thiskey.meta) - strlcat(ministate.prompt, " ", len); + enter_minibuffer(&m, "%s%s%s", thiskey.meta ? "M-" : "", + ui_keyname(thiskey.key), thiskey.meta ? " " : ""); } void @@ -552,33 +548,50 @@ cmd_tab_move_to(struct buffer *buffer) void cmd_tab_select(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = ts_select, + .abort = exit_minibuffer, + .complfn = compl_ts, + .must_select = 1, + }; + GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, ts_select, exit_minibuffer, - NULL, compl_ts, NULL, 1); - strlcpy(ministate.prompt, "Select tab: ", sizeof(ministate.prompt)); + enter_minibuffer(&m, "Select tab: "); } void cmd_load_url(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = lu_select, + .abort = exit_minibuffer, + .history = lu_history, + .complfn = compl_lu, + }; + GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, lu_select, exit_minibuffer, - lu_history, compl_lu, NULL, 0); - strlcpy(ministate.prompt, "Load URL: ", sizeof(ministate.prompt)); + enter_minibuffer(&m, "Load URL: "); } void cmd_load_current_url(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = lu_select, + .abort = exit_minibuffer, + .history = lu_history, + .complfn = compl_lu, + .input = hist_cur(current_tab->hist), + }; + GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, lu_select, exit_minibuffer, - lu_history, compl_lu, NULL, 0); - strlcpy(ministate.prompt, "Load URL: ", sizeof(ministate.prompt)); - strlcpy(ministate.buf, hist_cur(current_tab->hist), sizeof(ministate.buf)); - ministate.buffer.cpoff = utf8_cplen(ministate.buf); + enter_minibuffer(&m, "Load URL: "); } void @@ -591,14 +604,16 @@ cmd_reload_page(struct buffer *buffer) void cmd_bookmark_page(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = bp_select, + .abort = exit_minibuffer, + .input = hist_cur(current_tab->hist), + }; + GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, bp_select, exit_minibuffer, NULL, - NULL, NULL, 0); - strlcpy(ministate.prompt, "Bookmark URL: ", sizeof(ministate.prompt)); - strlcpy(ministate.buf, hist_cur(current_tab->hist), - sizeof(ministate.buf)); - ministate.buffer.cpoff = utf8_cplen(ministate.buf); + enter_minibuffer(&m, "Bookmark URL: "); } void @@ -617,6 +632,14 @@ void cmd_link_select(struct buffer *buffer) { struct line *l; + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = ls_select, + .abort = exit_minibuffer, + .complfn = compl_ls, + .compldata = NULL, + .must_select = 1, + }; GUARD_RECURSIVE_MINIBUFFER(); @@ -629,25 +652,39 @@ cmd_link_select(struct buffer *buffer) return; } - enter_minibuffer(sensible_self_insert, ls_select, exit_minibuffer, - NULL, compl_ls, l, 1); - strlcpy(ministate.prompt, "Select link: ", sizeof(ministate.prompt)); + m.compldata = l; + enter_minibuffer(&m, "Select link: "); } void cmd_swiper(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = swiper_select, + .abort = exit_minibuffer, + .complfn = compl_swiper, + .compldata = TAILQ_FIRST(&buffer->head), + .must_select = 1, + }; + GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, swiper_select, exit_minibuffer, - NULL, compl_swiper, TAILQ_FIRST(&buffer->head), 1); - strlcpy(ministate.prompt, "Select line: ", sizeof(ministate.prompt)); + enter_minibuffer(&m, "Select line: "); } void cmd_toc(struct buffer *buffer) { struct line *l; + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = toc_select, + .abort = exit_minibuffer, + .complfn = compl_toc, + .compldata = NULL, + .must_select = 1, + }; GUARD_RECURSIVE_MINIBUFFER(); @@ -663,10 +700,8 @@ cmd_toc(struct buffer *buffer) return; } - enter_minibuffer(sensible_self_insert, toc_select, exit_minibuffer, - NULL, compl_toc, l, 1); - strlcpy(ministate.prompt, "Select heading: ", - sizeof(ministate.prompt)); + m.compldata = l; + enter_minibuffer(&m, "Select heading: "); } void @@ -1116,12 +1151,17 @@ cmd_up(struct buffer *buffer) void cmd_use_certificate(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = uc_select, + .abort = exit_minibuffer, + .complfn = compl_uc, + .must_select = 1, + }; + GUARD_RECURSIVE_MINIBUFFER(); - enter_minibuffer(sensible_self_insert, uc_select, exit_minibuffer, - NULL, compl_uc, NULL, 1); - strlcpy(ministate.prompt, "Select certificate: ", - sizeof(ministate.prompt)); + enter_minibuffer(&m, "Select certificate: "); } void @@ -1167,6 +1207,12 @@ cmd_unload_certificate(struct buffer *buffer) void cmd_search(struct buffer *buffer) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = search_select, + .abort = exit_minibuffer, + }; + GUARD_RECURSIVE_MINIBUFFER(); if (!strncmp(default_search_engine, "gopher://", 9)) { @@ -1175,9 +1221,7 @@ cmd_search(struct buffer *buffer) return; } - enter_minibuffer(sensible_self_insert, search_select, exit_minibuffer, NULL, - NULL, NULL, 0); - strlcpy(ministate.prompt, "Search: ", sizeof(ministate.prompt)); + enter_minibuffer(&m, "Search: "); } void blob - d9af26cdb424daf1902c40e14b41286b33ac513c blob + aa66579f5a6e60003957fce42c917fd2e491c48a --- minibuffer.c +++ minibuffer.c @@ -567,35 +567,49 @@ populate_compl_buffer(complfn *fn, void *data) } void -enter_minibuffer(void (*self_insert_fn)(void), void (*donefn)(const char *), - void (*abortfn)(void), struct hist *hist, - complfn *complfn, void *compldata, int must_select) +enter_minibuffer(struct minibuffer *minibuffer, const char *fmt, ...) { - ministate.compl.must_select = must_select; - ministate.compl.fn = complfn; - ministate.compl.data = compldata; + va_list ap; - in_minibuffer = complfn == NULL ? MB_READ : MB_COMPREAD; + va_start(ap, fmt); + vsnprintf(ministate.prompt, sizeof(ministate.prompt), fmt, ap); + va_end(ap); + + ministate.compl.must_select = minibuffer->must_select; + ministate.compl.fn = minibuffer->complfn; + ministate.compl.data = minibuffer->compldata; + + in_minibuffer = minibuffer->complfn == NULL ? MB_READ : MB_COMPREAD; if (in_minibuffer == MB_COMPREAD) { - populate_compl_buffer(complfn, compldata); + populate_compl_buffer(minibuffer->complfn, + minibuffer->compldata); ui_schedule_redraw(); } base_map = &minibuffer_map; current_map = &minibuffer_map; - base_map->unhandled_input = self_insert_fn; + base_map->unhandled_input = minibuffer->self_insert; - ministate.donefn = donefn; - ministate.abortfn = abortfn; - memset(ministate.buf, 0, sizeof(ministate.buf)); + ministate.donefn = minibuffer->done; + ministate.abortfn = minibuffer->abort; + + ministate.buffer.cpoff = 0; + if (minibuffer->input) { + strlcpy(ministate.buf, minibuffer->input, + sizeof(ministate.buf)); + ministate.vline.cplen = utf8_cplen(ministate.buf); + ministate.buffer.cpoff = ministate.vline.cplen; + } else { + ministate.buf[0] = '\0'; + ministate.vline.cplen = ministate.buffer.cpoff = 0; + } + ministate.buffer.current_line = &ministate.vline; ministate.buffer.current_line->parent->line = ministate.buf; - ministate.buffer.cpoff = 0; - strlcpy(ministate.buf, "", sizeof(ministate.prompt)); ministate.editing = 1; - ministate.hist = hist; + ministate.hist = minibuffer->history; if (ministate.hist) hist_seek_start(ministate.hist); } @@ -616,7 +630,10 @@ exit_minibuffer(void) void yornp(const char *prompt, void (*fn)(int, void*), void *data) { - size_t len; + struct minibuffer m = { + .self_insert = yornp_self_insert, + .abort = yornp_abort, + }; if (in_minibuffer) { fn(0, data); @@ -625,27 +642,26 @@ yornp(const char *prompt, void (*fn)(int, void*), void yornp_cb = fn; yornp_data = data; - enter_minibuffer(yornp_self_insert, NULL, - yornp_abort, NULL, NULL, NULL, 0); - - len = sizeof(ministate.prompt); - strlcpy(ministate.prompt, prompt, len); - strlcat(ministate.prompt, " (y or n) ", len); + enter_minibuffer(&m, "%s (y or n)", prompt); } void minibuffer_read(const char *prompt, void (*fn)(const char *, struct tab *), struct tab *data) { + struct minibuffer m = { + .self_insert = read_self_insert, + .done = read_select, + .abort = read_abort, + .history = read_history, + }; + if (in_minibuffer) return; read_cb = fn; read_data = data; - enter_minibuffer(read_self_insert, read_select, read_abort, - read_history, NULL, NULL, 0); - - snprintf(ministate.prompt, sizeof(ministate.prompt), "%s: ", prompt); + enter_minibuffer(&m, "%s: ", prompt); } static void blob - 3fbe22ac1c77f2531259668025199b8cb445025c blob + 04aeaaa88d5ea7084fa21ef8f7debb4a59195fb9 --- minibuffer.h +++ minibuffer.h @@ -88,9 +88,19 @@ void toc_select(const char *); void uc_select(const char *); void search_select(const char *); -void enter_minibuffer(void(*)(void), void(*)(const char *), void(*)(void), - struct hist *, complfn *, void *, int); +struct minibuffer { + void (*self_insert)(void); + void (*done)(const char *); + void (*abort)(void); + struct hist *history; + complfn *complfn; + void *compldata; + int must_select; + const char *input; +}; +void enter_minibuffer(struct minibuffer *, const char *, ...); + void exit_minibuffer(void); void yornp(const char *, void (*)(int, void *), void *); blob - 3d80b3f3f90db230627a5809a6ffa98ec5f41a27 blob + 941159cefca7f3fa6b04a98b83403efecdcbd827 --- ui.c +++ ui.c @@ -1341,13 +1341,17 @@ ui_schedule_redraw(void) void ui_require_input(struct tab *tab, int hide, void (*fn)(const char *)) { + struct minibuffer m = { + .self_insert = sensible_self_insert, + .done = fn, + .abort = exit_minibuffer, + .history = ir_history, + }; + /* TODO: hard-switching to another tab is ugly */ switch_to_tab(tab); - enter_minibuffer(sensible_self_insert, fn, exit_minibuffer, - ir_history, NULL, NULL, 0); - strlcpy(ministate.prompt, "Input required: ", - sizeof(ministate.prompt)); + enter_minibuffer(&m, "Input required: "); redraw_tab(tab); }