@@ -8,6 +8,7 @@ let s:TYPE = {
8
8
\ ' dict' : type ({}),
9
9
\ ' funcref' : type (function (' call' ))
10
10
\ }
11
+ let s: FLOAT_WINDOW_AVAILABLE = has (' nvim' ) && exists (' *nvim_open_win' )
11
12
12
13
function ! s: AddPrefix (message) abort
13
14
return ' [LC] ' . a: message
@@ -261,6 +262,104 @@ function! s:GetVar(...) abort
261
262
endif
262
263
endfunction
263
264
265
+ function ! s: CloseFloatingHover (bufname , opened) abort
266
+ if getpos (' .' ) == a: opened
267
+ " Just after opening floating window, CursorMoved event is run.
268
+ " To avoid closing floating window immediately, check the cursor
269
+ " was really moved
270
+ return
271
+ endif
272
+ autocmd ! plugin - LC- neovim- close - hover
273
+ let bufnr = bufnr (a: bufname )
274
+ if bufnr == -1
275
+ return
276
+ endif
277
+ let winnr = bufwinnr (bufnr )
278
+ if winnr == -1
279
+ return
280
+ endif
281
+ execute winnr . ' wincmd c'
282
+ endfunction
283
+
284
+ " Open preview window. Window is open in:
285
+ " - Floating window on Neovim (0.4.0 or later)
286
+ " - Preview window on Neovim (0.3.0 or earlier) or Vim
287
+ function ! s: OpenHoverPreview (bufname , lines , filetype ) abort
288
+ " Use local variable since parameter is not modifiable
289
+ let lines = a: lines
290
+
291
+ if s: FLOAT_WINDOW_AVAILABLE
292
+ let pos = getpos (' .' )
293
+
294
+ " Unlike preview window, :pclose does not close window. Instead, close
295
+ " hover window automatically when cursor is moved.
296
+ let params = printf (' "%s", %s' , a: bufname , string (pos))
297
+ augroup plugin - LC- neovim- close - hover
298
+ execute ' autocmd CursorMoved,CursorMovedI,InsertEnter <buffer> call <SID>CloseFloatingHover(' . params . ' )'
299
+ augroup END
300
+
301
+ " Calculate width and height and give margin to lines
302
+ let width = 0
303
+ for index in range (len (lines ))
304
+ let line = ' ' . lines [index ]
305
+ let lw = strdisplaywidth (line )
306
+ if lw > width
307
+ let width = lw
308
+ endif
309
+ let lines [index ] = line
310
+ endfor
311
+
312
+ " Give margin
313
+ let width += 1
314
+ let lines = [' ' ] + lines + [' ' ]
315
+ let height = len (lines )
316
+
317
+ " Calculate anchor
318
+ " Prefer North, but if there is no space, fallback into South
319
+ if pos[1 ] + height <= &lines
320
+ let vert = ' N'
321
+ let row = 1
322
+ else
323
+ let vert = ' S'
324
+ let row = 0
325
+ endif
326
+
327
+ " Prefer West, but if there is no space, fallback into East
328
+ if pos[2 ] + width <= &columns
329
+ let hor = ' W'
330
+ let col = 0
331
+ else
332
+ let hor = ' E'
333
+ let col = 1
334
+ endif
335
+
336
+ call nvim_open_win (bufnr (' %' ), v: true , width, height, {
337
+ \ ' relative' : ' cursor' ,
338
+ \ ' anchor' : vert . hor ,
339
+ \ ' row' : row,
340
+ \ ' col' : col ,
341
+ \ })
342
+
343
+ execute ' noswapfile edit!' a: bufname
344
+
345
+ setlocal winhl= Normal :CursorLine
346
+ else
347
+ execute ' silent! noswapfile pedit!' a: bufname
348
+ wincmd P
349
+ endif
350
+
351
+ setlocal buftype = nofile nobuflisted bufhidden = wipe nonumber norelativenumber signcolumn = no
352
+
353
+ if a: filetype isnot v: null
354
+ let &filetype = a: filetype
355
+ endif
356
+
357
+ call setline (1 , lines )
358
+ setlocal nomodified nomodifiable
359
+
360
+ wincmd p
361
+ endfunction
362
+
264
363
let s: id = 1
265
364
let s: handlers = {}
266
365
0 commit comments