From: Daniel Carl Date: Wed, 3 Sep 2014 22:01:16 +0000 (+0200) Subject: Fixed wrong showcmd in status bar. X-Git-Url: https://git.owens.tech///git?a=commitdiff_plain;h=e0d43522bd6a2ba9700c0ada11cef89dd865cc05;p=vimb.git Fixed wrong showcmd in status bar. If there where mapping that start with keys that needs more keys and we wait over the timeoutlen without typing further, the already typed keys where added to the showcmd in status bar. For example if ':nnoremap 1gt' is configured and '1' is typed, '1' is written to showcmd. After timeoutlen '11' is written. If '1g' was typed, '1g1g' was written after timeoutlen. This patch adds a counter for keys shown in showcmd, so that we do not add keys that are already present there. --- diff --git a/src/ex.c b/src/ex.c index 6562f05..c42b348 100644 --- a/src/ex.c +++ b/src/ex.c @@ -39,7 +39,6 @@ #include "handlers.h" #include "map.h" #include "js.h" -#include "normal.h" typedef enum { EX_BMA, @@ -354,7 +353,7 @@ VbResult ex_keypress(int key) } else { /* if the key sequence is not complete show the already typed keys in * status bar */ - normal_showcmd(key); + map_showcmd(key); } return res; diff --git a/src/map.c b/src/map.c index e1e14ad..470584a 100644 --- a/src/map.c +++ b/src/map.c @@ -24,7 +24,8 @@ #include "ascii.h" #include "mode.h" -extern VbCore vb; +/* convert the lower 4 bits of byte n to its hex character */ +#define NR2HEX(n) (n & 0xf) <= 9 ? (n & 0xf) + '0' : (c & 0xf) - 10 + 'a' typedef struct { char *in; /* input keys */ @@ -35,14 +36,19 @@ typedef struct { gboolean remap; /* if false do not remap the {rhs} of this map */ } Map; +/* this is only to keep the variables together */ static struct { GSList *list; - char queue[MAP_QUEUE_SIZE]; /* queue holding typed keys */ - int qlen; /* pointer to last char in queue */ - int resolved; /* number of resolved keys (no mapping required) */ - guint timout_id; /* source id of the timeout function */ + char queue[MAP_QUEUE_SIZE]; /* queue holding typed keys */ + int qlen; /* pointer to last char in queue */ + int resolved; /* number of resolved keys (no mapping required) */ + guint timout_id; /* source id of the timeout function */ + char showcmd[SHOWCMD_LEN + 1]; /* buffer to show ambiguous key sequence */ } map; +extern VbCore vb; + +static char *transchar(int c); static gboolean map_delete_by_lhs(const char *lhs, int len, char mode); static int keyval_to_string(guint keyval, guint state, guchar *string); static int utf_char2bytes(guint c, guchar *buf); @@ -168,6 +174,7 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map) int ambiguous; Map *match = NULL; gboolean timeout = (keylen == 0); /* keylen 0 signalized timeout */ + static int showlen = 0; /* track the number of keys in showcmd of status bar */ /* if a previous timeout function was set remove this */ if (map.timout_id) { @@ -220,9 +227,12 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map) /* send the key to the parser */ if (RESULT_MORE != mode_handle_key((int)qk)) { -#ifndef TESTLIB - normal_showcmd(0); -#endif + map_showcmd(0); + showlen = 0; + } else if (showlen > 0) { + showlen--; + } else { + map_showcmd(qk); } } @@ -245,19 +255,16 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map) /* find ambiguous matches */ if (!timeout && m->inlen > map.qlen && !strncmp(m->in, map.queue, map.qlen)) { -#ifndef TESTLIB if (ambiguous == 0) { /* show command chars for the ambiguous commands */ int i = map.qlen > SHOWCMD_LEN ? map.qlen - SHOWCMD_LEN : 0; - /* only appending the last queue char does not work - * with the multi char termcap entries, so we flush - * the show command and put the chars into it again */ - normal_showcmd(0); + /* appen only those chars that are not already in showcmd */ + i += showlen; while (i < map.qlen) { - normal_showcmd(map.queue[i++]); + map_showcmd(map.queue[i++]); + showlen++; } } -#endif ambiguous++; } /* complete match or better/longer match than previous found */ @@ -281,12 +288,12 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map) * is the result of the mapping */ if (match) { int i, j; - /* flush ths show command to make room for possible mapped command + /* flush the show command to make room for possible mapped command * chars to show for example if :nmap foo 12g is use we want to * display the incomplete 12g command */ -#ifndef TESTLIB - normal_showcmd(0); -#endif + map_showcmd(0); + showlen = 0; + if (match->inlen < match->mappedlen) { /* make some space within the queue */ for (i = map.qlen + match->mappedlen - match->inlen, j = map.qlen; j > match->inlen; ) { @@ -360,6 +367,56 @@ gboolean map_delete(const char *in, char mode) return map_delete_by_lhs(lhs, len, mode); } +/** + * Put the given char onto the show command buffer. + */ +void map_showcmd(int c) +{ + char *translated; + int old, extra, overflow; + + if (c) { + translated = transchar(c); + old = strlen(map.showcmd); + extra = strlen(translated); + overflow = old + extra - SHOWCMD_LEN; + if (overflow > 0) { + memmove(map.showcmd, map.showcmd + overflow, old - overflow + 1); + } + strcat(map.showcmd, translated); + } else { + map.showcmd[0] = '\0'; + } +#ifndef TESTLIB + /* show the typed keys */ + gtk_label_set_text(GTK_LABEL(vb.gui.statusbar.cmd), map.showcmd); +#endif +} + +/** + * Translate a singe char into a readable representation to be show to the + * user in status bar. + */ +static char *transchar(int c) +{ + static char trans[5]; + int i = 0; + if (VB_IS_CTRL(c)) { + trans[i++] = '^'; + trans[i++] = CTRL(c); + } else if ((unsigned)c >= 0x80) { + trans[i++] = '<'; + trans[i++] = NR2HEX((unsigned)c >> 4); + trans[i++] = NR2HEX((unsigned)c); + trans[i++] = '>'; + } else { + trans[i++] = c; + } + trans[i++] = '\0'; + + return trans; +} + static gboolean map_delete_by_lhs(const char *lhs, int len, char mode) { for (GSList *l = map.list; l != NULL; l = l->next) { diff --git a/src/map.h b/src/map.h index a08dfce..a02e3db 100644 --- a/src/map.h +++ b/src/map.h @@ -38,5 +38,6 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map); void map_handle_string(const char *str, gboolean use_map); void map_insert(const char *in, const char *mapped, char mode, gboolean remap); gboolean map_delete(const char *in, char mode); +void map_showcmd(int c); #endif /* end of include guard: _MAP_H */ diff --git a/src/mode.c b/src/mode.c index 8bf4695..42a8996 100644 --- a/src/mode.c +++ b/src/mode.c @@ -20,7 +20,7 @@ #include "config.h" #include "main.h" #include "mode.h" -#include "normal.h" +#include "map.h" #include "ascii.h" #include @@ -133,7 +133,7 @@ VbResult mode_handle_key(int key) if (vb.mode->id != 'p' && key == CTRL('V')) { vb.mode->flags |= FLAG_NOMAP; ctrl_v = true; - normal_showcmd(key); + map_showcmd(key); return RESULT_MORE; } diff --git a/src/normal.c b/src/normal.c index 742c2d1..779bfac 100644 --- a/src/normal.c +++ b/src/normal.c @@ -29,9 +29,6 @@ #include "history.h" #include "util.h" -/* convert the lower 4 bits of byte n to its hex character */ -#define NR2HEX(n) (n & 0xf) <= 9 ? (n & 0xf) + '0' : (c & 0xf) - 10 + 'a' - typedef enum { PHASE_START, PHASE_KEY2, @@ -53,8 +50,6 @@ static NormalCmdInfo info = {0, '\0', '\0', PHASE_START}; typedef VbResult (*NormalCommand)(const NormalCmdInfo *info); -static char *transchar(int c); - static VbResult normal_clear_input(const NormalCmdInfo *info); static VbResult normal_descent(const NormalCmdInfo *info); static VbResult normal_ex(const NormalCmdInfo *info); @@ -215,8 +210,6 @@ static struct { extern VbCore vb; -static char showcmd_buf[SHOWCMD_LEN + 1]; /* buffer to show ambiguous key sequence */ - /** * Function called when vimb enters the normal mode. */ @@ -312,60 +305,9 @@ VbResult normal_keypress(int key) res = RESULT_MORE; } - if (res == RESULT_MORE) { - normal_showcmd(key); - } return res; } -/** - * Put the given char onto the show command buffer. - */ -void normal_showcmd(int c) -{ - char *translated; - int old, extra, overflow; - - if (c) { - translated = transchar(c); - old = strlen(showcmd_buf); - extra = strlen(translated); - overflow = old + extra - SHOWCMD_LEN; - if (overflow > 0) { - memmove(showcmd_buf, showcmd_buf + overflow, old - overflow + 1); - } - strcat(showcmd_buf, translated); - } else { - showcmd_buf[0] = '\0'; - } - /* show the typed keys */ - gtk_label_set_text(GTK_LABEL(vb.gui.statusbar.cmd), showcmd_buf); -} - -/** - * Translate a singe char into a readable representation to be show to the - * user in status bar. - */ -static char *transchar(int c) -{ - static char trans[5]; - int i = 0; - if (VB_IS_CTRL(c)) { - trans[i++] = '^'; - trans[i++] = CTRL(c); - } else if ((unsigned)c >= 0x80) { - trans[i++] = '<'; - trans[i++] = NR2HEX((unsigned)c >> 4); - trans[i++] = NR2HEX((unsigned)c); - trans[i++] = '>'; - } else { - trans[i++] = c; - } - trans[i++] = '\0'; - - return trans; -} - static VbResult normal_clear_input(const NormalCmdInfo *info) { gtk_widget_grab_focus(GTK_WIDGET(vb.gui.webview));