diff options
author | Raphael <glephunter@gmail.com> | 2024-01-20 08:08:44 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-20 08:08:44 +0800 |
commit | 98a4ed0a110625e63950d85b26f3e4614393ea04 (patch) | |
tree | c2a51aa96d1b99e97c01bd8303334bd3eb302044 | |
parent | d3a8e9217f39c59dd7762bd22a76b8bd03ca85ff (diff) | |
download | rneovim-98a4ed0a110625e63950d85b26f3e4614393ea04.tar.gz rneovim-98a4ed0a110625e63950d85b26f3e4614393ea04.tar.bz2 rneovim-98a4ed0a110625e63950d85b26f3e4614393ea04.zip |
feat(api): support getting abbreviations (#26868)
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | src/nvim/mapping.c | 36 | ||||
-rw-r--r-- | test/functional/api/keymap_spec.lua | 51 |
3 files changed, 67 insertions, 22 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 7743f5981a..05cfad5af1 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -159,7 +159,7 @@ The following new APIs and features were added. • |nvim_win_text_height()| computes the number of screen lines occupied by a range of text in a given window. -• |nvim_set_keymap()| and |nvim_del_keymap()| now support abbreviations. +• Mapping APIs now support abbreviations when mode short-name has suffix "a". • Better cmdline completion for string option value. |complete-set-option| diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index a8af2168c5..d36fbb32d7 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -36,6 +36,7 @@ #include "nvim/lua/executor.h" #include "nvim/macros_defs.h" #include "nvim/mapping.h" +#include "nvim/mapping_defs.h" #include "nvim/mbyte.h" #include "nvim/mbyte_defs.h" #include "nvim/memory.h" @@ -142,20 +143,6 @@ mapblock_T *get_buf_maphash_list(int state, int c) return curbuf->b_maphash[MAP_HASH(state, c)]; } -/// Retrieve the mapblock at the index either globally or for a certain buffer -/// -/// @param index The index in the maphash[] -/// @param buf The buffer to get the maphash from. NULL for global -mapblock_T *get_maphash(int index, buf_T *buf) - FUNC_ATTR_PURE -{ - if (index >= MAX_MAPHASH) { - return NULL; - } - - return (buf == NULL) ? maphash[index] : buf->b_maphash[index]; -} - /// Delete one entry from the abbrlist or maphash[]. /// "mpp" is a pointer to the m_next field of the PREVIOUS entry! static void mapblock_free(mapblock_T **mpp) @@ -2820,16 +2807,23 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf) { Array mappings = ARRAY_DICT_INIT; - // Convert the string mode to the integer mode - // that is stored within each mapblock - char *p = mode.data; - int int_mode = get_map_mode(&p, 0); + char *p = mode.size > 0 ? mode.data : "m"; + bool forceit = *p == '!'; + // Convert the string mode to the integer mode stored within each mapblock. + int int_mode = get_map_mode(&p, forceit); + if (forceit) { + assert(p == mode.data); + p++; + } + bool is_abbrev = (int_mode & (MODE_INSERT | MODE_CMDLINE)) != 0 && *p == 'a'; // Determine the desired buffer value int buffer_value = (buf == NULL) ? 0 : buf->handle; - for (int i = 0; i < MAX_MAPHASH; i++) { - for (const mapblock_T *current_maphash = get_maphash(i, buf); + for (int i = 0; i < (is_abbrev ? 1 : MAX_MAPHASH); i++) { + for (const mapblock_T *current_maphash = is_abbrev + ? (buf ? buf->b_first_abbr : first_abbr) + : (buf ? buf->b_maphash[i] : maphash[i]); current_maphash; current_maphash = current_maphash->m_next) { if (current_maphash->m_simplified) { @@ -2839,7 +2833,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf) if (int_mode & current_maphash->m_mode) { ADD(mappings, DICTIONARY_OBJ(mapblock_fill_dict(current_maphash, NULL, - buffer_value, false, false))); + buffer_value, is_abbrev, false))); } } } diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 4f57f6d0bd..0decd710e9 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -460,6 +460,57 @@ describe('nvim_get_keymap', function() desc = 'map description', }, api.nvim_get_keymap('n')[1]) end) + + it('can get abbreviations', function() + command('inoreabbr foo bar') + command('cnoreabbr <buffer> foo baz') + + local mapargs_i = { + abbr = 1, + buffer = 0, + expr = 0, + lhs = 'foo', + lhsraw = 'foo', + lnum = 0, + mode = 'i', + mode_bits = 0x10, + noremap = 1, + nowait = 0, + rhs = 'bar', + script = 0, + scriptversion = 1, + sid = 0, + silent = 0, + } + local mapargs_c = { + abbr = 1, + buffer = 1, + expr = 0, + lhs = 'foo', + lhsraw = 'foo', + lnum = 0, + mode = 'c', + mode_bits = 0x08, + noremap = 1, + nowait = 0, + rhs = 'baz', + script = 0, + scriptversion = 1, + sid = 0, + silent = 0, + } + + local curbuf = api.nvim_get_current_buf() + + eq({ mapargs_i }, api.nvim_get_keymap('ia')) + eq({}, api.nvim_buf_get_keymap(curbuf, 'ia')) + + eq({}, api.nvim_get_keymap('ca')) + eq({ mapargs_c }, api.nvim_buf_get_keymap(curbuf, 'ca')) + + eq({ mapargs_i }, api.nvim_get_keymap('!a')) + eq({ mapargs_c }, api.nvim_buf_get_keymap(curbuf, '!a')) + end) end) describe('nvim_set_keymap, nvim_del_keymap', function() |