Skip to content

Commit

Permalink
label-mode: replace conceal with virtual text in nvim ≥ 0.5
Browse files Browse the repository at this point in the history
Problem: Using conceal for label interferes with usual syntax highlights
that use conceal.

Solution: In nvim, set decoration provider that renders labels as
virtual text only in the current window.
  • Loading branch information
tomtomjhj committed Jul 11, 2023
1 parent 2bf2ea2 commit 3ff1033
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 20 deletions.
58 changes: 38 additions & 20 deletions autoload/sneak/label.vim
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
let g:sneak#target_labels = get(g:, 'sneak#target_labels', ";sftunq/SFGHLTUNRMQZ?0")

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 @@ -20,9 +26,13 @@ endif

func! s:placematch(c, pos) abort
let s:matchmap[a:c] = a:pos
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)
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
endf

func! s:save_conceal_matches() abort
Expand Down Expand Up @@ -119,14 +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()
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
exec 'hi! link Sneak '.s:orig_hl_sneak

let [&l:concealcursor,&l:conceallevel]=[s:o_cocu,s:o_cole]
endf

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

func! s:before() abort
let s:matchmap = {}
for o in ['cocu', 'cole']
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)

let s:orig_hl_conceal = sneak#util#links_to('Conceal')
call s:save_conceal_matches()
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_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

0 comments on commit 3ff1033

Please sign in to comment.