123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- let s:cpo_save=&cpo
- set cpo&vim
-
-
- let s:k_Toggle_cmd = 'Toggle'
- if !exists('s:toggle_commands')
- let s:toggle_commands = {}
- endif
-
-
-
-
- let s:k_version = 300
- function! lh#menu#version()
- return s:k_version
- endfunction
-
-
- let s:verbose = 0
- function! lh#menu#verbose(...)
- if a:0 > 0 | let s:verbose = a:1 | endif
- return s:verbose
- endfunction
-
- function! s:Verbose(expr)
- if exists('s:verbose') && s:verbose
- echomsg a:expr
- endif
- endfunction
-
- function! lh#menu#debug(expr)
- return eval(a:expr)
- endfunction
-
-
-
-
-
- " @return a text to be used in menus where "\
- function! lh#menu#text(text)
- return escape(a:text, '\ ')
- endfunction
-
-
-
-
-
-
- function! s:Fetch(Data, key)
- let len = len(a:Data[a:key])
- if a:Data.idx_crt_value >= len | let a:Data.idx_crt_value = 0 | endif
- let value = a:Data[a:key][a:Data.idx_crt_value]
- return value
- endfunction
-
-
-
-
- function! s:Search(Data, value)
- let idx = index(a:Data.values, a:value)
- " echo a:Data.variable . "[".idx."] ==
- return idx > 0 ? idx : 0
- endfunction
-
-
-
-
- function! s:SearchText(Data, value)
- let labels_key = s:MenuKey(a:Data)
- let list = a:Data[labels_key]
- let idx = index(list, a:value)
- return idx
- endfunction
-
-
-
-
-
-
- function! s:Set(Data)
- let value = a:Data.values[a:Data.idx_crt_value]
- let variable = a:Data.variable
- if variable[0] == '$'
- exe "let ".variable." = ".string(value)
- else
- let g:{variable} = value
- endif
- if has_key(a:Data, "actions")
- let l:Action = a:Data.actions[a:Data.idx_crt_value]
- if type(l:Action) == type(function('tr'))
- call l:Action()
- else
- exe l:Action
- endif
- endif
- if has_key(a:Data, "hook")
- let l:Action = a:Data.hook
- if type(l:Action) == type(function('tr'))
- call a:Data.hook()
- else
- exe l:Action
- endif
- endif
- return value
- endfunction
-
-
-
-
- " Priority is given to the optional "texts" table over the madatory "values
- function! s:MenuKey(Data)
- if has_key(a:Data, "texts")
- let menu_id = "texts"
- else
- let menu_id = "values"
- endif
- return menu_id
- endfunction
-
-
-
-
- function! s:SetTextValue(Data, text)
-
- let labels_key = s:MenuKey(a:Data)
-
- let old = s:Fetch(a:Data, labels_key)
- let new_idx = s:SearchText(a:Data, a:text)
- if -1 == new_idx
- throw "toggle-menu: unsupported value for {".(a:Data.variable)."}"
- endif
- if a:Data.idx_crt_value == new_idx
-
- return
- endif
-
-
- call s:ClearMenu(a:Data.menu, old)
-
-
- let a:Data.idx_crt_value = new_idx
-
- let new = s:Fetch(a:Data,labels_key)
-
- call s:UpdateMenu(a:Data.menu, new, a:Data.command)
-
- let value = s:Set(a:Data)
- echo a:Data.variable.'='.value
- endfunction
-
-
-
-
- function! s:NextValue(Data)
-
- let labels_key = s:MenuKey(a:Data)
-
- let old = s:Fetch(a:Data, labels_key)
-
-
- call s:ClearMenu(a:Data.menu, old)
-
-
- let a:Data.idx_crt_value += 1
-
- let new = s:Fetch(a:Data,labels_key)
-
- call s:UpdateMenu(a:Data.menu, new, a:Data.command)
-
- let value = s:Set(a:Data)
- echo a:Data.variable.'='.value
- endfunction
-
-
-
-
-
-
-
- function! s:ClearMenu(Menu, text)
- if has('gui_running')
- let name = substitute(a:Menu.name, '&', '', 'g')
- let cmd = 'unmenu '.lh#menu#text(name.'<tab>('.a:text.')')
- silent! exe cmd
- endif
- endfunction
-
-
-
-
-
-
-
-
-
-
- function! s:UpdateMenu(Menu, text, command)
- if has('gui_running')
- let cmd = 'nnoremenu <silent> '.a:Menu.priority.' '.
- \ lh#menu#text(a:Menu.name.'<tab>('.a:text.')').
- \ ' :'.s:k_Toggle_cmd.' '.a:command."\<cr>"
- silent! exe cmd
- endif
- endfunction
-
-
-
-
-
-
- let s:data_id = 0
- function! s:SaveData(Data)
- let s:Data{s:data_id} = a:Data
- let id = s:data_id
- let s:data_id += 1
- return id
- endfunction
-
-
-
-
-
-
-
-
- function! lh#menu#def_toggle_item(Data)
-
- let id = s:SaveData(a:Data)
-
-
-
- if !has_key(a:Data, "idx_crt_value")
-
- let value = lh#option#get(a:Data.variable, 0, 'g')
- " echo a:Data.variable . " <-
-
- let a:Data.idx_crt_value = s:Search(a:Data, value)
- endif
-
-
- let cmdName = substitute(a:Data.menu.name, '[^a-zA-Z_]', '', 'g')
-
- if 2 != exists(':'.s:k_Toggle_cmd)
- exe 'command! -nargs=+ -complete=custom,lh#menu#_toggle_complete '
- \ . s:k_Toggle_cmd . ' :call s:Toggle(<f-args>)'
- endif
-
- let s:toggle_commands[cmdName] = eval('s:Data'.id)
- let a:Data["command"] = cmdName
-
-
- call s:UpdateMenu(a:Data.menu, s:Fetch(a:Data, s:MenuKey(a:Data)), cmdName)
-
- call s:Set(a:Data)
- endfunction
-
-
-
- function! s:Toggle(cmdName, ...)
- if !has_key(s:toggle_commands, a:cmdName)
- throw "toggle-menu: unknown toggable variable ".a:cmdName
- endif
- let data = s:toggle_commands[a:cmdName]
- if a:0 > 0
- call s:SetTextValue(data, a:1)
- else
- call s:NextValue(data)
- endif
- endfunction
-
- function! lh#menu#_toggle_complete(ArgLead, CmdLine, CursorPos)
- let cmdline = split(a:CmdLine)
- " echomsg "cmd line: " . string(cmdline)." #
- let nb_args = len(cmdline)
- if (a:CmdLine !~ ' $')
- let nb_args -= 1
- endif
- " echomsg "nb args:
- if nb_args < 2
- return join(keys(s:toggle_commands),"\n")
- elseif nb_args == 2
- let variable = cmdline[1]
- if !has_key(s:toggle_commands, variable)
- throw "toggle-menu: unknown toggable variable ".variable
- endif
- let data = s:toggle_commands[variable]
- let labels_key = s:MenuKey(data)
- " echomsg "keys:
- return join(data[labels_key], "\n")
- else
- return ''
- endif
- endfunction
-
-
-
-
-
-
- function! s:CTRL_O(cmd)
- return substitute(a:cmd, '\(^\|<CR>\):', '\1\<C-O>:', 'g')
- endfunction
-
-
- function! lh#menu#is_in_visual_mode()
- return exists('s:is_in_visual_mode') && s:is_in_visual_mode
- endfunction
-
-
-
-
- function! lh#menu#_CMD_and_clear_v(cmd)
- try
- let s:is_in_visual_mode = 1
- exe a:cmd
- finally
- let @v=''
- silent! unlet s:is_in_visual_mode
- endtry
- endfunction
-
-
-
- function! s:Build_CMD(prefix, cmd)
- if a:cmd[0] != ':' | return ' ' . a:cmd
- endif
- if a:prefix[0] == "i" | return ' ' . <SID>CTRL_O(a:cmd)
- elseif a:prefix[0] == "n" | return ' ' . a:cmd
- elseif a:prefix[0] == "v"
- if match(a:cmd, ":VCall") == 0
- return substitute(a:cmd, ':VCall', ' :call', ''). "\<cr>gV"
-
- else
- return
- \ " \"vy\<C-C>:call lh#menu#_CMD_and_clear_v('" .
- \ substitute(a:cmd, "<CR>$", '', '') ."')\<cr>"
- endif
- elseif a:prefix[0] == "c" | return " \<C-C>" . a:cmd
- else | return ' ' . a:cmd
- endif
- endfunction
-
-
-
- function! lh#menu#map_all(map_type,...)
- let nore = (match(a:map_type, '[aincv]*noremap') != -1) ? "nore" : ""
- let prefix = matchstr(substitute(a:map_type, nore, '', ''), '[aincv]*')
- if a:1 == "<buffer>" | let i = 3 | let binding = a:1 . ' ' . a:2
- else | let i = 2 | let binding = a:1
- endif
- let binding = '<silent> ' . binding
- let cmd = a:{i}
- let i += 1
- while i <= a:0
- let cmd .= ' ' . a:{i}
- let i += 1
- endwhile
- let build_cmd = nore . 'map ' . binding
- while strlen(prefix)
- if prefix[0] == "a" | let prefix = "incv"
- else
- execute prefix[0] . build_cmd . <SID>Build_CMD(prefix[0],cmd)
- let prefix = strpart(prefix, 1)
- endif
- endwhile
- endfunction
-
-
-
- function! lh#menu#make(prefix, code, text, binding, ...)
- let nore = (match(a:prefix, '[aincv]*nore') != -1) ? "nore" : ""
- let prefix = matchstr(substitute(a:prefix, nore, '', ''), '[aincv]*')
- let b = (a:1 == "<buffer>") ? 1 : 0
- let i = b + 1
- let cmd = a:{i}
- let i += 1
- while i <= a:0
- let cmd .= ' ' . a:{i}
- let i += 1
- endwhile
- let build_cmd = nore . "menu <silent> " . a:code . ' ' . lh#menu#text(a:text)
- if strlen(a:binding) != 0
- let build_cmd .= '<tab>' .
- \ substitute(lh#menu#text(a:binding), '&', '\0\0', 'g')
- if prefix == 'i' && exists('*IMAP')
- if b != 0
- call IMAP(a:binding, cmd, &ft)
- else
- call IMAP(a:binding, cmd)
- endif
- else
- if b != 0
- call lh#menu#map_all(prefix.nore."map", ' <buffer> '.a:binding, cmd)
- else
- call lh#menu#map_all(prefix.nore."map", a:binding, cmd)
- endif
- endif
- endif
- if has("gui_running")
- while strlen(prefix)
- execute <SID>BMenu(b).prefix[0].build_cmd.<SID>Build_CMD(prefix[0],cmd)
- let prefix = strpart(prefix, 1)
- endwhile
- endif
- endfunction
-
-
-
-
- function! s:BMenu(b)
- let res = (a:b && exists(':Bmenu')
- \ && (1 == lh#option#get("want_buffermenu_or_global_disable", 1, "bg"))
- \) ? 'B' : ''
- " call confirm("BMenu(".a:b.")=
- return res
- endfunction
-
-
- function! lh#menu#IVN_make(code, text, binding, i_cmd, v_cmd, n_cmd, ...)
-
- let nore_i = (a:0 > 0) ? ((a:1 != 0) ? 'nore' : '') : ''
- let nore_v = (a:0 > 1) ? ((a:2 != 0) ? 'nore' : '') : ''
- let nore_n = (a:0 > 2) ? ((a:3 != 0) ? 'nore' : '') : ''
-
- call lh#menu#make('i'.nore_i,a:code,a:text, a:binding, '<buffer>', a:i_cmd)
- call lh#menu#make('v'.nore_v,a:code,a:text, a:binding, '<buffer>', a:v_cmd)
- if strlen(a:n_cmd) != 0
- call lh#menu#make('n'.nore_n,a:code,a:text, a:binding, '<buffer>', a:n_cmd)
- endif
- endfunction
-
-
-
-
- let &cpo=s:cpo_save
-
|