.cache
bash
c
gdb
git
haskell
info
python
qckcmd
rss
sql
tf2
tmux
vim
.vim
autoload
quickui
command.vim
confirm.vim
context.vim
core.vim
highlight.vim
input.vim
listbox.vim
menu.vim
palette.vim
palette9.vim
preview.vim
readline.vim
style.vim
terminal.vim
textbox.vim
tools.vim
utils.vim
window.vim
DrawIt.vim
acp.vim
markx.vim
tagbar.vim
colors
dist
doc
ftdetect
plugin
syntax
.vimrc
.vimrc9
x11
xterm
zsh
.gitignore
524 lines
15 KiB
VimL
524 lines
15 KiB
VimL
"======================================================================
|
|
"
|
|
" tools.vim -
|
|
"
|
|
" Created by skywind on 2019/12/23
|
|
" Last Modified: 2021/11/30 14:43
|
|
"
|
|
"======================================================================
|
|
|
|
" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" list buffer ids
|
|
"----------------------------------------------------------------------
|
|
function! s:buffer_list()
|
|
let l:ls_cli = get(g:, 'quickui_buffer_list_cli', 'ls t')
|
|
redir => buflist
|
|
silent execute l:ls_cli
|
|
redir END
|
|
let bids = []
|
|
for curline in split(buflist, '\n')
|
|
if curline =~ '^\s*\d\+'
|
|
let bid = str2nr(matchstr(curline, '^\s*\zs\d\+'))
|
|
let bids += [bid]
|
|
endif
|
|
endfor
|
|
return bids
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" get default width
|
|
"----------------------------------------------------------------------
|
|
function! s:get_tools_width()
|
|
let width = get(g:, 'quickui_tools_width', 70)
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" locals
|
|
"----------------------------------------------------------------------
|
|
let s:keymaps = '123456789abcdefimnopqrstuvwxyz'
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" switch buffer callback
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#buffer_switch(bid)
|
|
let switch = get(g:, 'quickui_switch_mode', &switchbuf)
|
|
let code = g:quickui#listbox#current.tag
|
|
let name = fnamemodify(bufname(a:bid), ':p')
|
|
let opts = {}
|
|
let bid = str2nr('' . a:bid)
|
|
if code == ''
|
|
let opts.switch = get(g:, 'quickui_switch_enter', switch)
|
|
call quickui#utils#switch(bid, opts)
|
|
elseif code == '1'
|
|
let opts.switch = get(g:, 'quickui_switch_space', switch)
|
|
call quickui#utils#switch(bid, opts)
|
|
elseif code == '2'
|
|
exec 'b '. a:bid
|
|
elseif code == '3'
|
|
exec 'vs'
|
|
exec 'b '. a:bid
|
|
elseif code == '4'
|
|
exec 'split'
|
|
exec 'b '. a:bid
|
|
elseif code == '5'
|
|
exec 'tab split'
|
|
exec 'b '. a:bid
|
|
elseif code == '6'
|
|
exec 'tab drop ' . fnameescape(name)
|
|
endif
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" get content
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#list_buffer(switch)
|
|
let bids = s:buffer_list()
|
|
let content = []
|
|
let index = 0
|
|
let current = -1
|
|
let bufnr = bufnr()
|
|
let s:switch = a:switch
|
|
for bid in bids
|
|
let key = (index < len(s:keymaps))? strpart(s:keymaps, index, 1) : ''
|
|
let text = '[' . ((key == '')? ' ' : ('&' . key)) . "]\t"
|
|
let text .= "\t"
|
|
let name = fnamemodify(bufname(bid), ':p')
|
|
let main = fnamemodify(name, ':t')
|
|
let path = fnamemodify(name, ':h')
|
|
let buftype = getbufvar(bid, '&buftype')
|
|
if main == ''
|
|
continue
|
|
elseif buftype == 'nofile' || buftype == 'quickfix'
|
|
continue
|
|
endif
|
|
let text = text . main . " " . "(" . bid . ")\t" . path
|
|
let cmd = 'call quickui#tools#buffer_switch(' . bid . ')'
|
|
if a:switch != ''
|
|
" let cmd = a:switch . ' ' . fnameescape(name)
|
|
endif
|
|
let content += [[text, cmd]]
|
|
if bid == bufnr()
|
|
let current = index
|
|
endif
|
|
let index += 1
|
|
endfor
|
|
let opts = {'title': 'Switch Buffer', 'index':current, 'close':'button'}
|
|
let opts.border = g:quickui#style#border
|
|
let opts.keymap = {}
|
|
let opts.keymap["\<space>"] = 'TAG:1'
|
|
let opts.keymap["\<c-e>"] = 'TAG:2'
|
|
let opts.keymap["\<c-]>"] = 'TAG:3'
|
|
let opts.keymap["\<c-x>"] = 'TAG:4'
|
|
let opts.keymap["\<c-t>"] = 'TAG:5'
|
|
let opts.keymap["\<c-g>"] = 'TAG:6'
|
|
if exists('g:quickui_tools_width')
|
|
let opts.w = quickui#utils#tools_width()
|
|
endif
|
|
" let opts.syntax = 'cpp'
|
|
let maxheight = (&lines) * 60 / 100
|
|
if len(content) > maxheight
|
|
let opts.h = maxheight
|
|
endif
|
|
if len(content) == 0
|
|
redraw
|
|
echohl ErrorMsg
|
|
echo "Empty buffer list"
|
|
echohl None
|
|
return -1
|
|
endif
|
|
call quickui#listbox#open(content, opts)
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" list function
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#list_function()
|
|
let ctags = get(g:, 'quickui_ctags_exe', 'ctags')
|
|
if !executable(ctags)
|
|
let msg = 'Not find ctags, add to $PATH or specify in '
|
|
call quickui#utils#errmsg(msg . 'g:quickui_ctags_exe')
|
|
return -1
|
|
endif
|
|
let items = quickui#tags#function_list(bufnr(), &ft)
|
|
if len(items) == 0
|
|
call quickui#utils#errmsg('No content !')
|
|
return -2
|
|
endif
|
|
let content = []
|
|
let cursor = -1
|
|
let index = 0
|
|
let ln = line('.')
|
|
let maxsize = (&columns) * 60 / 100
|
|
let maxheight = (&lines) * 60 / 100
|
|
let maxwidth = 0
|
|
let indents = get(g:, 'quickui_tags_indent', {})
|
|
for item in items
|
|
if ln >= item.line
|
|
let cursor = index
|
|
endif
|
|
let index += 1
|
|
let space = get(indents, item.mode, '')
|
|
let text = '' . item.mode . '' . " \t" . space . item.text
|
|
let text = text . ' [:' . item.line . ']'
|
|
let maxwidth = (maxwidth < len(text))? len(text) : maxwidth
|
|
let text = substitute(text, '&', '&&', 'g')
|
|
let content += [[text, ':' . item.line]]
|
|
endfor
|
|
let opts = {'title': 'Function List', 'close':'button'}
|
|
if cursor >= 0
|
|
let opts.index = cursor
|
|
endif
|
|
let limit = &columns * 90 / 100
|
|
let opts.h = len(content)
|
|
let opts.h = (opts.h < maxheight)? opts.h : maxheight
|
|
let opts.w = (maxwidth < limit)? maxwidth : limit
|
|
if opts.w < maxsize
|
|
let opts.w = (opts.w < 60)? 60 : opts.w
|
|
endif
|
|
let opts.syntax = 'qui_func'
|
|
if exists('g:quickui_tools_width')
|
|
let opts.w = quickui#utils#tools_width()
|
|
endif
|
|
" let content += ["1\t".repeat('0', 100)]
|
|
call quickui#listbox#open(content, opts)
|
|
return 0
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" preview register in popup and choose to paste
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#list_register()
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" display python help in the textbox
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#python_help(word)
|
|
let python = get(g:, 'quickui_tools_python', '')
|
|
if python == ''
|
|
if executable('python')
|
|
let python = 'python'
|
|
elseif executable('python3')
|
|
let python = 'python3'
|
|
elseif executable('python2')
|
|
let python = 'python2'
|
|
endif
|
|
endif
|
|
if a:word == ''
|
|
let text = getline('.')
|
|
let pre = text[:col('.') - 1]
|
|
let suf = text[col('.'):]
|
|
let word = matchstr(pre, "[A-Za-z0-9_.]*$")
|
|
let word = word . matchstr(suf, "^[A-Za-z0-9_]*")
|
|
else
|
|
let word = a:word
|
|
endif
|
|
let cmd = python . ' -m pydoc ' . shellescape(word)
|
|
let title = 'PyDoc <'. a:word . '>'
|
|
let opts = {'title':title}
|
|
let opts.color = 'QuickBG'
|
|
" let opts.bordercolor = 'QuickBG'
|
|
let opts.tabstop = 12
|
|
call quickui#textbox#command(cmd, opts)
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" display messages
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#display_messages()
|
|
let x = ''
|
|
redir => x
|
|
silent! messages
|
|
redir END
|
|
let x = substitute(x, '[\n\r]\+\%$', '', 'g')
|
|
let content = filter(split(x, "\n"), 'v:key != ""')
|
|
if len(content) == 0
|
|
call quickui#utils#errmsg('Empty messages')
|
|
return -1
|
|
endif
|
|
let opts = {"close":"button", "title":"Vim Messages"}
|
|
if exists('g:quickui_tools_width')
|
|
let opts.w = quickui#utils#tools_width()
|
|
endif
|
|
call quickui#textbox#open(content, opts)
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" preview quickfix
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#preview_quickfix(...)
|
|
if quickui#preview#visible()
|
|
call quickui#preview#close()
|
|
return 0
|
|
endif
|
|
if &bt != 'quickfix'
|
|
call quickui#utils#errmsg('Not in quickfix window !')
|
|
return -1
|
|
endif
|
|
if !exists('b:__quickui_qf__')
|
|
let b:__quickui_qf__ = {}
|
|
endif
|
|
let obj = b:__quickui_qf__
|
|
if !has_key(obj, 'version')
|
|
let obj.version = -1
|
|
endif
|
|
if b:changedtick != obj.version
|
|
if getwininfo(win_getid())[0].loclist != 0
|
|
let obj.items = getloclist(0)
|
|
else
|
|
let obj.items = getqflist()
|
|
endif
|
|
let obj.version = b:changedtick
|
|
endif
|
|
let index = (a:0 > 0)? a:1 : line('.')
|
|
if index < 1 || index > len(obj.items)
|
|
call quickui#utils#errmsg('No information in this line')
|
|
return -2
|
|
endif
|
|
let item = obj.items[index - 1]
|
|
if item.valid == 0
|
|
return -3
|
|
endif
|
|
if item.bufnr <= 0
|
|
return -4
|
|
endif
|
|
let name = bufname(item.bufnr)
|
|
let opts = {'cursor':item.lnum}
|
|
call quickui#preview#open(name, opts)
|
|
" echom 'lnum:'. item.lnum
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" preview tag
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#preview_tag(tagname)
|
|
let tagname = (a:tagname == '')? expand('<cword>') : a:tagname
|
|
if tagname == ''
|
|
call quickui#utils#errmsg('Error: empty tagname')
|
|
return 0
|
|
endif
|
|
let obj = quickui#core#object(0)
|
|
let reuse = 0
|
|
if has_key(obj, 'ptag')
|
|
let ptag = obj.ptag
|
|
if get(ptag, 'tagname', '') == tagname
|
|
let reuse = 1
|
|
endif
|
|
endif
|
|
if reuse == 0
|
|
let obj.ptag = {}
|
|
let ptag = obj.ptag
|
|
let ptag.taglist = quickui#tags#tagfind(tagname)
|
|
let ptag.tagname = tagname
|
|
let ptag.index = 0
|
|
else
|
|
let ptag = obj.ptag
|
|
let ptag.index += 1
|
|
if ptag.index >= len(ptag.taglist)
|
|
let ptag.index = 0
|
|
endif
|
|
endif
|
|
if len(ptag.taglist) == 0
|
|
call quickui#utils#errmsg('E257: preview: tag not find "' . tagname . '"')
|
|
return 1
|
|
endif
|
|
if ptag.index >= len(ptag.taglist) || ptag.index < 0
|
|
let ptag.index = 0
|
|
endif
|
|
let taginfo = ptag.taglist[ptag.index]
|
|
let filename = taginfo.filename
|
|
if !filereadable(filename)
|
|
call quickui#utils#errmsg('E484: Can not open file '.filename)
|
|
return 2
|
|
endif
|
|
if !has_key(taginfo, 'line')
|
|
call quickui#utils#errmsg('Error: no "line" information in your tags, regenerate with -n')
|
|
return 3
|
|
endif
|
|
let text = '('.(ptag.index + 1).'/'.len(ptag.taglist).')'
|
|
let opts = {'cursor':taginfo.line, 'title':text}
|
|
call quickui#preview#open(filename, opts)
|
|
let text = taginfo.name
|
|
let text.= ' ('.(ptag.index + 1).'/'.len(ptag.taglist).') '
|
|
let text.= filename
|
|
if has_key(taginfo, 'line')
|
|
let text .= ':'.taginfo.line
|
|
endif
|
|
let display = has('gui_running')? 0 : 1
|
|
let display = get(g:, 'quickui_preview_tag_msg', display)
|
|
if display != 0
|
|
call quickui#utils#print(text, 1)
|
|
endif
|
|
return 0
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" display vim help in popup
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#display_help(tag)
|
|
if !exists('s:help_tags')
|
|
let fn = expand('$VIMRUNTIME/doc/tags')
|
|
if filereadable(fn)
|
|
let content = readfile(fn)
|
|
let s:help_tags = {}
|
|
for line in content
|
|
let parts = split(line, "\t")
|
|
if len(parts) >= 3
|
|
let s:help_tags[parts[0]] = [parts[1], parts[2]]
|
|
endif
|
|
endfor
|
|
endif
|
|
endif
|
|
if !exists('s:help_tags')
|
|
call quickui#utils#errmsg('Sorry, not find help tags in $VIMRUNTIME')
|
|
return -1
|
|
endif
|
|
if !has_key(s:help_tags, a:tag)
|
|
call quickui#utils#errmsg('E149: Sorry, no help for '. a:tag)
|
|
return -2
|
|
endif
|
|
let item = s:help_tags[a:tag]
|
|
let name = expand($VIMRUNTIME . '/doc/' . item[0])
|
|
let command = substitute(item[1], '\*', '', 'g')
|
|
if !filereadable(name)
|
|
call quickui#utils#errmsg('E484: Sorry, cannot open file '.name)
|
|
return -3
|
|
endif
|
|
let content = readfile(name)
|
|
let opts = {'syntax':'help', 'color':'QuickPreview', 'close':'button'}
|
|
let opts.title = 'Help: ' . fnamemodify(name, ':t')
|
|
let g:quickui#tools#hint = item[1]
|
|
let opts.command = ['silent! exec g:quickui#tools#hint']
|
|
let opts.command += ["exec 'nohl'"]
|
|
let opts.command += ["normal zz"]
|
|
let opts.w = 80
|
|
" echom opts
|
|
let winid = quickui#textbox#open(content, opts)
|
|
return 0
|
|
endfunc
|
|
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" save curses help
|
|
"----------------------------------------------------------------------
|
|
let s:previous_cursor = {}
|
|
|
|
function! s:remember_cursor_context(code)
|
|
let hwnd = g:quickui#context#current
|
|
let name = hwnd.opts.keep_name
|
|
let s:previous_cursor[name] = g:quickui#context#cursor
|
|
endfunc
|
|
|
|
function! s:remember_cursor_listbox(code)
|
|
let hwnd = g:quickui#listbox#current
|
|
let name = hwnd.opts.keep_name
|
|
let s:previous_cursor[name] = g:quickui#listbox#cursor
|
|
endfunc
|
|
|
|
function! quickui#tools#clever_context(name, content, opts)
|
|
let opts = deepcopy(a:opts)
|
|
let opts.index = get(s:previous_cursor, a:name, -1)
|
|
let opts.keep_name = a:name
|
|
let opts.callback = function('s:remember_cursor_context')
|
|
let content = quickui#context#reduce_items(a:content)
|
|
call quickui#context#open_nested(content, opts)
|
|
endfunc
|
|
|
|
function! quickui#tools#clever_listbox(name, content, opts)
|
|
let opts = deepcopy(a:opts)
|
|
let opts.index = get(s:previous_cursor, a:name, -1)
|
|
let opts.keep_name = a:name
|
|
let opts.callback = function('s:remember_cursor_listbox')
|
|
call quickui#listbox#open(a:content, opts)
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" terminal
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#terminal(name)
|
|
if !exists('g:quickui_terminal_tools')
|
|
let g:quickui_terminal_tools = {}
|
|
endif
|
|
if !has_key(g:quickui_terminal_tools, a:name)
|
|
call quickui#utils#errmsg('ERROR: tool ' . a:name . ' not defined !')
|
|
return -1
|
|
endif
|
|
let tools = g:quickui_terminal_tools[a:name]
|
|
if !has_key(tools, 'cmd')
|
|
call quickui#utils#errmsg('ERROR: key cmd not present in tool ' . a:name)
|
|
return -1
|
|
endif
|
|
let opts = {}
|
|
let cmd = tools.cmd
|
|
let w = get(g:, 'quickui_terminal_w', 80)
|
|
let h = get(g:, 'quickui_terminal_h', 24)
|
|
let opts.w = get(tools, 'w', w)
|
|
let opts.h = get(tools, 'h', h)
|
|
if has_key(tools, 'color')
|
|
if tools.color != ''
|
|
let opts.color = tools.color
|
|
endif
|
|
endif
|
|
if has_key(tools, 'title')
|
|
let opts.title = tools.title
|
|
endif
|
|
if has_key(tools, 'callback')
|
|
let opts.callback = tools.callback
|
|
endif
|
|
if has_key(tools, 'prepare')
|
|
let opts.prepare = tools.prepare
|
|
endif
|
|
if has_key(tools, 'cwd')
|
|
let opts.cwd = tools.cwd
|
|
endif
|
|
if has_key(tools, 'script')
|
|
let opts.safe = tools.script
|
|
endif
|
|
if has_key(tools, 'pause')
|
|
if tools.pause
|
|
let opts.pause = 1
|
|
endif
|
|
endif
|
|
if has_key(tools, 'close')
|
|
if tools.close
|
|
let opts.close = 1
|
|
endif
|
|
endif
|
|
call quickui#terminal#dialog(cmd, opts)
|
|
return 0
|
|
endfunc
|
|
|
|
|
|
"----------------------------------------------------------------------
|
|
" search inputbox
|
|
"----------------------------------------------------------------------
|
|
function! quickui#tools#input_search()
|
|
let cword = expand('<cword>')
|
|
let title = 'Enter text to search:'
|
|
let text = quickui#input#open(title, cword, 'search')
|
|
redraw
|
|
if text != ''
|
|
let text = escape(text, '[\/*~^.')
|
|
call feedkeys("\<ESC>/" . text . "\<cr>", 'n')
|
|
endif
|
|
endfunc
|
|
|
|
|
|
|