Skip to content

Commit 0752271

Browse files
feat(Mapping): automatically remap duplicate
This commit fix @Vixyd comment, There is no more warning for duplicate during startup, Duplicates found at runtime are reported on the message section (background). The only counter intuitive case would be if user-defined and automatic key maps are mixed (unlikely). In this case, if a user-defined key map is already in use by a previous automatically assigned item, the user-defined key map is ignored (and a warning is raised). This would be costly to check and is now documented.
1 parent 9d5455d commit 0752271

File tree

2 files changed

+41
-37
lines changed

2 files changed

+41
-37
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@ let g:quickmenu_options = "HL"
3434
Simply use the function below:
3535

3636
```VimL
37-
function quickmenu#append(text, action [, help = ''])
37+
function quickmenu#append(text, action [, help = ''][, ft = ''][, weight = 0][, key = ''])
3838
```
3939

4040
- `text` will be show in the quickmenu, vimscript in `%{...}` will be evaluated and expanded.
4141
- `action` is a piece of vimscript to be executed when a item is selected.
4242
- `help` will display in the cmdline if g:quickmenu_options contains `H`.
43+
- 'ft' will filter this item only for matching filetypes
44+
- 'weight' menu items will be sorted according to the weight
45+
- 'key' use this key as shortcut if not already assigned
4346

4447
A item will be treated as "static text" (unselectable) If `action` is empty. `text` starting with "#" represents a new section.
4548

autoload/quickmenu.vim

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ if !exists('g:quickmenu_options')
3737
let g:quickmenu_options = ''
3838
endif
3939

40-
if !exists('g:quickmenu_special_keys')
41-
let g:quickmenu_special_keys = 1
42-
endif
43-
4440
"----------------------------------------------------------------------
4541
" Internal State
4642
"----------------------------------------------------------------------
@@ -53,20 +49,6 @@ let s:quickmenu_name = '[quickmenu]'
5349
let s:quickmenu_line = 0
5450
let s:quickmenu_custom_keys = {}
5551

56-
function! s:reset_key_map()
57-
let s:quickmenu_custom_keys = {}
58-
if g:quickmenu_special_keys == 1
59-
" Prevent user to bind special keys
60-
let s:quickmenu_custom_keys['g']=1
61-
let s:quickmenu_custom_keys['G']=1
62-
let s:quickmenu_custom_keys['j']=1
63-
let s:quickmenu_custom_keys['k']=1
64-
let s:quickmenu_custom_keys['q']=1
65-
endif
66-
endfunction
67-
68-
call s:reset_key_map()
69-
7052
"----------------------------------------------------------------------
7153
" popup window management
7254
"----------------------------------------------------------------------
@@ -143,29 +125,28 @@ function! quickmenu#reset()
143125
let s:quickmenu_items[s:quickmenu_mid] = []
144126
let s:quickmenu_line = 0
145127
let s:quickmenu_cursor[s:quickmenu_mid] = 0
146-
call s:reset_key_map()
147128
endfunc
148129

149130
function! quickmenu#append(text, event, ...)
150131
let help = (a:0 >= 1)? a:1 : ''
151132
let filetype = (a:0 >= 2)? a:2 : ''
152133
let weight = (a:0 >= 3)? a:3 : 0
153134
let item = {}
154-
let item.key = ''
155-
if a:0 >= 4
156-
if has_key(s:quickmenu_custom_keys, a:4)
157-
call s:errmsg("Quickmenu: Found duplicate binding for key ".a:4)
158-
else
159-
let item.key = a:4
160-
let s:quickmenu_custom_keys[a:4]=1
161-
endif
162-
endif
135+
163136
let item.mode = 0
164137
let item.event = a:event
165138
let item.text = a:text
166-
let item.ft = []
139+
140+
let item.key = ''
141+
if a:0 >= 4
142+
let item.key = a:4
143+
" all used keys for this panel
144+
let s:quickmenu_custom_keys[a:4]=1
145+
endif
146+
167147
let item.weight = weight
168148
let item.help = help
149+
169150
if a:event != ''
170151
let item.mode = 0
171152
elseif a:text[0] != '#'
@@ -174,9 +155,12 @@ function! quickmenu#append(text, event, ...)
174155
let item.mode = 2
175156
let item.text = matchstr(a:text, '^#\+\s*\zs.*')
176157
endif
158+
159+
let item.ft = []
177160
for ft in split(filetype, ',')
178161
let item.ft += [substitute(ft, '^\s*\(.\{-}\)\s*$', '\1', '')]
179162
endfor
163+
180164
let index = -1
181165
if !has_key(s:quickmenu_items, s:quickmenu_mid)
182166
let s:quickmenu_items[s:quickmenu_mid] = []
@@ -199,7 +183,6 @@ endfunc
199183

200184
function! quickmenu#current(mid)
201185
let s:quickmenu_mid = a:mid
202-
call s:reset_key_map()
203186
endfunc
204187

205188

@@ -378,7 +361,7 @@ function! s:set_cursor() abort
378361
let find = select - 2
379362
endif
380363
if find < 0
381-
call s:errmsg("fatal error in set_cursor() ".find)
364+
call s:start_error_message("Quickmenu: fatal error in set_cursor() ".find)
382365
return
383366
endif
384367
let s:quickmenu_line = find + 2
@@ -453,6 +436,7 @@ endfunc
453436
" select items by &ft, generate keymap and add some default items
454437
"----------------------------------------------------------------------
455438
function! s:select_by_ft(mid, ft) abort
439+
let duplicate_key_check = {}
456440
let hint = '123456789abcdefhilmnoprstuvwxyzACDIOPQRSUX*'
457441
" let hint = '12abcdefhlmnoprstuvwxyz*'
458442
let items = []
@@ -478,9 +462,14 @@ function! s:select_by_ft(mid, ft) abort
478462
let lastmode = item.mode
479463
" allocate key for non-filetype specific items
480464
if item.mode == 0 && len(item.ft) == 0
465+
" discard already used mapping
466+
if has_key(duplicate_key_check, item.key)
467+
call s:run_error_message("Quickmenu: duplicate mapping for ".item.key)
468+
let item.key = ''
469+
endif
481470
if item.key == ''
482-
" Avdoid to remap existing key
483-
while has_key(s:quickmenu_custom_keys, hint[index]) && index < strlen(hint)-1
471+
" Avdoid to remap already used mapping
472+
while has_key(duplicate_key_check, hint[index]) && index < strlen(hint)-1
484473
let index += 1
485474
endwhile
486475
let item.key = hint[index]
@@ -489,6 +478,7 @@ function! s:select_by_ft(mid, ft) abort
489478
let index = strlen(hint) - 1
490479
endif
491480
endif
481+
let duplicate_key_check[item.key] = 1
492482
endif
493483
let items += [item]
494484
if item.mode == 2
@@ -500,9 +490,14 @@ function! s:select_by_ft(mid, ft) abort
500490
" allocate key for filetype specific items
501491
for item in items
502492
if item.mode == 0 && len(item.ft) > 0
493+
" discard already used mapping
494+
if has_key(duplicate_key_check, item.key)
495+
call s:run_error_message("Quickmenu: duplicate mapping for ".item.key)
496+
let item.key = ''
497+
endif
503498
if item.key == ''
504-
" Avdoid to remap existing key
505-
while has_key(s:quickmenu_custom_keys, hint[index]) && index < strlen(hint)-1
499+
" Avdoid to remap already used mapping
500+
while has_key(duplicate_key_check, hint[index]) && index < strlen(hint)-1
506501
let index += 1
507502
endwhile
508503
let item.key = hint[index]
@@ -511,6 +506,8 @@ function! s:select_by_ft(mid, ft) abort
511506
let index = strlen(hint) - 1
512507
endif
513508
endif
509+
" keep all used keys
510+
let duplicate_key_check[item.key] = 1
514511
endif
515512
endfor
516513
if len(items)
@@ -663,12 +660,16 @@ endfunc
663660
"----------------------------------------------------------------------
664661
" echo a error msg
665662
"----------------------------------------------------------------------
666-
function! s:errmsg(msg)
663+
function! s:start_error_message(msg)
667664
echohl ErrorMsg
668665
echo a:msg
669666
echohl None
670667
endfunc
671668

669+
function! s:run_error_message(msg)
670+
echom a:msg
671+
endfunc
672+
672673

673674
"----------------------------------------------------------------------
674675
" echo highlight

0 commit comments

Comments
 (0)