tabline: support clickable tabline in Vim (>= v9.2.0338)

closes: #2745

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2026-04-12 08:07:05 +00:00
parent 081f8ac918
commit 723def3fa8
2 changed files with 72 additions and 5 deletions
@@ -97,6 +97,7 @@ function! airline#extensions#tabline#buffers#get()
endfunction endfunction
if has("tablineat") if has("tablineat")
" Neovim version
function! b.get_pretitle(i) dict function! b.get_pretitle(i) dict
let bufnum = get(self.buffers, a:i, -1) let bufnum = get(self.buffers, a:i, -1)
return '%'.bufnum.'@airline#extensions#tabline#buffers#clickbuf@' return '%'.bufnum.'@airline#extensions#tabline#buffers#clickbuf@'
@@ -107,6 +108,17 @@ function! airline#extensions#tabline#buffers#get()
endfunction endfunction
endif endif
if has("statusline_click")
" Vim version
function! b.get_pretitle(i) dict
return '%'.get(self.buffers, a:i, -1).'[airline#extensions#tabline#buffers#clickbufVim]'
endfunction
function! b.get_posttitle(i) dict
return '%[]'
endfunction
endif
function! b.get_title(i) dict function! b.get_title(i) dict
let bufnum = get(self.buffers, a:i, -1) let bufnum = get(self.buffers, a:i, -1)
let group = self.get_group(a:i) let group = self.get_group(a:i)
@@ -214,6 +226,61 @@ function! s:map_keys()
endif endif
endfunction endfunction
function! airline#extensions#tabline#buffers#clickbufVim(dict) abort
" Clickable buffers in Vim, requires v9.2.0338
" single mouse button click without modifiers pressed
if a:dict.nclicks == 1 && empty(a:dict.mods)
if a:dict.button is# 'l'
" left button - switch to buffer
try
silent execute 'buffer' a:dict.minwid
catch
call airline#util#warning("Cannot switch buffer, current buffer is modified! See :h 'hidden'")
endtry
elseif a:dict.button is# 'm'
" middle button - delete buffer
if get(g:, 'airline#extensions#tabline#middle_click_preserves_windows', 0) == 0 || winnr('$') == 1
" just simply delete the clicked buffer. This will cause windows
" associated with the clicked buffer to be closed.
silent execute 'bdelete' a:dict.minwid
else
" find windows displaying the clicked buffer and open an new
" buffer in them.
let current_window = bufwinnr("%")
let window_number = bufwinnr(a:dict.minwid)
let last_window_visited = -1
" Set to 1 if the clicked buffer was open in any windows.
let buffer_in_window = 0
" Find the next window with the clicked buffer open. If bufwinnr()
" returns the same window number, this is because we clicked a new
" buffer, and then tried editing a new buffer. Vim won't create a
" new empty buffer for the same window, so we get the same window
" number from bufwinnr(). In this case we just give up and don't
" delete the buffer.
" This could be made cleaner if we could check if the clicked buffer
" is a new buffer, but I don't know if there is a way to do that.
while window_number != -1 && window_number != last_window_visited
let buffer_in_window = 1
silent execute window_number . 'wincmd w'
silent execute 'enew'
let last_window_visited = window_number
let window_number = bufwinnr(a:minwid)
endwhile
silent execute current_window . 'wincmd w'
if window_number != last_window_visited || buffer_in_window == 0
silent execute 'bdelete' a:dict.minwid
endif
endif
endif
endif
" force a redraw
return 1
endfunction
function! airline#extensions#tabline#buffers#clickbuf(minwid, clicks, button, modifiers) abort function! airline#extensions#tabline#buffers#clickbuf(minwid, clicks, button, modifiers) abort
" Clickable buffers " Clickable buffers
" works only in recent NeoVim with has('tablineat') " works only in recent NeoVim with has('tablineat')
+5 -5
View File
@@ -266,9 +266,9 @@ values):
" disable per-buffer " disable per-buffer
let b:airline_disable_statusline = 1 let b:airline_disable_statusline = 1
< This setting disables setting the 'statusline' option. This allows to use < This setting disables setting the 'statusline' option. This allows to use
e.g. the tabline extension (|airline-tabline|) but keep the 'statusline' e.g. the tabline extension (|airline-tabline|) but keep the 'statusline'
option totally configurable by a custom configuration. option totally configurable by a custom configuration.
* Do not draw separators for empty sections (only for the active window) > * Do not draw separators for empty sections (only for the active window) >
let g:airline_skip_empty_sections = 1 let g:airline_skip_empty_sections = 1
< <
@@ -1149,8 +1149,8 @@ are supported!
(only supported for ctrlspace plugin). > (only supported for ctrlspace plugin). >
let g:airline#extensions#tabline#switch_buffers_and_tabs = 0 let g:airline#extensions#tabline#switch_buffers_and_tabs = 0
Note: If you are using neovim (has('tablineat') = 1), then you can click Note: If you are using Neovim or Vim with at least v9.2.0338, then you can
on the tabline with the left mouse button to switch to that buffer, and click on the tabline with the left mouse button to switch to that buffer, and
with the middle mouse button to delete that buffer. with the middle mouse button to delete that buffer.
* if you want to show the current active buffer like this: * if you want to show the current active buffer like this: