From 5b823ee6b763d4672f51a7669aa3f2afca5428ea Mon Sep 17 00:00:00 2001 From: Gueunet Charles Date: Wed, 2 Aug 2017 21:02:19 +0200 Subject: [PATCH 1/5] feat(Menu shortcut): choose key We can now precise the key we want to use in the configuration --- autoload/quickmenu.vim | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/autoload/quickmenu.vim b/autoload/quickmenu.vim index 3a81755..5ef04be 100644 --- a/autoload/quickmenu.vim +++ b/autoload/quickmenu.vim @@ -131,10 +131,10 @@ function! quickmenu#append(text, event, ...) let filetype = (a:0 >= 2)? a:2 : '' let weight = (a:0 >= 3)? a:3 : 0 let item = {} + let item.key = (a:0 >= 4)?a:4:'' let item.mode = 0 let item.event = a:event let item.text = a:text - let item.key = '' let item.ft = [] let item.weight = weight let item.help = help @@ -448,7 +448,9 @@ function! s:select_by_ft(mid, ft) abort let lastmode = item.mode " allocate key for non-filetype specific items if item.mode == 0 && len(item.ft) == 0 - let item.key = hint[index] + if item.key == '' + let item.key = hint[index] + endif let index += 1 if index >= strlen(hint) let index = strlen(hint) - 1 @@ -464,7 +466,9 @@ function! s:select_by_ft(mid, ft) abort " allocate key for filetype specific items for item in items if item.mode == 0 && len(item.ft) > 0 - let item.key = hint[index] + if item.key == '' + let item.key = hint[index] + endif let index += 1 if index >= strlen(hint) let index = strlen(hint) - 1 From 29428a118fac5e92bd40fa153335745f43e80c7a Mon Sep 17 00:00:00 2001 From: Gueunet Charles Date: Fri, 4 Aug 2017 23:50:48 +0200 Subject: [PATCH 2/5] feat(Custom Key binding): Echo warning on duplicate --- autoload/quickmenu.vim | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/autoload/quickmenu.vim b/autoload/quickmenu.vim index 5ef04be..3c6dfe3 100644 --- a/autoload/quickmenu.vim +++ b/autoload/quickmenu.vim @@ -35,6 +35,9 @@ if !exists('g:quickmenu_options') let g:quickmenu_options = '' endif +if !exists('g:quickmenu_special_keys') + let g:quickmenu_special_keys = 1 +endif "---------------------------------------------------------------------- " Internal State @@ -46,7 +49,7 @@ let s:quickmenu_cursor = {} let s:quickmenu_version = 'QuickMenu 1.2.2' let s:quickmenu_name = '[quickmenu]' let s:quickmenu_line = 0 - +let s:quickmenu_custom_keys = {} "---------------------------------------------------------------------- " popup window management @@ -131,7 +134,16 @@ function! quickmenu#append(text, event, ...) let filetype = (a:0 >= 2)? a:2 : '' let weight = (a:0 >= 3)? a:3 : 0 let item = {} - let item.key = (a:0 >= 4)?a:4:'' + if a:0 >= 4 + if has_key(s:quickmenu_custom_keys, a:4) + call s:errmsg("Quickmenu: Found duplicate binding for key ".a:4) + else + let item.key = a:4 + let s:quickmenu_custom_keys[a:4]=1 + endif + else + let item.key = '' + endif let item.mode = 0 let item.event = a:event let item.text = a:text @@ -222,7 +234,7 @@ function! quickmenu#toggle(mid) abort endfor let content += hr endfor - + let maxsize += g:quickmenu_padding_right if 1 From 71b7d99d579531d57628dfd379bb7a9adeee61bb Mon Sep 17 00:00:00 2001 From: Gueunet Charles Date: Sat, 5 Aug 2017 00:08:30 +0200 Subject: [PATCH 3/5] feat(Custom Key binding): prevent binding on move keys --- autoload/quickmenu.vim | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/autoload/quickmenu.vim b/autoload/quickmenu.vim index 3c6dfe3..f3e88a5 100644 --- a/autoload/quickmenu.vim +++ b/autoload/quickmenu.vim @@ -51,6 +51,15 @@ let s:quickmenu_name = '[quickmenu]' let s:quickmenu_line = 0 let s:quickmenu_custom_keys = {} +if g:quickmenu_special_keys == 1 + " Prevent user to bind special keys + let s:quickmenu_custom_keys['g']=1 + let s:quickmenu_custom_keys['G']=1 + let s:quickmenu_custom_keys['j']=1 + let s:quickmenu_custom_keys['k']=1 + let s:quickmenu_custom_keys['q']=1 +endif + "---------------------------------------------------------------------- " popup window management "---------------------------------------------------------------------- @@ -134,6 +143,7 @@ function! quickmenu#append(text, event, ...) let filetype = (a:0 >= 2)? a:2 : '' let weight = (a:0 >= 3)? a:3 : 0 let item = {} + let item.key = '' if a:0 >= 4 if has_key(s:quickmenu_custom_keys, a:4) call s:errmsg("Quickmenu: Found duplicate binding for key ".a:4) @@ -141,9 +151,7 @@ function! quickmenu#append(text, event, ...) let item.key = a:4 let s:quickmenu_custom_keys[a:4]=1 endif - else - let item.key = '' - endif + endif let item.mode = 0 let item.event = a:event let item.text = a:text @@ -361,9 +369,7 @@ function! s:set_cursor() abort let find = select - 2 endif if find < 0 - echohl ErrorMsg - echo "fatal error in set_cursor() ".find - echohl None + call s:errmsg("fatal error in set_cursor() ".find) return endif let s:quickmenu_line = find + 2 From ecf9d423355bb89c23200bad67229f180de5b741 Mon Sep 17 00:00:00 2001 From: Gueunet Charles Date: Sat, 5 Aug 2017 18:50:12 +0200 Subject: [PATCH 4/5] fix(Custom Key binding): Do not overlap with hint Also: can deal with multiple panel now --- autoload/quickmenu.vim | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/autoload/quickmenu.vim b/autoload/quickmenu.vim index f3e88a5..4e9c43e 100644 --- a/autoload/quickmenu.vim +++ b/autoload/quickmenu.vim @@ -51,14 +51,19 @@ let s:quickmenu_name = '[quickmenu]' let s:quickmenu_line = 0 let s:quickmenu_custom_keys = {} -if g:quickmenu_special_keys == 1 - " Prevent user to bind special keys - let s:quickmenu_custom_keys['g']=1 - let s:quickmenu_custom_keys['G']=1 - let s:quickmenu_custom_keys['j']=1 - let s:quickmenu_custom_keys['k']=1 - let s:quickmenu_custom_keys['q']=1 -endif +function! s:reset_key_map() + let s:quickmenu_custom_keys = {} + if g:quickmenu_special_keys == 1 + " Prevent user to bind special keys + let s:quickmenu_custom_keys['g']=1 + let s:quickmenu_custom_keys['G']=1 + let s:quickmenu_custom_keys['j']=1 + let s:quickmenu_custom_keys['k']=1 + let s:quickmenu_custom_keys['q']=1 + endif +endfunction + +call s:reset_key_map() "---------------------------------------------------------------------- " popup window management @@ -136,6 +141,7 @@ function! quickmenu#reset() let s:quickmenu_items[s:quickmenu_mid] = [] let s:quickmenu_line = 0 let s:quickmenu_cursor[s:quickmenu_mid] = 0 + call s:reset_key_map() endfunc function! quickmenu#append(text, event, ...) @@ -191,6 +197,7 @@ endfunc function! quickmenu#current(mid) let s:quickmenu_mid = a:mid + call s:reset_key_map() endfunc @@ -467,11 +474,15 @@ function! s:select_by_ft(mid, ft) abort " allocate key for non-filetype specific items if item.mode == 0 && len(item.ft) == 0 if item.key == '' + " Avdoid to remap existing key + while has_key(s:quickmenu_custom_keys, hint[index]) && index < strlen(hint)-1 + let index += 1 + endwhile let item.key = hint[index] - endif - let index += 1 - if index >= strlen(hint) - let index = strlen(hint) - 1 + let index += 1 + if index >= strlen(hint) + let index = strlen(hint) - 1 + endif endif endif let items += [item] @@ -485,11 +496,15 @@ function! s:select_by_ft(mid, ft) abort for item in items if item.mode == 0 && len(item.ft) > 0 if item.key == '' + " Avdoid to remap existing key + while has_key(s:quickmenu_custom_keys, hint[index]) && index < strlen(hint)-1 + let index += 1 + endwhile let item.key = hint[index] - endif - let index += 1 - if index >= strlen(hint) - let index = strlen(hint) - 1 + let index += 1 + if index >= strlen(hint) + let index = strlen(hint) - 1 + endif endif endif endfor From 075227118d507d1061bbca5aaeba98b680f50fcc Mon Sep 17 00:00:00 2001 From: Charles Gueunet Date: Thu, 9 Aug 2018 17:40:08 +0000 Subject: [PATCH 5/5] 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. --- README.md | 5 ++- autoload/quickmenu.vim | 73 +++++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index eb7f39d..3bc4674 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,15 @@ let g:quickmenu_options = "HL" Simply use the function below: ```VimL -function quickmenu#append(text, action [, help = '']) +function quickmenu#append(text, action [, help = ''][, ft = ''][, weight = 0][, key = '']) ``` - `text` will be show in the quickmenu, vimscript in `%{...}` will be evaluated and expanded. - `action` is a piece of vimscript to be executed when a item is selected. - `help` will display in the cmdline if g:quickmenu_options contains `H`. +- 'ft' will filter this item only for matching filetypes +- 'weight' menu items will be sorted according to the weight +- 'key' use this key as shortcut if not already assigned A item will be treated as "static text" (unselectable) If `action` is empty. `text` starting with "#" represents a new section. diff --git a/autoload/quickmenu.vim b/autoload/quickmenu.vim index 76f3c27..a537870 100644 --- a/autoload/quickmenu.vim +++ b/autoload/quickmenu.vim @@ -37,10 +37,6 @@ if !exists('g:quickmenu_options') let g:quickmenu_options = '' endif -if !exists('g:quickmenu_special_keys') - let g:quickmenu_special_keys = 1 -endif - "---------------------------------------------------------------------- " Internal State "---------------------------------------------------------------------- @@ -53,20 +49,6 @@ let s:quickmenu_name = '[quickmenu]' let s:quickmenu_line = 0 let s:quickmenu_custom_keys = {} -function! s:reset_key_map() - let s:quickmenu_custom_keys = {} - if g:quickmenu_special_keys == 1 - " Prevent user to bind special keys - let s:quickmenu_custom_keys['g']=1 - let s:quickmenu_custom_keys['G']=1 - let s:quickmenu_custom_keys['j']=1 - let s:quickmenu_custom_keys['k']=1 - let s:quickmenu_custom_keys['q']=1 - endif -endfunction - -call s:reset_key_map() - "---------------------------------------------------------------------- " popup window management "---------------------------------------------------------------------- @@ -143,7 +125,6 @@ function! quickmenu#reset() let s:quickmenu_items[s:quickmenu_mid] = [] let s:quickmenu_line = 0 let s:quickmenu_cursor[s:quickmenu_mid] = 0 - call s:reset_key_map() endfunc function! quickmenu#append(text, event, ...) @@ -151,21 +132,21 @@ function! quickmenu#append(text, event, ...) let filetype = (a:0 >= 2)? a:2 : '' let weight = (a:0 >= 3)? a:3 : 0 let item = {} - let item.key = '' - if a:0 >= 4 - if has_key(s:quickmenu_custom_keys, a:4) - call s:errmsg("Quickmenu: Found duplicate binding for key ".a:4) - else - let item.key = a:4 - let s:quickmenu_custom_keys[a:4]=1 - endif - endif + let item.mode = 0 let item.event = a:event let item.text = a:text - let item.ft = [] + + let item.key = '' + if a:0 >= 4 + let item.key = a:4 + " all used keys for this panel + let s:quickmenu_custom_keys[a:4]=1 + endif + let item.weight = weight let item.help = help + if a:event != '' let item.mode = 0 elseif a:text[0] != '#' @@ -174,9 +155,12 @@ function! quickmenu#append(text, event, ...) let item.mode = 2 let item.text = matchstr(a:text, '^#\+\s*\zs.*') endif + + let item.ft = [] for ft in split(filetype, ',') let item.ft += [substitute(ft, '^\s*\(.\{-}\)\s*$', '\1', '')] endfor + let index = -1 if !has_key(s:quickmenu_items, s:quickmenu_mid) let s:quickmenu_items[s:quickmenu_mid] = [] @@ -199,7 +183,6 @@ endfunc function! quickmenu#current(mid) let s:quickmenu_mid = a:mid - call s:reset_key_map() endfunc @@ -378,7 +361,7 @@ function! s:set_cursor() abort let find = select - 2 endif if find < 0 - call s:errmsg("fatal error in set_cursor() ".find) + call s:start_error_message("Quickmenu: fatal error in set_cursor() ".find) return endif let s:quickmenu_line = find + 2 @@ -453,6 +436,7 @@ endfunc " select items by &ft, generate keymap and add some default items "---------------------------------------------------------------------- function! s:select_by_ft(mid, ft) abort + let duplicate_key_check = {} let hint = '123456789abcdefhilmnoprstuvwxyzACDIOPQRSUX*' " let hint = '12abcdefhlmnoprstuvwxyz*' let items = [] @@ -478,9 +462,14 @@ function! s:select_by_ft(mid, ft) abort let lastmode = item.mode " allocate key for non-filetype specific items if item.mode == 0 && len(item.ft) == 0 + " discard already used mapping + if has_key(duplicate_key_check, item.key) + call s:run_error_message("Quickmenu: duplicate mapping for ".item.key) + let item.key = '' + endif if item.key == '' - " Avdoid to remap existing key - while has_key(s:quickmenu_custom_keys, hint[index]) && index < strlen(hint)-1 + " Avdoid to remap already used mapping + while has_key(duplicate_key_check, hint[index]) && index < strlen(hint)-1 let index += 1 endwhile let item.key = hint[index] @@ -489,6 +478,7 @@ function! s:select_by_ft(mid, ft) abort let index = strlen(hint) - 1 endif endif + let duplicate_key_check[item.key] = 1 endif let items += [item] if item.mode == 2 @@ -500,9 +490,14 @@ function! s:select_by_ft(mid, ft) abort " allocate key for filetype specific items for item in items if item.mode == 0 && len(item.ft) > 0 + " discard already used mapping + if has_key(duplicate_key_check, item.key) + call s:run_error_message("Quickmenu: duplicate mapping for ".item.key) + let item.key = '' + endif if item.key == '' - " Avdoid to remap existing key - while has_key(s:quickmenu_custom_keys, hint[index]) && index < strlen(hint)-1 + " Avdoid to remap already used mapping + while has_key(duplicate_key_check, hint[index]) && index < strlen(hint)-1 let index += 1 endwhile let item.key = hint[index] @@ -511,6 +506,8 @@ function! s:select_by_ft(mid, ft) abort let index = strlen(hint) - 1 endif endif + " keep all used keys + let duplicate_key_check[item.key] = 1 endif endfor if len(items) @@ -663,12 +660,16 @@ endfunc "---------------------------------------------------------------------- " echo a error msg "---------------------------------------------------------------------- -function! s:errmsg(msg) +function! s:start_error_message(msg) echohl ErrorMsg echo a:msg echohl None endfunc +function! s:run_error_message(msg) + echom a:msg +endfunc + "---------------------------------------------------------------------- " echo highlight