diff options
-rw-r--r-- | autoload/hints.vim | 45 | ||||
-rw-r--r-- | autoload/hints/plugins.vim | 92 |
2 files changed, 85 insertions, 52 deletions
diff --git a/autoload/hints.vim b/autoload/hints.vim index ac0a3e5..757fc5f 100644 --- a/autoload/hints.vim +++ b/autoload/hints.vim @@ -1,6 +1,6 @@ " Display qutebrowser-like hints. -" Max number of tags is 105, which is LCM(21, 5) +" Max number of tags is 105, which is LCM(21, 5) because 21 and 5 are coprime let s:cons = "tnshrdlcumwfgypkbvjxqz" " 21 let s:vowel = "aeiou" " 5 @@ -20,25 +20,34 @@ function! s:generate_hints() abort let plugin = hints#plugins#getPluginForFiletype(&ft) call plugin.Before(expand("%")) - let line = line('w0') - let endline = line('w$') + let cur_line = line('.') + let line = 1 let hints = {} + let tag_hints = {} for i in marklist - let hints[i.mark] = i.pos[1] + let tag_hints[i.mark] = i.pos[1] endfor - while line <= endline + let hints_left = len(s:vowel) * len(s:cons) + let last_line = line('$') + + let cnt = 0 + while line <= last_line if plugin.TagLine(line, getline(line)) let tag=printf("%s%s", - \ s:cons[line % len(s:cons)], s:vowel[line % len(s:vowel)]) - let hints[tag] = line + \ s:cons[cnt % len(s:cons)], s:vowel[cnt % len(s:vowel)]) + let cnt += 1 + " We want to keep the hints closest to the cursor line. + if !has_key(hints, tag) || abs(cur_line - hints[tag]) > abs(cur_line - line) + let hints[tag] = line + endif endif let line += 1 endwhile - return hints + return extend(tag_hints, hints, 'force') endfunction function! s:display_hints(hints) abort @@ -76,15 +85,21 @@ function! s:cleanup_hints() abort endfunction function! s:get(hint_dict, str) abort + if a:str =~ '^[A-Z]\+$' + let [a, _] = s:get(a:hint_dict, tolower(a:str)) + return [a, "^"] + endif + if has_key(a:hint_dict, a:str) - return a:hint_dict[a:str] + return [a:hint_dict[a:str], col('.') . '|'] endif if len(a:str) == 1 || a:str[0] == a:str[1] - return s:get(a:hint_dict, "'" . a:str[0]) + let [a, _] = s:get(a:hint_dict, "'" . a:str[0]) + return [a, "`" . a:str[0]] endif - return -1 + return [-1, ''] endfunction function! hints#runHints(visual) abort @@ -99,7 +114,7 @@ function! hints#runHints(visual) abort return endif - if stridx(s:cons, nr2char(c1)) >= 0 || nr2char(c1) == "'" + if stridx(s:cons, tolower(nr2char(c1))) >= 0 || nr2char(c1) == "'" let c2 = getchar() else let c2 = "" @@ -107,7 +122,7 @@ function! hints#runHints(visual) abort call s:cleanup_hints() - let line = s:get(hints, nr2char(c1) . nr2char(c2)) + let [line, act] = s:get(hints, nr2char(c1) . nr2char(c2)) if line >= 0 if a:visual == 'o' @@ -115,6 +130,8 @@ function! hints#runHints(visual) abort endif norm m' call cursor(line, 1) - norm ^ + if len(act) > 0 + exec "norm! " . act + endif endif endfunction diff --git a/autoload/hints/plugins.vim b/autoload/hints/plugins.vim index 7f22301..3f080d7 100644 --- a/autoload/hints/plugins.vim +++ b/autoload/hints/plugins.vim @@ -1,5 +1,4 @@ let s:ftplugins = {} -let s:default_plugin = {} let s:vim_plugin = {} function! s:vim_plugin.Before(file) @@ -8,32 +7,37 @@ function! s:vim_plugin.TagLine(linenr, line) return a:line =~ '\<\(if\|function\|return\|end\w*\|while\|for\|let\|else\|try\)\>' endfunction +let s:WHITESPACE_OR_COMMENT='\(^\s*$\)\|\(^\s*//\)\|\(^\s*\*/\)' let s:java_plugin = {} +function! s:java_plugin.new() dict + let ret = {} -function! s:java_plugin.Before(file) dict - let self.last_line = '' - let self.last_indent = '' -endfunction + function! ret.Before(file) dict + let self.last_line = '' + let self.last_indent = '' + endfunction + + function! ret.TagLine(linenr, line) dict + if self.last_line =~ s:WHITESPACE_OR_COMMENT + \ && !(a:line =~ s:WHITESPACE_OR_COMMENT) + let self.last_line = a:line + return v:true + endif -let s:WHITESPACE_OR_COMMENT='\(^\s*$\)\|\(^\s*//\)\|\(^\s*\*/\)' -function! s:java_plugin.TagLine(linenr, line) dict - if self.last_line =~ s:WHITESPACE_OR_COMMENT - \ && !(a:line =~ s:WHITESPACE_OR_COMMENT) let self.last_line = a:line - return v:true - endif + let indent = matchlist(a:line, '^\s*') + let indent = len(indent) > 0 ? indent[0] : "" + if self.last_indent != indent + let self.last_indent = indent + return v:true + endif - let self.last_line = a:line - let indent = matchlist(a:line, '^\s*') - let indent = len(indent) > 0 ? indent[0] : "" - if self.last_indent != indent - let self.last_indent = indent - return v:true - endif + return + \ a:line =~ '^\s*}$' || + \ a:line =~ '\<\(public\|private\|protected\|class\|static\|try\|while\|for\|if\|else\|catch\)\>' + endfunction - return - \ a:line =~ '^\s*}$' || - \ a:line =~ '\<\(public\|private\|protected\|class\|static\|try\|while\|for\|if\|else\|catch\)\>' + return ret endfunction function! hints#plugins#registerFt(filetype, plugin) abort @@ -41,35 +45,47 @@ function! hints#plugins#registerFt(filetype, plugin) abort endfunction function! hints#plugins#getPluginForFiletype(filetype) abort - return get(s:ftplugins, a:filetype, s:default_plugin) + let plug = get(s:ftplugins, a:filetype, s:default_plugin) + if has_key(plug, "new") + let plug = plug.new() + endif + return plug endfunction +let s:default_plugin = {} function! hints#plugins#getDefaultPlugin() abort return s:default_plugin endfunction -function! s:default_plugin.Before(file) - let self.last_kind = 1 -endfunction let s:ISSPACE = '^\s*$' let s:ISCOMMENT = '^\s*[-/#;"(]' -function! s:default_plugin.TagLine(linenr, line) - if a:line =~ s:ISSPACE - let kind = 1 - elseif a:line =~ s:ISCOMMENT - let kind = 2 - else - let kind = 3 - endif +function! s:default_plugin.new() + let ret = {} + + function! ret.Before(file) + let self.last_kind = 1 + endfunction + + function! ret.TagLine(linenr, line) + if a:line =~ s:ISSPACE + let kind = 1 + elseif a:line =~ s:ISCOMMENT + let kind = 2 + else + let kind = 3 + endif + + if self.last_kind != kind && kind != 1 + let self.last_kind = kind + return v:true + endif - if self.last_kind != kind && kind != 1 let self.last_kind = kind - return v:true - endif + return v:false + endfunction - let self.last_kind = kind - return v:false + return ret endfunction call hints#plugins#registerFt("vim", s:vim_plugin) |