aboutsummaryrefslogtreecommitdiff
path: root/dotfiles/.vim/autoload/airline/extensions/tabline/buffers.vim
blob: 88ebe5c81774d302ce6245479bac76ae01062e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
" MIT License. Copyright (c) 2013-2018 Bailey Ling et al.
" vim: et ts=2 sts=2 sw=2

scriptencoding utf-8

let s:spc = g:airline_symbols.space

let s:current_bufnr = -1
let s:current_modified = 0
let s:current_tabline = ''
let s:current_visible_buffers = []

let s:number_map = {
      \ '0': '⁰',
      \ '1': '¹',
      \ '2': '²',
      \ '3': '³',
      \ '4': '⁴',
      \ '5': '⁵',
      \ '6': '⁶',
      \ '7': '⁷',
      \ '8': '⁸',
      \ '9': '⁹'
      \ }
let s:number_map = &encoding == 'utf-8'
      \ ? get(g:, 'airline#extensions#tabline#buffer_idx_format', s:number_map)
      \ : {}

function! airline#extensions#tabline#buffers#off()
  augroup airline_tabline_buffers
    autocmd!
  augroup END
endfunction

function! airline#extensions#tabline#buffers#on()
  augroup airline_tabline_buffers
    autocmd!
    autocmd BufDelete * call airline#extensions#tabline#buflist#clean()
    autocmd User BufMRUChange call airline#extensions#tabline#buflist#clean()
  augroup END
endfunction

function! airline#extensions#tabline#buffers#invalidate()
  let s:current_bufnr = -1
endfunction

function! airline#extensions#tabline#buffers#get()
  try
    call <sid>map_keys()
  catch
    " no-op
  endtry
  let cur = bufnr('%')
  if cur == s:current_bufnr && &columns == s:column_width
    if !g:airline_detect_modified || getbufvar(cur, '&modified') == s:current_modified
      return s:current_tabline
    endif
  endif

  let b = airline#extensions#tabline#new_builder()
  let tab_bufs = tabpagebuflist(tabpagenr())
  let show_buf_label_first = 0

  if get(g:, 'airline#extensions#tabline#buf_label_first', 0)
    let show_buf_label_first = 1
  endif
  if show_buf_label_first
    call airline#extensions#tabline#add_label(b, 'buffers')
  endif

  let b.tab_bufs = tabpagebuflist(tabpagenr())

  let b.overflow_group = 'airline_tabhid'
  let b.buffers = airline#extensions#tabline#buflist#list()
  if get(g:, 'airline#extensions#tabline#current_first', 0)
    if index(b.buffers, cur) > -1
      call remove(b.buffers, index(b.buffers, cur))
    endif
    let b.buffers = [cur] + b.buffers
  endif

  function! b.get_group(i) dict
    let bufnum = get(self.buffers, a:i, -1)
    if bufnum == -1
      return ''
    endif
    let group = airline#extensions#tabline#group_of_bufnr(self.tab_bufs, bufnum)
    if bufnum == bufnr('%')
      let s:current_modified = (group == 'airline_tabmod') ? 1 : 0
    endif
    return group
  endfunction

  if has("tablineat")
    function! b.get_pretitle(i) dict
      let bufnum = get(self.buffers, a:i, -1)
      return '%'.bufnum.'@airline#extensions#tabline#buffers#clickbuf@'
    endfunction

    function! b.get_posttitle(i) dict
      return '%X'
    endfunction
  endif

  function! b.get_title(i) dict
    let bufnum = get(self.buffers, a:i, -1)
    let group = self.get_group(a:i)
    let pgroup = self.get_group(a:i - 1)
    " always add a space when powerline_fonts are used
    " or for the very first item
    if get(g:, 'airline_powerline_fonts', 0) || a:i == 0
      let space = s:spc
    else
      let space= (pgroup == group ? s:spc : '')
    endif

    if get(g:, 'airline#extensions#tabline#buffer_idx_mode', 0)
      if len(s:number_map) > 0
        return space. get(s:number_map, a:i+1, '') . '%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)' . s:spc
      else
        return '['.(a:i+1).s:spc.'%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)'.']'
      endif
    else
      return space.'%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)'.s:spc
    endif
  endfunction

  let current_buffer = max([index(b.buffers, cur), 0])
  let last_buffer = len(b.buffers) - 1
  call b.insert_titles(current_buffer, 0, last_buffer)

  call b.add_section('airline_tabfill', '')
  call b.split()
  call b.add_section('airline_tabfill', '')
  if !show_buf_label_first
    call airline#extensions#tabline#add_label(b, 'buffers')
  endif

  if tabpagenr('$') > 1
    call b.add_section_spaced('airline_tabmod', printf('%s %d/%d', "tab", tabpagenr(), tabpagenr('$')))
  endif

  let s:current_bufnr = cur
  let s:column_width = &columns
  let s:current_tabline = b.build()
  let s:current_visible_buffers = copy(b.buffers)
  if b._right_title <= last_buffer
    call remove(s:current_visible_buffers, b._right_title, last_buffer)
  endif
  if b._left_title > 0
    call remove(s:current_visible_buffers, 0, b._left_title)
  endif
  return s:current_tabline
