Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

label-mode: use virtual text in nvim ≥ 0.5 #303

Merged
merged 2 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 32 additions & 47 deletions autoload/sneak/label.vim
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
" NOTES:
" problem: cchar cannot be more than 1 character.
" strategy: make fg/bg the same color, then conceal the other char.
"
" problem: [before 7.4.792] keyword highlight takes priority over conceal.
" strategy: syntax clear | [do the conceal] | let &syntax=s:o_syntax

let g:sneak#target_labels = get(g:, 'sneak#target_labels', ";sftunq/SFGHLTUNRMQZ?0")

let s:clear_syntax = !has('patch-7.4.792')
let s:matchmap = {}
let s:match_ids = []
let s:orig_conceal_matches = []

let s:use_virt_text = has('nvim-0.5')
if s:use_virt_text
call luaeval('require("sneak").init()')
else
let s:match_ids = []
endif

if exists('*strcharpart')
func! s:strchar(s, i) abort
return strcharpart(a:s, a:i, 1)
Expand All @@ -24,10 +26,10 @@ endif

func! s:placematch(c, pos) abort
let s:matchmap[a:c] = a:pos
let pat = '\%'.a:pos[0].'l\%'.a:pos[1].'c.'
if s:clear_syntax
exec "syntax match SneakLabel '".pat."' conceal cchar=".a:c
if s:use_virt_text
call luaeval('require("sneak").placematch(_A[1], _A[2], _A[3])', [a:c, a:pos[0] - 1, a:pos[1] - 1])
else
let pat = '\%'.a:pos[0].'l\%'.a:pos[1].'c.'
let id = matchadd('Conceal', pat, 999, -1, { 'conceal': a:c })
call add(s:match_ids, id)
endif
Expand Down Expand Up @@ -127,25 +129,17 @@ endf "}}}
func! s:after() abort
autocmd! sneak_label_cleanup
try | call matchdelete(s:sneak_cursor_hl) | catch | endtry
call map(s:match_ids, 'matchdelete(v:val)')
let s:match_ids = []
" Remove temporary highlight links.
exec 'hi! link Conceal '.s:orig_hl_conceal
call s:restore_conceal_matches()
exec 'hi! link Sneak '.s:orig_hl_sneak

if s:clear_syntax
let &l:synmaxcol=s:o_synmaxcol
" Always clear before restore, in case user has `:syntax off`. #200
syntax clear
silent! let &l:foldmethod=s:o_fdm
silent! let &l:syntax=s:o_syntax
" Force Vim to reapply 'spell' (must set 'spelllang'). #110
let [&l:spell,&l:spelllang]=[s:o_spell,s:o_spelllang]
call s:restore_conceal_in_other_windows()
if s:use_virt_text
call luaeval('require("sneak").after()')
else
call map(s:match_ids, 'matchdelete(v:val)')
let s:match_ids = []
" Remove temporary highlight links.
exec 'hi! link Conceal '.s:orig_hl_conceal
call s:restore_conceal_matches()
let [&l:concealcursor,&l:conceallevel]=[s:o_cocu,s:o_cole]
endif

let [&l:concealcursor,&l:conceallevel]=[s:o_cocu,s:o_cole]
exec 'hi! link Sneak '.s:orig_hl_sneak
endf

func! s:disable_conceal_in_other_windows() abort
Expand All @@ -168,34 +162,25 @@ endf

func! s:before() abort
let s:matchmap = {}
for o in ['spell', 'spelllang', 'cocu', 'cole', 'fdm', 'synmaxcol', 'syntax']
exe 'let s:o_'.o.'=&l:'.o
endfor

setlocal concealcursor=ncv conceallevel=2

" Highlight the cursor location (because cursor is hidden during getchar()).
let s:sneak_cursor_hl = matchadd("SneakScope", '\%#', 11, -1)

if s:clear_syntax
setlocal nospell
" Prevent highlighting in other windows showing the same buffer.
ownsyntax sneak_label
" Avoid broken folds when we clear syntax below.
if &l:foldmethod ==# 'syntax'
setlocal foldmethod=manual
endif
syntax clear
" This is fast because we cleared syntax. Allows Sneak to work on very long wrapped lines.
setlocal synmaxcol=0
call s:disable_conceal_in_other_windows()
if s:use_virt_text
call luaeval('require("sneak").before()')
else
for o in ['cocu', 'cole']
exe 'let s:o_'.o.'=&l:'.o
endfor
setlocal concealcursor=ncv conceallevel=2

let s:orig_hl_conceal = sneak#util#links_to('Conceal')
call s:save_conceal_matches()
" Set temporary link to our custom 'conceal' highlight.
hi! link Conceal SneakLabel
endif

let s:orig_hl_conceal = sneak#util#links_to('Conceal')
call s:save_conceal_matches()
let s:orig_hl_sneak = sneak#util#links_to('Sneak')
" Set temporary link to our custom 'conceal' highlight.
hi! link Conceal SneakLabel
" Set temporary link to hide the sneak search targets.
hi! link Sneak SneakLabelMask

Expand Down
43 changes: 43 additions & 0 deletions lua/sneak.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
local M = {}

local ns = vim.api.nvim_create_namespace('sneak')

local matches

function M.before()
matches = {}
end

function M.placematch(c, row, col)
matches[#matches+1] = { c, row, col }
end

function M.after()
matches = nil
end

function M.init()
vim.api.nvim_set_decoration_provider(ns, {
on_start = function(_, _)
if not matches then
return false
end
end,
on_win = function(_, win, _, _, _)
if win ~= vim.api.nvim_get_current_win() then
return false
end
for _, m in ipairs(matches) do
local c, row, col = unpack(m)
vim.api.nvim_buf_set_extmark(0, ns, row, col, {
priority = 1000,
virt_text = { {c, 'SneakLabel'} },
virt_text_pos = 'overlay',
ephemeral = true,
})
end
end
})
end

return M