diff --git a/autoload/fern.vim b/autoload/fern.vim index 2182155..4e0ce4f 100644 --- a/autoload/fern.vim +++ b/autoload/fern.vim @@ -35,6 +35,7 @@ call s:Config.config(expand(':p'), { \ 'disable_drawer_auto_winfixwidth': 0, \ 'disable_drawer_auto_resize': 0, \ 'disable_drawer_smart_quit': get(g:, 'disable_drawer_auto_quit', 0), + \ 'disable_drawer_hover_popup': 0, \ 'disable_drawer_auto_restore_focus': 0, \ 'default_hidden': 0, \ 'default_include': '', diff --git a/autoload/fern/internal/drawer.vim b/autoload/fern/internal/drawer.vim index cf37946..cee211d 100644 --- a/autoload/fern/internal/drawer.vim +++ b/autoload/fern/internal/drawer.vim @@ -51,6 +51,7 @@ function! fern#internal#drawer#init() abort call fern#internal#drawer#auto_winfixwidth#init() call fern#internal#drawer#auto_restore_focus#init() call fern#internal#drawer#smart_quit#init() + call fern#internal#drawer#hover_popup#init() call fern#internal#drawer#resize() setlocal winfixwidth endfunction diff --git a/autoload/fern/internal/drawer/hover_popup.vim b/autoload/fern/internal/drawer/hover_popup.vim new file mode 100644 index 0000000..6729866 --- /dev/null +++ b/autoload/fern/internal/drawer/hover_popup.vim @@ -0,0 +1,63 @@ +function! fern#internal#drawer#hover_popup#init() abort + if g:fern#disable_drawer_hover_popup + return + endif + + if !exists('*popup_create') + call fern#logger#warn('hover popup is not supported, popup_create() + \ does not exist. Disable this message + \ with g:fern#disable_drawer_hover_popup.') + return + endif + + augroup fern_internal_drawer_hover_popup_init + autocmd! * + autocmd CursorMoved call s:cursor_moved_event() + augroup END +endfunction + +function! fern#internal#drawer#hover_popup#calculate_node_char_offset(node) abort + " find line offset where label text begins + let line = getline('.') + let labelbegin = charidx(line, strridx(line, a:node.label)) + let labelbegin = labelbegin < 0 ? 0 : labelbegin + + let windowid = win_getid() + + " get cursor position in drawer window (char- and byte-indexed) + let charpos = getcursorcharpos(windowid) + let pos = getcurpos(windowid) + + " get cursor position relative to screen + let cursorpos = screenpos(windowid, pos[1], pos[2]) + + " calculate screen column where label text begins + return cursorpos['col'] - charpos[2] + labelbegin +endfunction + +function! fern#internal#drawer#hover_popup#should_display_popup() abort + return len(getline('.')) >= winwidth(0) +endfunction + +function! s:cursor_moved_event() abort + let helper = fern#helper#new() + + if fern#internal#drawer#hover_popup#should_display_popup() + call s:show_popup(helper) + endif +endfunction + +function! s:show_popup(helper) abort + let node = a:helper.sync.get_cursor_node() + if node is# v:null + return + endif + + let label_offset = fern#internal#drawer#hover_popup#calculate_node_char_offset(node) + call popup_create(l:node.label, { + \ 'line': 'cursor', + \ 'col': label_offset + 1, + \ 'moved': 'any', + \}) +endfunction + diff --git a/doc/fern.txt b/doc/fern.txt index 49d640e..7f98cfd 100644 --- a/doc/fern.txt +++ b/doc/fern.txt @@ -411,7 +411,15 @@ VARIABLE *fern-variable* of Neovim to avoid unwilling resize reported as #294 https://github.com/lambdalisue/fern.vim/issues/294 - Default: 0 + Default: 0 + +*g:fern#disable_drawer_hover_popup* + Set 1 to disable popups shown when the name of a node extends beyond + the width of the drawer. + + Note that this feature is not supported in Neovim. + + Default: 0 *g:fern#disable_drawer_smart_quit* Set 1 to disable smart quit behavior when there are only two buffer