diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index 821aae4d..72074aec 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -97,6 +97,7 @@ function! airline#extensions#tabline#buffers#get() endfunction if has("tablineat") + " Neovim version function! b.get_pretitle(i) dict let bufnum = get(self.buffers, a:i, -1) return '%'.bufnum.'@airline#extensions#tabline#buffers#clickbuf@' @@ -107,6 +108,17 @@ function! airline#extensions#tabline#buffers#get() endfunction 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 let bufnum = get(self.buffers, a:i, -1) let group = self.get_group(a:i) @@ -214,6 +226,61 @@ function! s:map_keys() endif 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 " Clickable buffers " works only in recent NeoVim with has('tablineat') diff --git a/doc/airline.txt b/doc/airline.txt index 140fdabd..b1172e1d 100644 --- a/doc/airline.txt +++ b/doc/airline.txt @@ -266,9 +266,9 @@ values): " disable per-buffer let b:airline_disable_statusline = 1 -< This setting disables setting the 'statusline' option. This allows to use - e.g. the tabline extension (|airline-tabline|) but keep the 'statusline' - option totally configurable by a custom configuration. +< This setting disables setting the 'statusline' option. This allows to use + e.g. the tabline extension (|airline-tabline|) but keep the 'statusline' + option totally configurable by a custom configuration. * Do not draw separators for empty sections (only for the active window) > let g:airline_skip_empty_sections = 1 < @@ -1149,8 +1149,8 @@ are supported! (only supported for ctrlspace plugin). > let g:airline#extensions#tabline#switch_buffers_and_tabs = 0 -Note: If you are using neovim (has('tablineat') = 1), then you can click -on the tabline with the left mouse button to switch to that buffer, and +Note: If you are using Neovim or Vim with at least v9.2.0338, then you can +click on the tabline with the left mouse button to switch to that buffer, and with the middle mouse button to delete that buffer. * if you want to show the current active buffer like this: