changeset 28817:1ad71fcbf546 v8.2.4932

patch 8.2.4932: not easy to filter the output of maplist() Commit: https://github.com/vim/vim/commit/d8f5f766219273a8579947cc80b92580b6988a4b Author: Ernie Rael <errael@raelity.com> Date: Tue May 10 17:50:39 2022 +0100 patch 8.2.4932: not easy to filter the output of maplist() Problem: Not easy to filter the output of maplist(). Solution: Add mode_bits to the dictionary. (Ernie Rael, closes https://github.com/vim/vim/issues/10356)
author Bram Moolenaar <Bram@vim.org>
date Tue, 10 May 2022 19:00:04 +0200
parents 708dfad50c43
children 6295b60a7491
files runtime/doc/builtin.txt src/map.c src/testdir/test_map_functions.vim src/testdir/test_vim9_builtin.vim src/version.c
diffstat 5 files changed, 36 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -5331,6 +5331,10 @@ maparg({name} [, {mode} [, {abbr} [, {di
 		  "nowait"   Do not wait for other, longer mappings.
 			     (|:map-<nowait>|).
 		  "abbr"     True if this is an abbreviation |abbreviations|.
+		  "mode_bits" Vim's internal binary representation of "mode".
+			     |mapset()| ignores this; only "mode" is used.
+			     See |maplist()| for usage examples. The values
+			     are from src/vim.h and may change in the future.
 
 		The dictionary can be used to restore a mapping with
 		|mapset()|.
@@ -5391,6 +5395,28 @@ maplist([{abbr}])					*maplist()*
 			vim9script
 			echo maplist()->filter(
 				(_, m) => match(m.rhs, 'MultiMatch') >= 0)
+<		It can be tricky to find mappings for particular |:map-modes|.
+		|mapping-dict|'s "mode_bits" can simplify this. For example,
+		the mode_bits for Normal, Insert or Command-line modes are
+		0x19. To find all the mappings available in those modes you
+		can do: >
+			vim9script
+			var saved_maps = []
+			for m in maplist()
+			    if and(m.mode_bits, 0x19) != 0
+				saved_maps->add(m)
+			    endif
+			endfor
+			echo saved_maps->mapnew((_, m) => m.lhs)
+<		The values of the mode_bits are defined in Vim's src/vim.h
+		file and they can be discovered at runtime using
+		|:map-commands| and "maplist()". Example: >
+			vim9script
+			omap xyzzy <Nop>
+			var op_bit = maplist()->filter(
+			    (_, m) => m.lhs == 'xyzzy')[0].mode_bits
+			ounmap xyzzy
+			echo printf("Operator-pending mode bit: 0x%x", op_bit)
 
 
 mapnew({expr1}, {expr2})					*mapnew()*
--- a/src/map.c
+++ b/src/map.c
@@ -2303,6 +2303,7 @@ mapblock2dict(
     dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L);
     dict_add_string(dict, "mode", mapmode);
     dict_add_number(dict, "abbr", abbr ? 1L : 0L);
+    dict_add_number(dict, "mode_bits", mp->m_mode);
 
     vim_free(mapmode);
 }
--- a/src/testdir/test_map_functions.vim
+++ b/src/testdir/test_map_functions.vim
@@ -19,13 +19,13 @@ func Test_maparg()
         \ 'lhsraw': "foo\x80\xfc\x04V", 'lhsrawalt': "foo\x16",
         \ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'scriptversion': 1,
         \ 'lnum': lnum + 1, 
-	\ 'rhs': 'is<F4>foo', 'buffer': 0, 'abbr': 0},
+	\ 'rhs': 'is<F4>foo', 'buffer': 0, 'abbr': 0, 'mode_bits': 0x47},
 	\ maparg('foo<C-V>', '', 0, 1))
   call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar',
         \ 'lhsraw': 'bar', 'mode': 'v',
         \ 'nowait': 0, 'expr': 1, 'sid': sid, 'scriptversion': 1,
         \ 'lnum': lnum + 2,
-	\ 'rhs': 'isbar', 'buffer': 1, 'abbr': 0},
+	\ 'rhs': 'isbar', 'buffer': 1, 'abbr': 0, 'mode_bits': 0x42},
         \ 'bar'->maparg('', 0, 1))
   let lnum = expand('<sflnum>')
   map <buffer> <nowait> foo bar
@@ -33,7 +33,7 @@ func Test_maparg()
         \ 'lhsraw': 'foo', 'mode': ' ',
         \ 'nowait': 1, 'expr': 0, 'sid': sid, 'scriptversion': 1,
         \ 'lnum': lnum + 1, 'rhs': 'bar',
-	\ 'buffer': 1, 'abbr': 0},
+	\ 'buffer': 1, 'abbr': 0, 'mode_bits': 0x47},
         \ maparg('foo', '', 0, 1))
   let lnum = expand('<sflnum>')
   tmap baz foo
@@ -41,7 +41,7 @@ func Test_maparg()
         \ 'lhsraw': 'baz', 'mode': 't',
         \ 'nowait': 0, 'expr': 0, 'sid': sid, 'scriptversion': 1,
         \ 'lnum': lnum + 1, 'rhs': 'foo',
-	\ 'buffer': 0, 'abbr': 0},
+        \ 'buffer': 0, 'abbr': 0, 'mode_bits': 0x80},
         \ maparg('baz', 't', 0, 1))
   let lnum = expand('<sflnum>')
   iab A B
@@ -49,7 +49,7 @@ func Test_maparg()
         \ 'lhsraw': 'A', 'mode': 'i',
         \ 'nowait': 0, 'expr': 0, 'sid': sid, 'scriptversion': 1,
         \ 'lnum': lnum + 1, 'rhs': 'B',
-	\ 'buffer': 0, 'abbr': 1},
+	\ 'buffer': 0, 'abbr': 1, 'mode_bits': 0x0010},
         \ maparg('A', 'i', 1, 1))
   iuna A
 
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -2464,7 +2464,8 @@ def Test_maparg()
         scriptversion: 999999,
         rhs: 'bar',
         buffer: 0,
-        abbr: 0})
+        abbr: 0,
+        mode_bits: 0x47})
   unmap foo
   v9.CheckDefAndScriptFailure(['maparg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'])
   v9.CheckDefAndScriptFailure(['maparg("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'])
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4932,
+/**/
     4931,
 /**/
     4930,