aboutsummaryrefslogtreecommitdiff
path: root/autoload/hints.vim
diff options
context:
space:
mode:
Diffstat (limited to 'autoload/hints.vim')
-rw-r--r--autoload/hints.vim107
1 files changed, 107 insertions, 0 deletions
diff --git a/autoload/hints.vim b/autoload/hints.vim
new file mode 100644
index 0000000..e7b9a1b
--- /dev/null
+++ b/autoload/hints.vim
@@ -0,0 +1,107 @@
+" Display qutebrowser-like hints.
+
+" Max number of tags is 105, which is LCM(21, 5)
+let s:cons = "bcdfghjklmnpqrstvwxyz" " 21
+let s:vowel = "aeiou" " 5
+
+let s:signs_to_unplace = []
+let s:signs_to_undefine = []
+let s:sign_index = 5555
+
+if !exists('g:hints_ns')
+ let g:hints_ns = nvim_create_namespace("")
+endif
+
+" Generate hints on the current file. This may use specific plugins for each
+" filetype.
+function! s:generate_hints() abort
+ let plugin = hints#plugins#getPluginForFiletype(&ft)
+ call plugin.Before(expand("%"))
+
+ let ci = 0
+ let vi = 0
+
+ let line = line('w0')
+ let endline = line('w$')
+
+ let hints = {}
+
+ while line <= endline
+ if plugin.TagLine(line, getline(line))
+ let tag=printf("%s%s",
+ \ s:cons[ci % len(s:cons)], s:vowel[vi % len(s:vowel)])
+ let hints[tag] = line
+
+ " Advance _both_ the consonants and vowels. We want the tags to generally
+ " have as little in common as possible.
+ let ci += 1
+ let vi += 1
+ endif
+
+ let line += 1
+ endwhile
+
+ return hints
+endfunction
+
+function! s:display_hints(hints) abort
+ let s = s:sign_index
+
+ for [tag, line] in items(a:hints)
+ call add(s:signs_to_undefine, "tag_" . tag)
+ call add(s:signs_to_unplace, s)
+
+ "call nvim_buf_set_virtual_text(
+ " \ 0, g:hints_ns, line - 1, [[tag, "Number"]], {})
+
+ exec printf("sign define tag_%s text=%s texthl=LineNr", tag, tag)
+ exec printf("sign place %d line=%d name=tag_%s file=%s", s, line, tag, expand('%:p'))
+
+ let s += 1
+ endfor
+endfunction
+
+function! s:cleanup_hints() abort
+ call nvim_buf_clear_namespace(0, g:hints_ns, 0, -1)
+ for s in s:signs_to_unplace
+ try
+ exec printf("sign unplace %d", s)
+ catch
+ endtry
+ endfor
+
+ for s in s:signs_to_undefine
+ try
+ exec printf("sign undefine %s", s)
+ catch
+ endtry
+ endfor
+endfunction
+
+function! hints#runHints(visual) abort
+ let hints = s:generate_hints()
+ call s:display_hints(hints)
+ redraw!
+
+ let c1 = getchar()
+
+ if c1 == 0x1b " Escape
+ call s:cleanup_hints()
+ return
+ endif
+
+ let c2 = getchar()
+
+ call s:cleanup_hints()
+
+ let line = get(hints, nr2char(c1) . nr2char(c2), -1)
+
+ if line >= 0
+ norm m'
+ if len(a:visual)
+ exec "norm " . a:visual
+ endif
+ call cursor(line, 1)
+ norm ^
+ endif
+endfunction