if (keylen > 0) {
g_string_overwrite_len(map.queue, map.qlen, (char*)keys, keylen);
map.qlen += keylen;
- } else {
- /* Shrink the queue to free some memory. */
- g_string_truncate(map.queue, map.qlen);
}
/* try to resolve keys against the map */
}
}
- /* replace the matched chars from queue by the cooked string that
- * is the result of the mapping */
+ /* Replace the matched chars from queue by the cooked string that
+ * is the result of the mapping. */
if (match) {
- int i, j;
- /* 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 */
+ /* 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. */
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; ) {
- map.queue->str[--i] = map.queue->str[--j];
- }
- } else if (match->inlen > match->mappedlen) {
- /* delete some keys */
- for (i = match->mappedlen, j = match->inlen; i < map.qlen; ) {
- map.queue->str[i++] = map.queue->str[j++];
- }
+ /* Replace the matching input chars by the mapped chars. */
+ if (match->inlen == match->mappedlen) {
+ /* If inlen and mappedlen are the same - replace the inlin
+ * chars with the mapped chars. This case could also be
+ * handled by the later string erase and prepend, but handling
+ * it special avoids unneded function call. */
+ g_string_overwrite_len(map.queue, 0, match->mapped, match->mappedlen);
+ } else {
+ /* Remove all the chars that where matched and prepend the
+ * mapped chars to the queue. */
+ g_string_erase(map.queue, 0, match->inlen);
+ g_string_prepend_len(map.queue, match->mapped, match->mappedlen);
}
-
- /* copy the mapped string into the queue */
- g_string_overwrite_len(map.queue, 0, match->mapped, match->mappedlen);
map.qlen += match->mappedlen - match->inlen;
/* without remap the mapped chars are resolved now */
#include <src/map.h>
#include <src/mode.h>
-static char queue[10]; /* receives the keypresses */
+static char queue[20]; /* receives the keypresses */
static int qpos = 0; /* points to the queue entry for the next keypress */
#define QUEUE_APPEND(c) { \
/* test simple mappings */
ASSERT_MAPPING("a", "[a]");
ASSERT_MAPPING("b", "[b]");
+ ASSERT_MAPPING("[c]", "c");
ASSERT_MAPPING("<Tab>", "[tab]");
ASSERT_MAPPING("<S-Tab>", "[shift-tab]");
ASSERT_MAPPING("<C-F>", "[ctrl-f]");
ASSERT_MAPPING("<C-f>", "[ctrl-f]");
ASSERT_MAPPING("<CR>", "[cr]");
ASSERT_MAPPING("foobar", "[baz]");
+
+ /* key sequences that are not changed by mappings */
+ ASSERT_MAPPING("fghi", "fghi");
}
static void test_handle_string_alias(void)
ASSERT_MAPPING("<C-M>", "[cr]");
}
-static void test_handle_string_multiple(void)
-{
- /* test multiple mappings together */
- ASSERT_MAPPING("ba", "[b][a]");
-
- /* incomplete ambiguous sequences are not matched jet */
- ASSERT_MAPPING("foob", "");
- ASSERT_MAPPING("ar", "[baz]");
-}
-
static void test_handle_string_remapped(void)
{
/* test multiple mappings together */
ASSERT_MAPPING("ba", "[b][a]");
+ ASSERT_MAPPING("ab12345[c]", "[a][b]12345c");
/* incomplete ambiguous sequences are not matched jet */
ASSERT_MAPPING("foob", "");
ASSERT_MAPPING("c", "[b][a]z[a]");
map_insert("d", "cki", 't', true);
ASSERT_MAPPING("d", "[b][a]z[a]ki");
+
+ /* remove the no more needed mappings */
+ map_delete("c", 't');
+ map_delete("d", 't');
+}
+
+static void test_handle_string_overrule(void)
+{
+ /* add another map for 'a' and check if this overrules the previous set */
+ map_insert("a", "overruled", 't', false);
+ ASSERT_MAPPING("a", "overruled");
}
static void test_remove(void)
g_test_add_func("/test-map/handle_string/simple", test_handle_string_simple);
g_test_add_func("/test-map/handle_string/alias", test_handle_string_alias);
- g_test_add_func("/test-map/handle_string/multi", test_handle_string_multiple);
g_test_add_func("/test-map/handle_string/remapped", test_handle_string_remapped);
+ g_test_add_func("/test-map/handle_string/overrule", test_handle_string_overrule);
g_test_add_func("/test-map/remove", test_remove);
g_test_add_func("/test-map/keypress/single-char", test_keypress_single);
g_test_add_func("/test-map/keypress/sequence", test_keypress_sequence);
/* add some mappings to test */
- map_insert("a", "[a]", 't', false);
+ map_insert("a", "[a]", 't', false); /* inlen < mappedlen */
map_insert("b", "[b]", 't', false);
+ map_insert("[c]", "c", 't', false); /* inlen > mappedlen */
+ map_insert("foobar", "[baz]", 't', false);
map_insert("<Tab>", "[tab]", 't', false);
map_insert("<S-Tab>", "[shift-tab]", 't', false);
map_insert("<C-F>", "[ctrl-f]", 't', false);
map_insert("<CR>", "[cr]", 't', false);
- /* map long sequence to shorter result */
- map_insert("foobar", "[baz]", 't', false);
result = g_test_run();
map_cleanup();