aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael <glephunter@gmail.com>2024-01-20 08:08:44 +0800
committerGitHub <noreply@github.com>2024-01-20 08:08:44 +0800
commit98a4ed0a110625e63950d85b26f3e4614393ea04 (patch)
treec2a51aa96d1b99e97c01bd8303334bd3eb302044
parentd3a8e9217f39c59dd7762bd22a76b8bd03ca85ff (diff)
downloadrneovim-98a4ed0a110625e63950d85b26f3e4614393ea04.tar.gz
rneovim-98a4ed0a110625e63950d85b26f3e4614393ea04.tar.bz2
rneovim-98a4ed0a110625e63950d85b26f3e4614393ea04.zip
feat(api): support getting abbreviations (#26868)
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--src/nvim/mapping.c36
-rw-r--r--test/functional/api/keymap_spec.lua51
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()