endfunction

function! s:select_tab(buf_index)
  " no-op when called in 'keymap_ignored_filetypes'
  if count(get(g:, 'airline#extensions#tabline#keymap_ignored_filetypes', 
        \ ['vimfiler', 'nerdtree']), &ft)
    return
  endif

  let idx = a:buf_index
  if s:current_visible_buffers[0] == -1
    let idx = idx + 1
  endif

  let buf = get(s:current_visible_buffers, idx, 0)
  if buf != 0
    exec 'b!' . buf
  endif
endfunction

function! s:jump_to_tab(offset)
    let l = airline#extensions#tabline#buflist#list()
    let i = index(l, bufnr('%'))
    if i > -1
        exec 'b!' . l[(i + a:offset) % len(l)]
    endif
endfunction

function! s:map_keys()
  if get(g:, 'airline#extensions#tabline#buffer_idx_mode', 1)
    noremap <silent> <Plug>AirlineSelectTab1 :call <SID>select_tab(0)<CR>
    noremap <silent> <Plug>AirlineSelectTab2 :call <SID>select_tab(1)<CR>
    noremap <silent> <Plug>AirlineSelectTab3 :call <SID>select_tab(2)<CR>
    noremap <silent> <Plug>AirlineSelectTab4 :call <SID>select_tab(3)<CR>
    noremap <silent> <Plug>AirlineSelectTab5 :call <SID>select_tab(4)<CR>
    noremap <silent> <Plug>AirlineSelectTab6 :call <SID>select_tab(5)<CR>
    noremap <silent> <Plug>AirlineSelectTab7 :call <SID>select_tab(6)<CR>
    noremap <silent> <Plug>AirlineSelectTab8 :call <SID>select_tab(7)<CR>
    noremap <silent> <Plug>AirlineSelectTab9 :call <SID>select_tab(8)<CR>
    noremap <silent> <Plug>AirlineSelectPrevTab :<C-u>call <SID>jump_to_tab(-v:count1)<CR>
    noremap <silent> <Plug>AirlineSelectNextTab :<C-u>call <SID>jump_to_tab(v:count1)<CR>
  endif
endfunction

function! airline#extensions#tabline#buffers#clickbuf(minwid, clicks, button, modifiers) abort
    " Clickable buffers
    " works only in recent NeoVim with has('tablineat')

    " single mouse button click without modifiers pressed
    if a:clicks == 1 && a:modifiers !~# '[^ ]'
      if a:button is# 'l'
        " left button - switch to buffer
        silent execute 'buffer' a:minwid
      elseif a: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:minwid
        else
          " find windows displaying the clicked buffer and open an new
          " buffer in them.
          let current_window = bufwinnr("%")
          let window_number = bufwinnr(a: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:minwid
          endif
        endif
      endif
    endif
endfunction