diff options
| author | Yaroslav <contact@yaroslavps.com> | 2020-02-25 14:47:03 +0300 | 
|---|---|---|
| committer | Yaroslav <contact@yaroslavps.com> | 2020-02-25 14:47:03 +0300 | 
| commit | d16e82d468eb0d5bb1e662ac4812c0ca6fc0fc64 (patch) | |
| tree | 6575864b75dc0c9de61b5d523e77dbcff785c998 /dotfiles/.vim/autoload/airline/extensions/tabline | |
| parent | 69d47128244a06ee28e4b43191ef9216b04bce13 (diff) | |
| download | vimrice-d16e82d468eb0d5bb1e662ac4812c0ca6fc0fc64.tar.gz vimrice-d16e82d468eb0d5bb1e662ac4812c0ca6fc0fc64.zip | |
reorganized repo to be easier to use with GNU stow; added script to stow
Diffstat (limited to 'dotfiles/.vim/autoload/airline/extensions/tabline')
12 files changed, 1492 insertions, 0 deletions
| diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/autoshow.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/autoshow.vim new file mode 100644 index 0000000..ac1413f --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/autoshow.vim @@ -0,0 +1,55 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1) +let s:buf_min_count = get(g:, 'airline#extensions#tabline#buffer_min_count', 0) +let s:tab_min_count = get(g:, 'airline#extensions#tabline#tab_min_count', 0) + +function! airline#extensions#tabline#autoshow#off() +  if exists('s:original_tabline') +    let &tabline = s:original_tabline +    let &showtabline = s:original_showtabline +  endif + +  augroup airline_tabline_autoshow +    autocmd! +  augroup END +endfunction + +function! airline#extensions#tabline#autoshow#on() +  let [ s:original_tabline, s:original_showtabline ] = [ &tabline, &showtabline ] + +  augroup airline_tabline_autoshow +    autocmd! +    if s:buf_min_count <= 0 && s:tab_min_count <= 1 +      if &lines > 3 +        set showtabline=2 +      endif +    else +      if s:show_buffers == 1 +        autocmd BufEnter  * call <sid>show_tabline(s:buf_min_count, len(airline#extensions#tabline#buflist#list())) +        autocmd BufUnload * call <sid>show_tabline(s:buf_min_count, len(airline#extensions#tabline#buflist#list()) - 1) +      else +        autocmd TabEnter  * call <sid>show_tabline(s:tab_min_count, tabpagenr('$')) +      endif +    endif + +    " Invalidate cache.  This has to come after the BufUnload for +    " s:show_buffers, to invalidate the cache for BufEnter. +    autocmd BufLeave,BufAdd,BufUnload * call airline#extensions#tabline#buflist#invalidate() +  augroup END +endfunction + +function! s:show_tabline(min_count, total_count) +  if a:total_count >= a:min_count +    if &showtabline != 2 && &lines > 3 +      set showtabline=2 +    endif +  else +    if &showtabline != 0 +      set showtabline=0 +    endif +  endif +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/buffers.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/buffers.vim new file mode 100644 index 0000000..88ebe5c --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/buffers.vim @@ -0,0 +1,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 diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/buflist.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/buflist.vim new file mode 100644 index 0000000..a944cb9 --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/buflist.vim @@ -0,0 +1,77 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#buflist#invalidate() +  unlet! s:current_buffer_list +endfunction + +function! airline#extensions#tabline#buflist#clean() +  call airline#extensions#tabline#buflist#invalidate() +  call airline#extensions#tabline#buffers#invalidate() +endfunction + +" paths in excludes list +function! s:ExcludePaths(nr, exclude_paths) +  let bpath = fnamemodify(bufname(a:nr), ":p") +  for f in a:exclude_paths +    if bpath =~# f | return 1 | endif +  endfor +endfunction + +" other types to exclude +function! s:ExcludeOther(nr, exclude_preview) +  if (getbufvar(a:nr, 'current_syntax') == 'qf') || +        \  (a:exclude_preview && getbufvar(a:nr, '&bufhidden') == 'wipe' +        \  && getbufvar(a:nr, '&buftype') == 'nofile') +    return 1 | endif +endfunction + +function! airline#extensions#tabline#buflist#list() +  if exists('s:current_buffer_list') +    return s:current_buffer_list +  endif + +  let exclude_buffers = get(g:, 'airline#extensions#tabline#exclude_buffers', []) +  let exclude_paths = get(g:, 'airline#extensions#tabline#excludes', []) +  let exclude_preview = get(g:, 'airline#extensions#tabline#exclude_preview', 1) + +  let list = (exists('g:did_bufmru') && g:did_bufmru) ? BufMRUList() : range(1, bufnr("$")) + +  let buffers = [] +  " If this is too slow, we can switch to a different algorithm. +  " Basically branch 535 already does it, but since it relies on +  " BufAdd autocommand, I'd like to avoid this if possible. +  for nr in list +    if buflisted(nr) +      " Do not add to the bufferlist, if either +      " 1) bufnr is exclude_buffers list +      " 2) buffername matches one of exclude_paths patterns +      " 3) buffer is a quickfix buffer +      " 4) when excluding preview windows: +      "     'bufhidden' == wipe +      "     'buftype' == nofile +      " 5) ignore buffers matching airline#extensions#tabline#ignore_bufadd_pat + +      " check buffer numbers first +      if index(exclude_buffers, nr) >= 0 +        continue +      " check paths second +      elseif !empty(exclude_paths) && s:ExcludePaths(nr, exclude_paths) +        continue +      " ignore buffers matching airline#extensions#tabline#ignore_bufadd_pat +      elseif airline#util#ignore_buf(bufname(nr)) +        continue +      " check other types last +      elseif s:ExcludeOther(nr, exclude_preview) +        continue +      endif + +      call add(buffers, nr) +    endif +  endfor + +  let s:current_buffer_list = buffers +  return buffers +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim new file mode 100644 index 0000000..20964b1 --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim @@ -0,0 +1,232 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:prototype = {} + +" Set the point in the tabline where the builder should insert the titles. +" +" Subsequent calls will overwrite the previous ones, so only the last call +" determines to location to insert titles. +" +" NOTE: The titles are not inserted until |build| is called, so that the +" remaining contents of the tabline can be taken into account. +" +" Callers should define at least |get_title| and |get_group| on the host +" object before calling |build|. +function! s:prototype.insert_titles(current, first, last) dict +  let self._first_title = a:first " lowest index +  let self._last_title = a:last " highest index +  let self._left_title = a:current " next index to add on the left +  let self._right_title = a:current + 1 " next index to add on the right +  let self._left_position = self.get_position() " left end of titles +  let self._right_position = self._left_position " right end of the titles +endfunction + +" Insert a title for entry number |index|, of group |group| at position |pos|, +" if there is space for it. Returns 1 if it is inserted, 0 otherwise +" +" |force| inserts the title even if there isn't enough space left for it. +" |sep_size| adjusts the size change that the title is considered to take up, +"            to account for changes to the separators +" +" The title is defined by |get_title| on the hosting object, called with +" |index| as its only argument. +" |get_pretitle| and |get_posttitle| may be defined on the host object to +" insert some formatting before or after the title. These should be 0-width. +" +" This method updates |_right_position| and |_remaining_space| on the host +" object, if the title is inserted. +function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict +  let title = self.get_title(a:index) +  let title_size = s:tabline_evaluated_length(title) + a:sep_size +  if a:force || self._remaining_space >= title_size +    let pos = a:pos +    if has_key(self, "get_pretitle") +      call self.insert_raw(self.get_pretitle(a:index), pos) +      let self._right_position += 1 +      let pos += 1 +    endif + +    call self.insert_section(a:group, title, pos) +    let self._right_position += 1 +    let pos += 1 + +    if has_key(self, "get_posttitle") +      call self.insert_raw(self.get_posttitle(a:index), pos) +      let self._right_position += 1 +      let pos += 1 +    endif + +    let self._remaining_space -= title_size +    return 1 +  endif +  return 0 +endfunction + +function! s:get_separator_change(new_group, old_group, end_group, sep_size, alt_sep_size) +  return s:get_separator_change_with_end(a:new_group, a:old_group, a:end_group, a:end_group, a:sep_size, a:alt_sep_size) +endfunction + +" Compute the change in size of the tabline caused by separators +" +" This should be kept up-to-date with |s:get_transitioned_seperator| and +" |s:get_separator| in autoload/airline/builder.vim +function! s:get_separator_change_with_end(new_group, old_group, new_end_group, old_end_group, sep_size, alt_sep_size) +  let sep_change = 0 +  if !empty(a:new_end_group) " Separator between title and the end +    let sep_change += airline#builder#should_change_group(a:new_group, a:new_end_group) ? a:sep_size : a:alt_sep_size +  endif +  if !empty(a:old_group) " Separator between the title and the one adjacent +    let sep_change += airline#builder#should_change_group(a:new_group, a:old_group) ? a:sep_size : a:alt_sep_size +    if !empty(a:old_end_group) " Remove mis-predicted separator +      let sep_change -= airline#builder#should_change_group(a:old_group, a:old_end_group) ? a:sep_size : a:alt_sep_size +    endif +  endif +  return sep_change +endfunction + +" This replaces the build function of the |airline#builder#new| object, to +" insert titles as specified by the last call to |insert_titles| before +" passing to the original build function. +" +" Callers should define at least |get_title| and |get_group| on the host +" object if |insert_titles| has been called on it. +function! s:prototype.build() dict +  if has_key(self, '_left_position') && self._first_title <= self._last_title +    let self._remaining_space = &columns - s:tabline_evaluated_length(self._build()) + +    let center_active = get(g:, 'airline#extensions#tabline#center_active', 0) + +    let sep_size = s:tabline_evaluated_length(self._context.left_sep) +    let alt_sep_size = s:tabline_evaluated_length(self._context.left_alt_sep) + +    let outer_left_group = airline#builder#get_prev_group(self._sections, self._left_position) +    let outer_right_group = airline#builder#get_next_group(self._sections, self._right_position) + +    let overflow_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) +    let overflow_marker_size = s:tabline_evaluated_length(overflow_marker) +    " Allow space for the markers before we begin filling in titles. +    if self._left_title > self._first_title +      let self._remaining_space -= overflow_marker_size + +        \ s:get_separator_change(self.overflow_group, "", outer_left_group, sep_size, alt_sep_size) +    endif +    if self._left_title < self._last_title +      let self._remaining_space -= overflow_marker_size + +        \ s:get_separator_change(self.overflow_group, "", outer_right_group, sep_size, alt_sep_size) +    endif + +    " Add the current title +    let group = self.get_group(self._left_title) +    if self._left_title == self._first_title +      let sep_change = s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) +    else +      let sep_change = s:get_separator_change(group, "", self.overflow_group, sep_size, alt_sep_size) +    endif +    if self._left_title == self._last_title +      let sep_change += s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) +    else +      let sep_change += s:get_separator_change(group, "", self.overflow_group, sep_size, alt_sep_size) +    endif +    let left_group = group +    let right_group = group +    let self._left_title -= +      \ self.try_insert_title(self._left_title, group, self._left_position, sep_change, 1) + +    if get(g:, 'airline#extensions#tabline#current_first', 0) +      " always have current title first +      let self._left_position += 1 +    endif + +    if !center_active && self._right_title <= self._last_title +      " Add the title to the right +      let group = self.get_group(self._right_title) +      if self._right_title == self._last_title +        let sep_change = s:get_separator_change_with_end(group, right_group, outer_right_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size +      else +        let sep_change = s:get_separator_change(group, right_group, self.overflow_group, sep_size, alt_sep_size) +      endif +      let right_group = group +      let self._right_title += +      \ self.try_insert_title(self._right_title, group, self._right_position, sep_change, 1) +    endif + +    while self._remaining_space > 0 +      let done = 0 +      if self._left_title >= self._first_title +        " Insert next title to the left +        let group = self.get_group(self._left_title) +        if self._left_title == self._first_title +          let sep_change = s:get_separator_change_with_end(group, left_group, outer_left_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size +        else +          let sep_change = s:get_separator_change(group, left_group, self.overflow_group, sep_size, alt_sep_size) +        endif +        let left_group = group +        let done = self.try_insert_title(self._left_title, group, self._left_position, sep_change, 0) +        let self._left_title -= done +      endif +      " If center_active is set, this |if| operates as an independent |if|, +      " otherwise as an |elif|. +      if self._right_title <= self._last_title && (center_active || !done) +        " Insert next title to the right +        let group = self.get_group(self._right_title) +        if self._right_title == self._last_title +          let sep_change = s:get_separator_change_with_end(group, right_group, outer_right_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size +        else +          let sep_change = s:get_separator_change(group, right_group, self.overflow_group, sep_size, alt_sep_size) +        endif +        let right_group = group +        let done = self.try_insert_title(self._right_title, group, self._right_position, sep_change, 0) +        let self._right_title += done +      endif +      if !done +        break +      endif +    endwhile + +    if self._left_title >= self._first_title +      if get(g:, 'airline#extensions#tabline#current_first', 0) +        let self._left_position -= 1 +      endif +      call self.insert_section(self.overflow_group, overflow_marker, self._left_position) +      let self._right_position += 1 +    endif + +    if self._right_title <= self._last_title +      call self.insert_section(self.overflow_group, overflow_marker, self._right_position) +    endif +  endif + +  return self._build() +endfunction + +let s:prototype.overflow_group = 'airline_tab' + +" Extract the text content a tabline will render. (Incomplete). +" +" See :help 'statusline' for the list of fields. +function! s:evaluate_tabline(tabline) +  let tabline = a:tabline +  let tabline = substitute(tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') +  let tabline = substitute(tabline, '%#[^#]\+#', '', 'g') +  let tabline = substitute(tabline, '%(\([^)]\+\)%)', '\1', 'g') +  let tabline = substitute(tabline, '%\d\+[TX]', '', 'g') +  let tabline = substitute(tabline, '%=', '', 'g') +  let tabline = substitute(tabline, '%\d*\*', '', 'g') +  if has('tablineat') +    let tabline = substitute(tabline, '%@[^@]\+@', '', 'g') +  endif +  return tabline +endfunction + +function! s:tabline_evaluated_length(tabline) +  return airline#util#strchars(s:evaluate_tabline(a:tabline)) +endfunction + +function! airline#extensions#tabline#builder#new(context) +  let builder = airline#builder#new(a:context) +  let builder._build = builder.build +  call extend(builder, s:prototype, 'force') +  return builder +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/ctrlspace.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/ctrlspace.vim new file mode 100644 index 0000000..bb2d518 --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/ctrlspace.vim @@ -0,0 +1,157 @@ +" MIT License. Copyright (c) 2016-2018 Kevin Sapper et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:current_bufnr = -1 +let s:current_modified = 0 +let s:current_tabnr = -1 +let s:current_tabline = '' +let s:highlight_groups = ['hid', 0, '', 'sel', 'mod_unsel', 0, 'mod_unsel', 'mod'] + +function! airline#extensions#tabline#ctrlspace#off() +  augroup airline_tabline_ctrlspace +    autocmd! +  augroup END +endfunction + +function! airline#extensions#tabline#ctrlspace#on() +  augroup airline_tabline_ctrlspace +    autocmd! +    autocmd BufDelete * call airline#extensions#tabline#ctrlspace#invalidate() +  augroup END +endfunction + +function! airline#extensions#tabline#ctrlspace#invalidate() +  let s:current_bufnr = -1 +  let s:current_tabnr = -1 +endfunction + +function! airline#extensions#tabline#ctrlspace#add_buffer_section(builder, cur_tab, cur_buf, pull_right) +  let pos_extension = (a:pull_right ? '_right' : '') +  let buffer_list = ctrlspace#api#BufferList(a:cur_tab) + +  " add by tenfy(tenfyzhong@qq.com) +  " if the current buffer no in the buffer list +  " return false and no redraw tabline. +  " Fixes #1515. if there a BufEnter autocmd execute redraw. The tabline may no update. +  let bufnr_list = map(copy(buffer_list), 'v:val["index"]') +  if index(bufnr_list, a:cur_buf) == -1 && a:cur_tab == s:current_tabnr +    return 0 +  endif + +  let s:current_modified = getbufvar(a:cur_buf, '&modified') + +  for buffer in buffer_list +    let group = 'airline_tab' +          \ .s:highlight_groups[(4 * buffer.modified) + (2 * buffer.visible) + (a:cur_buf == buffer.index)] +          \ .pos_extension + +    let buf_name = '%(%{airline#extensions#tabline#get_buffer_name('.buffer.index.')}%)' + +    if has("tablineat") +      let buf_name = '%'.buffer.index.'@airline#extensions#tabline#buffers#clickbuf@'.buf_name.'%X' +    endif + +    call a:builder.add_section_spaced(group, buf_name) +  endfor + +  " add by tenfy(tenfyzhong@qq.com) +  " if the selected buffer was updated +  " return true +  return 1 +endfunction + +function! airline#extensions#tabline#ctrlspace#add_tab_section(builder, pull_right) +  let pos_extension = (a:pull_right ? '_right' : '') +  let tab_list = ctrlspace#api#TabList() + +  for tab in tab_list +    let group = 'airline_tab' +          \ .s:highlight_groups[(4 * tab.modified) + (3 * tab.current)] +          \ .pos_extension + +    if get(g:, 'airline#extensions#tabline#ctrlspace_show_tab_nr', 0) == 0 +      call a:builder.add_section_spaced(group, '%'.tab.index.'T'.tab.title.ctrlspace#api#TabBuffersNumber(tab.index).'%T') +    else +      call a:builder.add_section_spaced(group, '%'.(tab.index).'T'.(tab.index).(g:airline_symbols.space).(tab.title).ctrlspace#api#TabBuffersNumber(tab.index).'%T') +    endif +  endfor +endfunction + +function! airline#extensions#tabline#ctrlspace#get() +  let cur_buf = bufnr('%') +  let buffer_label = get(g:, 'airline#extensions#tabline#buffers_label', 'buffers') +  let tab_label = get(g:, 'airline#extensions#tabline#tabs_label', 'tabs') +  let switch_buffers_and_tabs = get(g:, 'airline#extensions#tabline#switch_buffers_and_tabs', 0) + +  try +    call airline#extensions#tabline#tabs#map_keys() +  endtry + +  let cur_tab = tabpagenr() + +  if cur_buf == s:current_bufnr && cur_tab == s:current_tabnr +    if !g:airline_detect_modified || getbufvar(cur_buf, '&modified') == s:current_modified +      return s:current_tabline +    endif +  endif + +  let builder = airline#extensions#tabline#new_builder() + +  let show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1) +  let show_tabs = get(g:, 'airline#extensions#tabline#show_tabs', 1) + +  let AppendBuffers = function('airline#extensions#tabline#ctrlspace#add_buffer_section', [builder, cur_tab, cur_buf]) +  let AppendTabs = function('airline#extensions#tabline#ctrlspace#add_tab_section', [builder]) +  let AppendLabel = function(builder.add_section_spaced, ['airline_tabtype'], builder) + +  " <= 1: |{Tabs}                      <tab| +  " == 2: |{Buffers}               <buffers| +  " == 3: |buffers> {Buffers}  {Tabs} <tabs| +  let showing_mode = (2 * show_buffers) + (show_tabs) +  let ignore_update = 0 + +  " Add left tabline content +  if showing_mode <= 1 " Tabs only mode +    call AppendTabs(0) +  elseif showing_mode == 2 " Buffers only mode +    let ignore_update = !AppendBuffers(0) +  else +    if !switch_buffers_and_tabs +      call AppendLabel(buffer_label) +      let ignore_update = !AppendBuffers(0) +    else +      call AppendLabel(tab_label) +      call AppendTabs(0) +    endif +  endif + +  if ignore_update | return s:current_tabline | endif + +  call builder.add_section('airline_tabfill', '') +  call builder.split() +  call builder.add_section('airline_tabfill', '') + +  " Add right tabline content +  if showing_mode <= 1 " Tabs only mode +    call AppendLabel(tab_label) +  elseif showing_mode == 2 " Buffers only mode +    call AppendLabel(buffer_label) +  else +    if !switch_buffers_and_tabs +      call AppendTabs(1) +      call AppendLabel(tab_label) +    else +      let ignore_update = AppendBuffers(1) +      call AppendLabel(buffer_label) +    endif +  endif + +  if ignore_update | return s:current_tabline | endif + +  let s:current_bufnr = cur_buf +  let s:current_tabnr = cur_tab +  let s:current_tabline = builder.build() +  return s:current_tabline +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/default.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/default.vim new file mode 100644 index 0000000..c98d7ef --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/default.vim @@ -0,0 +1,43 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:fnamecollapse = get(g:, 'airline#extensions#tabline#fnamecollapse', 1) +let s:fnametruncate = get(g:, 'airline#extensions#tabline#fnametruncate', 0) +let s:buf_nr_format = get(g:, 'airline#extensions#tabline#buffer_nr_format', '%s: ') +let s:buf_nr_show = get(g:, 'airline#extensions#tabline#buffer_nr_show', 0) +let s:buf_modified_symbol = g:airline_symbols.modified + +function! airline#extensions#tabline#formatters#default#format(bufnr, buffers) +  let fmod = get(g:, 'airline#extensions#tabline#fnamemod', ':~:.') +  let _ = '' + +  let name = bufname(a:bufnr) +  if empty(name) +    let _ .= '[No Name]' +  else +    if s:fnamecollapse +      " Does not handle non-ascii characters like Cyrillic: 'D/Учёба/t.c' +      "let _ .= substitute(fnamemodify(name, fmod), '\v\w\zs.{-}\ze(\\|/)', '', 'g') +      let _ .= pathshorten(fnamemodify(name, fmod)) +    else +      let _ .= fnamemodify(name, fmod) +    endif +    if a:bufnr != bufnr('%') && s:fnametruncate && strlen(_) > s:fnametruncate +      let _ = strpart(_, 0, s:fnametruncate) +    endif +  endif + +  return airline#extensions#tabline#formatters#default#wrap_name(a:bufnr, _) +endfunction + +function! airline#extensions#tabline#formatters#default#wrap_name(bufnr, buffer_name) +  let _ = s:buf_nr_show ? printf(s:buf_nr_format, a:bufnr) : '' +  let _ .= substitute(a:buffer_name, '\\', '/', 'g') + +  if getbufvar(a:bufnr, '&modified') == 1 +    let _ .= s:buf_modified_symbol +  endif +  return _ +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/jsformatter.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/jsformatter.vim new file mode 100644 index 0000000..b16d06f --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/jsformatter.vim @@ -0,0 +1,15 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#formatters#jsformatter#format(bufnr, buffers) +  let buf = bufname(a:bufnr) +  let filename = fnamemodify(buf, ':t') + +  if filename == 'index.js' || filename == 'index.jsx' || filename == 'index.ts' || filename == 'index.tsx' +    return fnamemodify(buf, ':p:h:t') . '/i' +  else +    return airline#extensions#tabline#formatters#unique_tail_improved#format(a:bufnr, a:buffers) +  endif +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/tabnr.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/tabnr.vim new file mode 100644 index 0000000..fa71014 --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/tabnr.vim @@ -0,0 +1,14 @@ +" MIT License. Copyright (c) 2017-2018 C.Brabandt et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#formatters#tabnr#format(tab_nr_type, nr) +  if a:tab_nr_type == 0 " nr of splits +    return (g:airline_symbols.space).'%{len(tabpagebuflist('.a:nr.'))}' +  elseif a:tab_nr_type == 1 " tab number +    return (g:airline_symbols.space).a:nr +  else "== 2 splits and tab number +    return (g:airline_symbols.space).a:nr.'.%{len(tabpagebuflist('.a:nr.'))}' +  endif +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/unique_tail.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/unique_tail.vim new file mode 100644 index 0000000..3e61b60 --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/unique_tail.vim @@ -0,0 +1,41 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#formatters#unique_tail#format(bufnr, buffers) +  let duplicates = {} +  let tails = {} +  let map = {} +  for nr in a:buffers +    let name = bufname(nr) +    if empty(name) +      let map[nr] = '[No Name]' +    else +      let tail = fnamemodify(name, ':s?/\+$??:t') +      if has_key(tails, tail) +        let duplicates[nr] = nr +      endif +      let tails[tail] = 1 +      let map[nr] = airline#extensions#tabline#formatters#default#wrap_name(nr, tail) +    endif +  endfor + +  let fmod = get(g:, 'airline#extensions#tabline#fnamemod', ':p:.') +  for nr in values(duplicates) +    let name = bufname(nr) +    let fnamecollapse = get(g:, 'airline#extensions#tabline#fnamecollapse', 1) +    if fnamecollapse +      let map[nr] = airline#extensions#tabline#formatters#default#wrap_name(nr, substitute(fnamemodify(name, fmod), '\v\w\zs.{-}\ze(\\|/)', '', 'g')) +    else +      let map[nr] = airline#extensions#tabline#formatters#default#wrap_name(nr, fnamemodify(name, fmod)) +    endif +  endfor + +  if has_key(map, a:bufnr) +    return map[a:bufnr] +  endif + +  " if we get here, the buffer list isn't in sync with the selected buffer yet, fall back to the default +  return airline#extensions#tabline#formatters#default#format(a:bufnr, a:buffers) +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/unique_tail_improved.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/unique_tail_improved.vim new file mode 100644 index 0000000..c48174b --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/formatters/unique_tail_improved.vim @@ -0,0 +1,91 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:skip_symbol = '…' + +function! airline#extensions#tabline#formatters#unique_tail_improved#format(bufnr, buffers) +  if len(a:buffers) <= 1 " don't need to compare bufnames if has less than one buffer opened +    return airline#extensions#tabline#formatters#default#format(a:bufnr, a:buffers) +  endif + +  let curbuf_tail = fnamemodify(bufname(a:bufnr), ':t') +  let do_deduplicate = 0 +  let path_tokens = {} + +  for nr in a:buffers +    let name = bufname(nr) +    if !empty(name) && nr != a:bufnr && fnamemodify(name, ':t') == curbuf_tail " only perform actions if curbuf_tail isn't unique +      let do_deduplicate = 1 +      let tokens = reverse(split(substitute(fnamemodify(name, ':p:h'), '\\', '/', 'g'), '/')) +      let token_index = 0 +      for token in tokens +        if token == '' | continue | endif +        if token == '.' | break | endif +        if !has_key(path_tokens, token_index) +          let path_tokens[token_index] = {} +        endif +        let path_tokens[token_index][token] = 1 +        let token_index += 1 +      endfor +    endif +  endfor + +  if do_deduplicate == 1 +    let path = [] +    let token_index = 0 +    for token in reverse(split(substitute(fnamemodify(bufname(a:bufnr), ':p:h'), '\\', '/', 'g'), '/')) +      if token == '.' | break | endif +      let duplicated = 0 +      let uniq = 1 +      let single = 1 +      if has_key(path_tokens, token_index) +        let duplicated = 1 +        if len(keys(path_tokens[token_index])) > 1 | let single = 0 | endif +        if has_key(path_tokens[token_index], token) | let uniq = 0 | endif +      endif +      call insert(path, {'token': token, 'duplicated': duplicated, 'uniq': uniq, 'single': single}) +      let token_index += 1 +    endfor + +    let buf_name = [curbuf_tail] +    let has_uniq = 0 +    let has_skipped = 0 +    for token1 in reverse(path) +      if !token1['duplicated'] && len(buf_name) > 1 +        call insert(buf_name, s:skip_symbol) +        let has_skipped = 0 +        break +      endif + +      if has_uniq == 1 +        call insert(buf_name, s:skip_symbol) +        let has_skipped = 0 +        break +      endif + +      if token1['uniq'] == 0 && token1['single'] == 1 +        let has_skipped = 1 +      else +        if has_skipped == 1 +          call insert(buf_name, s:skip_symbol) +          let has_skipped = 0 +        endif +        call insert(buf_name, token1['token']) +      endif + +      if token1['uniq'] == 1 +        let has_uniq = 1 +      endif +    endfor + +    if has_skipped == 1 +      call insert(buf_name, s:skip_symbol) +    endif + +    return airline#extensions#tabline#formatters#default#wrap_name(a:bufnr, join(buf_name, '/')) +  else +    return airline#extensions#tabline#formatters#default#format(a:bufnr, a:buffers) +  endif +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/tabs.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/tabs.vim new file mode 100644 index 0000000..a74ab5b --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/tabs.vim @@ -0,0 +1,124 @@ +" 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_tabnr = -1 +let s:current_modified = 0 + +function! airline#extensions#tabline#tabs#off() +  augroup airline_tabline_tabs +    autocmd! +  augroup END +endfunction + +function! airline#extensions#tabline#tabs#on() +  augroup airline_tabline_tabs +    autocmd! +    autocmd BufDelete * call airline#extensions#tabline#tabs#invalidate() +  augroup END +endfunction + +function! airline#extensions#tabline#tabs#invalidate() +  let s:current_bufnr = -1 +endfunction + +function! airline#extensions#tabline#tabs#get() +  let curbuf = bufnr('%') +  let curtab = tabpagenr() +  try +    call airline#extensions#tabline#tabs#map_keys() +  catch +    " no-op +  endtry +  if curbuf == s:current_bufnr && curtab == s:current_tabnr && &columns == s:column_width +    if !g:airline_detect_modified || getbufvar(curbuf, '&modified') == s:current_modified +      return s:current_tabline +    endif +  endif + +  let b = airline#extensions#tabline#new_builder() + +  call airline#extensions#tabline#add_label(b, 'tabs') + +  function! b.get_group(i) dict +    let curtab = tabpagenr() +    let group = 'airline_tab' +    if a:i == curtab +      let group = 'airline_tabsel' +      if g:airline_detect_modified +        for bi in tabpagebuflist(curtab) +          if getbufvar(bi, '&modified') +            let group = 'airline_tabmod' +          endif +        endfor +      endif +      let s:current_modified = (group == 'airline_tabmod') ? 1 : 0 +    endif +    return group +  endfunction + +  function! b.get_title(i) dict +    let val = '%(' + +    if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) +      let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) +      let val .= airline#extensions#tabline#tabs#tabnr_formatter(tab_nr_type, a:i) +    endif + +    return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' +  endfunction + +  call b.insert_titles(curtab, 1, tabpagenr('$')) + +  call b.add_section('airline_tabfill', '') +  call b.split() +  call b.add_section('airline_tabfill', '') + +  if get(g:, 'airline#extensions#tabline#show_close_button', 1) +    call b.add_section('airline_tab_right', ' %999X'. +          \ get(g:, 'airline#extensions#tabline#close_symbol', 'X').' ') +  endif + +  if get(g:, 'airline#extensions#tabline#show_splits', 1) == 1 +    let buffers = tabpagebuflist(curtab) +    for nr in buffers +      let group = airline#extensions#tabline#group_of_bufnr(buffers, nr) . "_right" +      call b.add_section_spaced(group, '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)') +    endfor +    if get(g:, 'airline#extensions#tabline#show_buffers', 1) +      call airline#extensions#tabline#add_label(b, 'buffers') +    endif +  endif + +  let s:current_bufnr = curbuf +  let s:current_tabnr = curtab +  let s:column_width = &columns +  let s:current_tabline = b.build() +  return s:current_tabline +endfunction + +function! airline#extensions#tabline#tabs#map_keys() +  if maparg('<Plug>AirlineSelectTab1', 'n') is# ':1tabn<CR>' +    return +  endif +  noremap <silent> <Plug>AirlineSelectTab1 :1tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab2 :2tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab3 :3tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab4 :4tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab5 :5tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab6 :6tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab7 :7tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab8 :8tabn<CR> +  noremap <silent> <Plug>AirlineSelectTab9 :9tabn<CR> +  noremap <silent> <Plug>AirlineSelectPrevTab gT +  " tabn {count} goes to count tab does not go {count} tab pages forward! +  noremap <silent> <Plug>AirlineSelectNextTab :<C-U>exe repeat(':tabn\|', v:count1)<cr> +endfunction + +function! airline#extensions#tabline#tabs#tabnr_formatter(nr, i) +  let formatter = get(g:, 'airline#extensions#tabline#tabnr_formatter', 'tabnr') +  return airline#extensions#tabline#formatters#{formatter}#format(a:nr, a:i) +endfunction diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/xtabline.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/xtabline.vim new file mode 100644 index 0000000..4d1cdec --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/xtabline.vim @@ -0,0 +1,397 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" xTabline - Reduced version for vim-airline +" Copyright (C) 2018 Gianmaria Bajo <mg1979.git@gmail.com> +" License: MIT License +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + +function! airline#extensions#tabline#xtabline#init() + +    let s:state = 0 + +    " initialize mappings +    call airline#extensions#tabline#xtabline#maps() + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +    " Variables +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    let g:loaded_xtabline = 1 +    let s:most_recent = -1 +    let s:xtabline_filtering = 1 + +    let t:xtl_excluded = get(g:, 'airline#extensions#tabline#exclude_buffers', []) +    let t:xtl_accepted = [] + +    let g:xtabline_include_previews = get(g:, 'xtabline_include_previews', 1) + +    let g:xtabline_alt_action = get(g:, 'xtabline_alt_action', "buffer #") + + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +    " Autocommands +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    augroup plugin-xtabline +        autocmd! + +        autocmd TabNew    * call s:Do('new') +        autocmd TabEnter  * call s:Do('enter') +        autocmd TabLeave  * call s:Do('leave') +        autocmd TabClosed * call s:Do('close') + +        autocmd BufEnter  * let g:xtabline_changing_buffer = 0 +        autocmd BufAdd,BufDelete,BufWrite * call airline#extensions#tabline#xtabline#filter_buffers() +    augroup END + + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +    " Commands +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    com! XTabReopen call airline#extensions#tabline#xtabline#reopen_last_tab() + +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Mappings +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#maps() + +    if !exists('g:xtabline_disable_keybindings') + +        fun! s:mapkeys(keys, plug) +            if empty(mapcheck(a:keys)) && !hasmapto(a:plug) +                silent! execute 'nmap <unique> '.a:keys.' '.a:plug +            endif +        endfun + +        call s:mapkeys('<F5>','<Plug>XTablineToggleTabs') +        call s:mapkeys('<leader><F5>','<Plug>XTablineToggleFiltering') +        call s:mapkeys('<BS>','<Plug>XTablineSelectBuffer') +        call s:mapkeys(']l','<Plug>XTablineNextBuffer') +        call s:mapkeys('[l','<Plug>XTablinePrevBuffer') +        call s:mapkeys('<leader>tr','<Plug>XTablineReopen') +    endif + +    nnoremap <unique> <script> <Plug>XTablineToggleTabs <SID>ToggleTabs +    nnoremap <silent> <SID>ToggleTabs :call airline#extensions#tabline#xtabline#toggle_tabs()<cr> + +    nnoremap <unique> <script> <Plug>XTablineToggleFiltering <SID>ToggleFiltering +    nnoremap <silent> <SID>ToggleFiltering :call airline#extensions#tabline#xtabline#toggle_buffers()<cr> + +    nnoremap <unique> <script> <Plug>XTablineSelectBuffer <SID>SelectBuffer +    nnoremap <silent> <expr> <SID>SelectBuffer g:xtabline_changing_buffer ? "\<C-c>" : ":<C-u>call airline#extensions#tabline#xtabline#select_buffer(v:count)\<cr>" + +    nnoremap <unique> <script> <Plug>XTablineNextBuffer <SID>NextBuffer +    nnoremap <silent> <expr> <SID>NextBuffer airline#extensions#tabline#xtabline#next_buffer(v:count1) + +    nnoremap <unique> <script> <Plug>XTablinePrevBuffer <SID>PrevBuffer +    nnoremap <silent> <expr> <SID>PrevBuffer airline#extensions#tabline#xtabline#prev_buffer(v:count1) + +    nnoremap <unique> <script> <Plug>XTablineReopen <SID>ReopenLastTab +    nnoremap <silent> <SID>ReopenLastTab :XTabReopen<cr> + +    if get(g:, 'xtabline_cd_commands', 0) +        map <unique> <leader>cdc <Plug>XTablineCdCurrent +        map <unique> <leader>cdd <Plug>XTablineCdDown1 +        map <unique> <leader>cd2 <Plug>XTablineCdDown2 +        map <unique> <leader>cd3 <Plug>XTablineCdDown3 +        map <unique> <leader>cdh <Plug>XTablineCdHome +        nnoremap <unique> <script> <Plug>XTablineCdCurrent :cd %:p:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> +        nnoremap <unique> <script> <Plug>XTablineCdDown1   :cd %:p:h:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> +        nnoremap <unique> <script> <Plug>XTablineCdDown2   :cd %:p:h:h:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> +        nnoremap <unique> <script> <Plug>XTablineCdDown3   :cd %:p:h:h:h:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> +        nnoremap <unique> <script> <Plug>XTablineCdHome    :cd ~<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> +    endif +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Commands functions +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#toggle_tabs() +    """Toggle between tabs/buffers tabline.""" + +    if tabpagenr("$") == 1 | call airline#util#warning("There is only one tab.") | return | endif + +    if g:airline#extensions#tabline#show_tabs +        let g:airline#extensions#tabline#show_tabs = 0 +        call airline#util#warning("Showing buffers") +    else +        let g:airline#extensions#tabline#show_tabs = 1 +        call airline#util#warning("Showing tabs") +    endif + +    doautocmd BufAdd +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#toggle_buffers() +    """Toggle buffer filtering in the tabline.""" + +    if s:xtabline_filtering +        let s:xtabline_filtering = 0 +        let g:airline#extensions#tabline#exclude_buffers = [] +        call airline#util#warning("Buffer filtering turned off") +        doautocmd BufAdd +    else +        let s:xtabline_filtering = 1 +        call airline#extensions#tabline#xtabline#filter_buffers() +        call airline#util#warning("Buffer filtering turned on") +        doautocmd BufAdd +    endif +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#reopen_last_tab() +    """Reopen the last closed tab.""" + +    if !exists('s:most_recently_closed_tab') +        call airline#util#warning("No recent tabs.") +        return +    endif + +    let tab = s:most_recently_closed_tab +    tabnew +    let empty = bufnr("%") +    let t:cwd = tab['cwd'] +    cd `=t:cwd` +    let t:name = tab['name'] +    for buf in tab['buffers'] | execute "badd ".buf | endfor +    execute "edit ".tab['buffers'][0] +    execute "bdelete ".empty +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#filter_buffers() +    """Filter buffers so that only the ones within the tab's cwd will show up. + +    " 'accepted' is a list of buffer numbers, for quick access. +    " 'excluded' is a list of buffer numbers, it will be used by Airline to hide buffers. + +    if !s:xtabline_filtering | return | endif + +    let g:airline#extensions#tabline#exclude_buffers = [] +    let t:xtl_excluded = g:airline#extensions#tabline#exclude_buffers +    let t:xtl_accepted = [] | let accepted = t:xtl_accepted +    let previews = g:xtabline_include_previews + +    " bufnr(0) is the alternate buffer +    for buf in range(1, bufnr("$")) + +        if !buflisted(buf) | continue | endif + +        " get the path +        let path = expand("#".buf.":p") + +        " confront with the cwd +        if !previews && path =~ "^".getcwd() +            call add(accepted, buf) +        elseif previews && path =~ getcwd() +            call add(accepted, buf) +        else +            call add(t:xtl_excluded, buf) +        endif +    endfor + +    call s:RefreshTabline() +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#next_buffer(nr) +    """Switch to next visible buffer.""" + +    if ( s:NotEnoughBuffers() || !s:xtabline_filtering ) | return | endif +    let accepted = t:xtl_accepted + +    let ix = index(accepted, bufnr("%")) +    let target = ix + a:nr +    let total = len(accepted) + +    if ix == -1 +        " not in index, go back to most recent or back to first +        if s:most_recent == -1 || s:most_recent >= total +            let s:most_recent = 0 +        endif + +    elseif target >= total +        " over last buffer +        while target >= total | let target -= total | endwhile +        let s:most_recent = target + +    else +        let s:most_recent = target +    endif + +    return ":buffer " . accepted[s:most_recent] . "\<cr>" +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#prev_buffer(nr) +    """Switch to previous visible buffer.""" + +    if ( s:NotEnoughBuffers() || !s:xtabline_filtering ) | return | endif +    let accepted = t:xtl_accepted + +    let ix = index(accepted, bufnr("%")) +    let target = ix - a:nr +    let total = len(accepted) + +    if ix == -1 +        " not in index, go back to most recent or back to first +        if s:most_recent == -1 || s:most_recent >= total +            let s:most_recent = 0 +        endif + +    elseif target < 0 +        " before first buffer +        while target < 0 | let target += total | endwhile +        let s:most_recent = target + +    else +        let s:most_recent = target +    endif + +    return ":buffer " . accepted[s:most_recent] . "\<cr>" +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#select_buffer(nr) +    """Switch to visible buffer in the tabline with [count].""" + +    if ( a:nr == 0 || !s:xtabline_filtering ) | execute g:xtabline_alt_action | return | endif +    let accepted = t:xtl_accepted + +    if (a:nr > len(accepted)) || s:NotEnoughBuffers() || accepted[a:nr - 1] == bufnr("%") +        return +    else +        let g:xtabline_changing_buffer = 1 +        execute "buffer ".accepted[a:nr - 1] +    endif +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:TabBuffers() +    """Return a list of buffers names for this tab.""" + +    return map(copy(t:xtl_accepted), 'bufname(v:val)') +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Helper functions +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:NotEnoughBuffers() +    """Just return if there aren't enough buffers.""" + +    if len(t:xtl_accepted) < 2 +        if index(t:xtl_accepted, bufnr("%")) == -1 +            return +        elseif !len(t:xtl_accepted) +            call airline#util#warning("No available buffers for this tab.") +        else +            call airline#util#warning("No other available buffers for this tab.") +        endif +        return 1 +    endif +endfunction + +function! s:RefreshTabline() +    call airline#extensions#tabline#buflist#invalidate() +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" TabPageCd +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" tabpagecd - Turn :cd into :tabpagecd, to use one tab page per project +" expanded version by mg979 +" Copyright (C) 2012-2013 Kana Natsuno <http://whileimautomaton.net/> +" Copyright (C) 2018 Gianmaria Bajo <mg1979.git@gmail.com> +" License: MIT License + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:InitCwds() +    if !exists('g:xtab_cwds') | let g:xtab_cwds = [] | endif + +    while len(g:xtab_cwds) < tabpagenr("$") +        call add(g:xtab_cwds, getcwd()) +    endwhile +    let s:state    = 1 +    let t:cwd      = getcwd() +    let s:last_tab = 0 +    call airline#extensions#tabline#xtabline#filter_buffers() +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#update_obsession() +    let string = 'let g:xtab_cwds = '.string(g:xtab_cwds).' | call airline#extensions#tabline#xtabline#update_obsession()' +    if !exists('g:obsession_append') +        let g:obsession_append = [string] +    else +        call filter(g:obsession_append, 'v:val !~# "^let g:xtab_cwds"') +        call add(g:obsession_append, string) +    endif +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:Do(action) +    let arg = a:action +    if !s:state | call s:InitCwds() | return | endif + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    if arg == 'new' + +        call insert(g:xtab_cwds, getcwd(), tabpagenr()-1) + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    elseif arg == 'enter' + +        let t:cwd =g:xtab_cwds[tabpagenr()-1] + +        cd `=t:cwd` +        call airline#extensions#tabline#xtabline#filter_buffers() + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    elseif arg == 'leave' + +        let t:cwd = getcwd() +        let g:xtab_cwds[tabpagenr()-1] = t:cwd +        let s:last_tab = tabpagenr() - 1 + +        if !exists('t:name') | let t:name = t:cwd | endif +        let s:most_recent_tab = {'cwd': t:cwd, 'name': t:name, 'buffers': s:TabBuffers()} + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    elseif arg == 'close' + +        let s:most_recently_closed_tab = copy(s:most_recent_tab) +        call remove(g:xtab_cwds, s:last_tab) +    endif + +    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +    call airline#extensions#tabline#xtabline#update_obsession() +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | 
