Skip to content

feat(icon): support using highlight group in add_icon_fn() #256

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*]
indent_style = space
indent_size = 2
tab_width = 2
34 changes: 23 additions & 11 deletions autoload/dirvish.vim
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ let s:noswapfile = (2 == exists(':noswapfile')) ? 'noswapfile' : ''
let s:noau = 'silent noautocmd keepjumps'
let s:cb_map = {} " callback map
let s:rel = get(g:, 'dirvish_relative_paths', 0)
let s:virttext_feat = has('nvim-0.8') ? 'extmark' : ((v:version >= 901 && has('textprop'))? 'textprop': 'conceal')

" Debug:
" echo '' > dirvish.log ; tail -F dirvish.log
@@ -426,12 +427,11 @@ func! s:apply_icons() abort
if 0 == len(s:cb_map)
return
endif
let l:feat = has('nvim-0.8') ? 'extmark' : ((v:version >= 901 && has('textprop'))? 'textprop': 'conceal')
if l:feat ==# 'extmark'
if s:virttext_feat ==# 'extmark'
if !exists('s:ns_id')
let s:ns_id = nvim_create_namespace('dirvish.icons')
endif
elseif l:feat ==# 'textprop'
elseif s:virttext_feat ==# 'textprop'
if !exists('s:prop_type')
let s:prop_type = 'dirvish.icons'
call prop_type_add(s:prop_type, {})
@@ -443,24 +443,36 @@ func! s:apply_icons() abort
let i = 0
for f in getline(1, '$')
let i += 1
let icon = ''
for id in sort(keys(s:cb_map))
let icon = s:cb_map[id](f)
if -1 != match(icon, '\S')
break
if type(icon) == type('')
if -1 != match(icon, '\S')
unlet icon
break
endif
endif
endfor
if icon != ''
if l:feat ==# 'extmark'
call nvim_buf_set_extmark(0, s:ns_id, i-1, 0, #{virt_text: [[icon, 'DirvishColumnHead']], virt_text_pos: 'inline'})
elseif l:feat ==# 'textprop'
call prop_add(i, 1, #{type: s:prop_type, text: icon})
if exists('l:icon')
if s:virttext_feat ==# 'extmark'
let l:virt_text = type(icon) == type({}) ? [[icon.icon, icon.hl]] : [[icon, 'DirvishColumnHead']]
call nvim_buf_set_extmark(0, s:ns_id, i-1, 0, #{virt_text: l:virt_text, virt_text_pos: 'inline'})
elseif s:virttext_feat ==# 'textprop'
if type(icon) == type('')
call prop_add(i, 1, #{type: s:prop_type, text: icon})
else
let l:prop_type = prop_type_get('dirvish.'.icon.hl, {})
if l:prop_type == {}
call prop_type_add('dirvish.'.icon.hl, #{highlight: icon.hl})
endif
call prop_add(i, 1, #{type: 'dirvish.'.icon.hl, text: icon.icon})
endif
else
let isdir = (f[-1:] == s:sep)
let f = substitute(s:f(f), escape(s:sep,'\').'$', '', 'g') " Full path, trim slash.
let tail_esc = escape(fnamemodify(f,':t').(isdir?(s:sep):''), '[,*.^$~\')
exe 'syntax match DirvishColumnHead =\%'.i.'l^.\{-}\ze'.tail_esc.'$= conceal cchar='.icon
endif
unlet icon
endif
endfor
endf
23 changes: 19 additions & 4 deletions doc/dirvish.txt
Original file line number Diff line number Diff line change
@@ -114,12 +114,27 @@ dirvish#add_icon_fn(fn)
a given path, wins. Best practice: if you don't have anything meaningful
to show for a given path, return empty string (or whitespace).

{fn} is any |Funcref| that takes a path (string) and returns a string
(the "icon"). Example: >vim
{fn} is any |Funcref| that takes a path (string) and returns an `icon-item` as
a |string| or a |dict| with the following keys:
- "icon" (|string|): the string representing the icon.
- "hl" (|string|): the highlight group to use for the icon.

Note: If your Vim isn't Vim 9.1+ with |+textprop| or Nvim 0.8+, `icon-item`
can only be a character.

Example that returns a string: >vim
call dirvish#add_icon_fn({p -> p[-1:]=='/'?'📂':'📄'})
<
Note: multi-character icons are only supported on Nvim 0.8+ or Vim 9.1+
with |+textprop|.
Example that uses |mini.icons| <https://github.com/echasnovski/mini.icons>
0.15.0 as icon provider >lua
--- NOTE: mini.icons must be loaded before vim-dirvish
vim.fn['dirvish#add_icon_fn'](function(p)
local get = require('mini.icons').get
local icon, hl = get(p:sub(-1) == '/' and 'directory' or 'file', p)
icon = icon .. ' '
return { icon = icon, hl = hl }
end)
<

*dirvish#remove_icon_fn()*
dirvish#remove_icon_fn(fn_id)