diff options
| author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2025-12-23 13:54:17 +0100 |
|---|---|---|
| committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2025-12-23 13:54:17 +0100 |
| commit | 0c89fb700957e411885e7e7835e15f441e8b5e84 (patch) | |
| tree | 56d756d6fa1923a5198504a322ec9c67cf274922 /src/interface-curses | |
| parent | 2592ef74ab2eba57c32fe21993ce01e9698b106f (diff) | |
fixed clicking the "(Unnamed)" buffer in 0EB popupsHEADmaster-fmsbw-cimaster
* When constructing the list of popup items, the unnamed buffer is stored as the empty string
instead of a prerendered "(Unnamed)".
Using the empty string simplifies autocompletions, which will actually have to insert nothing
at all (in addition to terminating the string).
* Since unnamed buffers are now special in the popup list, we can render them with special
icons as well.
Currently, only on Curses we use a file symbol with a question mark.
There doesn't appear to be a fitting standard Freedesktop icon to use on GTK and there
isn't even any fitting standard emblem to lay over the default file icon.
Diffstat (limited to 'src/interface-curses')
| -rw-r--r-- | src/interface-curses/curses-icons.c | 4 | ||||
| -rw-r--r-- | src/interface-curses/curses-info-popup.c | 20 | ||||
| -rw-r--r-- | src/interface-curses/curses-utils.h | 3 | ||||
| -rw-r--r-- | src/interface-curses/interface.c | 38 |
4 files changed, 40 insertions, 25 deletions
diff --git a/src/interface-curses/curses-icons.c b/src/interface-curses/curses-icons.c index 7c021d6..d932104 100644 --- a/src/interface-curses/curses-icons.c +++ b/src/interface-curses/curses-icons.c @@ -362,6 +362,10 @@ teco_curses_icon_cmp(const void *a, const void *b) gunichar teco_curses_icons_lookup_file(const gchar *filename) { + if (!filename || !*filename) + /* "(Unnamed)" file */ + return 0xf1036; /* */ + g_autofree gchar *basename = g_path_get_basename(filename); const teco_curses_icon_t *icon; diff --git a/src/interface-curses/curses-info-popup.c b/src/interface-curses/curses-info-popup.c index c51a99b..8da6fbb 100644 --- a/src/interface-curses/curses-info-popup.c +++ b/src/interface-curses/curses-info-popup.c @@ -19,6 +19,8 @@ #include "config.h" #endif +#include <string.h> + #include <glib.h> #include <curses.h> @@ -38,6 +40,7 @@ typedef struct { teco_stailq_entry_t entry; teco_popup_entry_type_t type; + /** entry name or empty string for the "(Unnamed)" buffer */ teco_string_t name; gboolean highlight; } teco_popup_entry_t; @@ -122,25 +125,32 @@ teco_curses_info_popup_init_pad(teco_curses_info_popup_t *ctx, attr_t attr) if (entry->highlight) wattron(ctx->pad, A_BOLD); + teco_string_t name = entry->name; + if (!name.len) { + name.data = TECO_UNNAMED_FILE; + name.len = strlen(name.data); + } + switch (entry->type) { case TECO_POPUP_FILE: - g_assert(!teco_string_contains(&entry->name, '\0')); + g_assert(!teco_string_contains(&name, '\0')); if (teco_ed & TECO_ED_ICONS) { + /* "(Unnamed)" buffer is looked up as "" */ teco_curses_add_wc(ctx->pad, teco_curses_icons_lookup_file(entry->name.data)); waddch(ctx->pad, ' '); } - teco_curses_format_filename(ctx->pad, entry->name.data, -1); + teco_curses_format_filename(ctx->pad, name.data, -1); break; case TECO_POPUP_DIRECTORY: - g_assert(!teco_string_contains(&entry->name, '\0')); + g_assert(!teco_string_contains(&name, '\0')); if (teco_ed & TECO_ED_ICONS) { teco_curses_add_wc(ctx->pad, teco_curses_icons_lookup_dir(entry->name.data)); waddch(ctx->pad, ' '); } - teco_curses_format_filename(ctx->pad, entry->name.data, -1); + teco_curses_format_filename(ctx->pad, name.data, -1); break; default: - teco_curses_format_str(ctx->pad, entry->name.data, entry->name.len, -1); + teco_curses_format_str(ctx->pad, name.data, name.len, -1); break; } diff --git a/src/interface-curses/curses-utils.h b/src/interface-curses/curses-utils.h index 18cdd3d..c63c747 100644 --- a/src/interface-curses/curses-utils.h +++ b/src/interface-curses/curses-utils.h @@ -20,6 +20,9 @@ #include <curses.h> +/** what is displayed for unnamed buffers in the info line and popups */ +#define TECO_UNNAMED_FILE "(Unnamed)" + guint teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width); guint teco_curses_format_filename(WINDOW *win, const gchar *filename, gint max_width); diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 073ff86..833b564 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -138,8 +138,6 @@ static gint teco_xterm_version(void) G_GNUC_UNUSED; static gint teco_interface_blocking_getch(void); -#define UNNAMED_FILE "(Unnamed)" - /** * Get bright variant of one of the 8 standard * curses colors. @@ -202,6 +200,7 @@ static struct { TECO_INFO_TYPE_BUFFER = 0, TECO_INFO_TYPE_QREG } info_type; + /* current document's name or empty string for "(Unnamed)" buffer */ teco_string_t info_current; gboolean info_dirty; @@ -437,12 +436,6 @@ teco_interface_init(void) teco_curses_info_popup_init(&teco_interface.popup); - /* - * Make sure we have a string for the info line - * even if teco_interface_info_update() is never called. - */ - teco_string_init(&teco_interface.info_current, PACKAGE_NAME, strlen(PACKAGE_NAME)); - teco_cmdline_init(); /* * The default INDIC_STRIKE wouldn't be visible. @@ -1160,26 +1153,30 @@ teco_interface_draw_info(void) waddstr(teco_interface.info_window, PACKAGE_NAME " "); + teco_string_t info_current = teco_interface.info_current; + if (!info_current.len) { + info_current.data = TECO_UNNAMED_FILE; + info_current.len = strlen(info_current.data); + } + switch (teco_interface.info_type) { case TECO_INFO_TYPE_QREG: info_type_str = PACKAGE_NAME " - <QRegister> "; teco_curses_add_wc(teco_interface.info_window, teco_ed & TECO_ED_ICONS ? TECO_CURSES_ICONS_QREG : '-'); waddstr(teco_interface.info_window, " <QRegister> "); - /* same formatting as in command lines */ teco_curses_format_str(teco_interface.info_window, - teco_interface.info_current.data, - teco_interface.info_current.len, -1); + info_current.data, info_current.len, -1); break; case TECO_INFO_TYPE_BUFFER: info_type_str = PACKAGE_NAME " - <Buffer> "; - g_assert(!teco_string_contains(&teco_interface.info_current, '\0')); + g_assert(!teco_string_contains(&info_current, '\0')); + /* "(Unnamed)" buffer has to be looked up as "" */ teco_curses_add_wc(teco_interface.info_window, teco_ed & TECO_ED_ICONS ? teco_curses_icons_lookup_file(teco_interface.info_current.data) : '-'); waddstr(teco_interface.info_window, " <Buffer> "); - teco_curses_format_filename(teco_interface.info_window, - teco_interface.info_current.data, + teco_curses_format_filename(teco_interface.info_window, info_current.data, getmaxx(teco_interface.info_window) - getcurx(teco_interface.info_window) - 1); waddch(teco_interface.info_window, teco_interface.info_dirty ? '*' : ' '); @@ -1195,8 +1192,7 @@ teco_interface_draw_info(void) * Make sure the title will consist only of printable characters. */ g_autofree gchar *info_current_printable; - info_current_printable = teco_string_echo(teco_interface.info_current.data, - teco_interface.info_current.len); + info_current_printable = teco_string_echo(info_current.data, info_current.len); g_autofree gchar *title = g_strconcat(info_type_str, info_current_printable, teco_interface.info_dirty ? "*" : "", NULL); teco_interface_set_window_title(title); @@ -1216,10 +1212,9 @@ teco_interface_info_update_qreg(const teco_qreg_t *reg) void teco_interface_info_update_buffer(const teco_buffer_t *buffer) { - const gchar *filename = buffer->filename ? : UNNAMED_FILE; - teco_string_clear(&teco_interface.info_current); - teco_string_init(&teco_interface.info_current, filename, strlen(filename)); + teco_string_init(&teco_interface.info_current, buffer->filename, + buffer->filename ? strlen(buffer->filename) : 0); teco_interface.info_dirty = buffer->state > TECO_BUFFER_CLEAN; teco_interface.info_type = TECO_INFO_TYPE_BUFFER; /* NOTE: drawn in teco_interface_event_loop_iter() */ @@ -1865,7 +1860,10 @@ teco_interface_process_mevent(MEVENT *event, GError **error) event->y, event->x); if (insert && machine->current->insert_completion_cb) { - /* successfully clicked popup item */ + /* + * Successfully clicked popup item. + * `insert` is the empty string for the "(Unnamed)" buffer. + */ const teco_string_t insert_suffix = {insert->data + teco_interface.popup_prefix_len, insert->len - teco_interface.popup_prefix_len}; if (!machine->current->insert_completion_cb(machine, &insert_suffix, error)) |
