From f60cf736db5ef551ad9adc5df3e3f50dc3e956cb Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sat, 10 Mar 2018 01:04:18 +0000 Subject: [PATCH 01/54] Add a get_tabs function to abstract over tabs --- autoload/airline/extensions/tabline/tabs.vim | 24 ++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 54019b5..d7b662f 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -25,6 +25,20 @@ function! airline#extensions#tabline#tabs#invalidate() let s:current_bufnr = -1 endfunction +function! s:get_tabs() + let tablist = range(1, tabpagenr('$')) + let curbuf = bufnr('%') + + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current tabpage first + if index(tablist, curtab) > -1 + call remove(tablist, index(tablist, curtab)) + endif + let tablist = [curtab] + tablist + endif + return tablist +endfunction + function! airline#extensions#tabline#tabs#get() let curbuf = bufnr('%') let curtab = tabpagenr() @@ -43,15 +57,7 @@ function! airline#extensions#tabline#tabs#get() let b = airline#extensions#tabline#new_builder() call airline#extensions#tabline#add_label(b, 'tabs') - " always have current tabpage first - let tablist = range(1, tabpagenr('$')) - if get(g:, 'airline#extensions#tabline#current_first', 0) - if index(tablist, curtab) > -1 - call remove(tablist, index(tablist, curtab)) - endif - let tablist = [curtab] + tablist - endif - for i in tablist + for i in s:get_tabs() if i == curtab let group = 'airline_tabsel' if g:airline_detect_modified From abd310bb313d100536a1419208b451b9fa0f852b Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sat, 10 Mar 2018 01:22:03 +0000 Subject: [PATCH 02/54] Show current tab in the middle of the tabline This is heavily based on 3cc1dcb6976ba6ea64f534cdb646f69d41f49b4c, mostly by copying the get_visible_buffers function and making some tweaks --- autoload/airline/extensions/tabline/tabs.vim | 54 +++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index d7b662f..84b8b4d 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -25,7 +25,7 @@ function! airline#extensions#tabline#tabs#invalidate() let s:current_bufnr = -1 endfunction -function! s:get_tabs() +function! s:get_visible_tabs() let tablist = range(1, tabpagenr('$')) let curbuf = bufnr('%') @@ -36,6 +36,52 @@ function! s:get_tabs() endif let tablist = [curtab] + tablist endif + + let total_width = 0 + let max_width = 0 + + for nr in tablist + let width = len(airline#extensions#tabline#title(nr)) + 4 + let total_width += width + let max_width = max([max_width, width]) + endfor + + " only show current and surrounding tabs if there are too many tabs + let position = index(tablist, curbuf) + let vimwidth = &columns + if total_width > vimwidth && position > -1 + let tab_count = len(tablist) + + " determine how many tabs to show based on the longest tab width, + " use one on the right side and put the rest on the left + let tab_max = vimwidth / max_width + let tab_right = 1 + let tab_left = max([0, tab_max - tab_right]) + + let start = max([0, position - tab_left]) + let end = min([tab_count, position + tab_right]) + + " fill up available space on the right + if position < tab_left + let end += (tab_left - position) + endif + + " fill up available space on the left + if end > tab_count - 1 - tab_right + let start -= max([0, tab_right - (tab_count - 1 - position)]) + endif + + let tablist = eval('tablist[' . start . ':' . end . ']') + + if start > 0 + call insert(tablist, -1, 0) + endif + + if end < tab_count - 1 + call add(tablist, -1) + endif + endif + return tablist endfunction @@ -57,7 +103,11 @@ function! airline#extensions#tabline#tabs#get() let b = airline#extensions#tabline#new_builder() call airline#extensions#tabline#add_label(b, 'tabs') - for i in s:get_tabs() + for i in s:get_visible_tabs() + if i < 0 + call b.add_raw('%#airline_tabhid#...') + continue + endif if i == curtab let group = 'airline_tabsel' if g:airline_detect_modified From cf47d63f7184062f8cbb2ab005bce19f62b3fd8e Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sat, 10 Mar 2018 01:50:29 +0000 Subject: [PATCH 03/54] Fix formatting in clipped tab bar --- autoload/airline/extensions/tabline/tabs.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 84b8b4d..e715b13 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -105,7 +105,7 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'tabs') for i in s:get_visible_tabs() if i < 0 - call b.add_raw('%#airline_tabhid#...') + call b.add_raw('%#airline_tab#...') continue endif if i == curtab From 2711c73a47eeb848ddec42c5f8f62a6cb85f941e Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 12 Mar 2018 18:12:08 +0000 Subject: [PATCH 04/54] Pass the available space for tabs as an argument to |get_visible_tabs| --- autoload/airline/extensions/tabline/tabs.vim | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index e715b13..596013a 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -25,7 +25,7 @@ function! airline#extensions#tabline#tabs#invalidate() let s:current_bufnr = -1 endfunction -function! s:get_visible_tabs() +function! s:get_visible_tabs(width) let tablist = range(1, tabpagenr('$')) let curbuf = bufnr('%') @@ -48,13 +48,12 @@ function! s:get_visible_tabs() " only show current and surrounding tabs if there are too many tabs let position = index(tablist, curbuf) - let vimwidth = &columns - if total_width > vimwidth && position > -1 + if total_width > a:width && position > -1 let tab_count = len(tablist) " determine how many tabs to show based on the longest tab width, " use one on the right side and put the rest on the left - let tab_max = vimwidth / max_width + let tab_max = a:width / max_width let tab_right = 1 let tab_left = max([0, tab_max - tab_right]) @@ -103,7 +102,7 @@ function! airline#extensions#tabline#tabs#get() let b = airline#extensions#tabline#new_builder() call airline#extensions#tabline#add_label(b, 'tabs') - for i in s:get_visible_tabs() + for i in s:get_visible_tabs(&columns) if i < 0 call b.add_raw('%#airline_tab#...') continue From 7a286639c520b7972fc67de81ff4d8c087746f0b Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 12 Mar 2018 20:27:52 +0000 Subject: [PATCH 05/54] Attach tabs to tabline last --- autoload/airline/builder.vim | 12 ++++++ autoload/airline/extensions/tabline/tabs.vim | 45 +++++++++++--------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/autoload/airline/builder.vim b/autoload/airline/builder.vim index 38dc83c..b536d4c 100644 --- a/autoload/airline/builder.vim +++ b/autoload/airline/builder.vim @@ -22,6 +22,18 @@ function! s:prototype.add_raw(text) dict call add(self._sections, ['', a:text]) endfunction +function! s:prototype.insert_section(group, contents, position) dict + call insert(self._sections, [a:group, a:contents], a:position) +endfunction + +function! s:prototype.insert_raw(text, position) dict + call insert(self._sections, ['', a:text], a:position) +endfunction + +function! s:prototype.get_position() dict + return len(self._sections) +endfunction + function! s:get_prev_group(sections, i) let x = a:i - 1 while x >= 0 diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 596013a..3db6d92 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -102,9 +102,31 @@ function! airline#extensions#tabline#tabs#get() let b = airline#extensions#tabline#new_builder() call airline#extensions#tabline#add_label(b, 'tabs') + + let tabs_position = b.get_position() + + 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 + call airline#extensions#tabline#add_label(b, 'buffers') + endif + for i in s:get_visible_tabs(&columns) if i < 0 - call b.add_raw('%#airline_tab#...') + call b.insert_raw('%#airline_tab#...', tabs_position) + let tabs_position += 1 continue endif if i == curtab @@ -125,27 +147,10 @@ function! airline#extensions#tabline#tabs#get() if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) let val .= airline#extensions#tabline#tabs#tabnr_formatter(tab_nr_type, i) endif - call b.add_section(group, val.'%'.i.'T %{airline#extensions#tabline#title('.i.')} %)') + call b.insert_section(group, val.'%'.i.'T %{airline#extensions#tabline#title('.i.')} %)', tabs_position) + let tabs_position += 1 endfor - 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 - call airline#extensions#tabline#add_label(b, 'buffers') - endif - let s:current_bufnr = curbuf let s:current_tabnr = curtab let s:current_tabline = b.build() From e0791cc1a00e1ab225355b6a0704882c8879ea50 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 12 Mar 2018 20:31:50 +0000 Subject: [PATCH 06/54] Use the partially built tabline to calculate space left for tabs --- autoload/airline/extensions/tabline/tabs.vim | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 3db6d92..61deaee 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -123,7 +123,15 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'buffers') endif - for i in s:get_visible_tabs(&columns) + let b_tabline = b.build() + let b_tabline = substitute(b_tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') + let b_tabline = substitute(b_tabline, '%#[^#]\+#', '', 'g') + let b_tabline = substitute(b_tabline, '%(\([^)]\+\))', '\1', 'g') + let b_tabline = substitute(b_tabline, '%\d\+[TX]', '', 'g') + let b_tabline = substitute(b_tabline, '%=', '', 'g') + let b_tabline = substitute(b_tabline, '%\d*\*', '', 'g') + + for i in s:get_visible_tabs(&columns - strlen(b_tabline)) if i < 0 call b.insert_raw('%#airline_tab#...', tabs_position) let tabs_position += 1 From 3305410982d1d6ccb93195059d324ff62a0adbef Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 12 Mar 2018 20:37:37 +0000 Subject: [PATCH 07/54] Move tabline evaluation into its own function --- autoload/airline/extensions/tabline/tabs.vim | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 61deaee..1cd1e5b 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -84,6 +84,17 @@ function! s:get_visible_tabs(width) return tablist endfunction +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') + return tabline +endfunction + function! airline#extensions#tabline#tabs#get() let curbuf = bufnr('%') let curtab = tabpagenr() @@ -123,13 +134,7 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'buffers') endif - let b_tabline = b.build() - let b_tabline = substitute(b_tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') - let b_tabline = substitute(b_tabline, '%#[^#]\+#', '', 'g') - let b_tabline = substitute(b_tabline, '%(\([^)]\+\))', '\1', 'g') - let b_tabline = substitute(b_tabline, '%\d\+[TX]', '', 'g') - let b_tabline = substitute(b_tabline, '%=', '', 'g') - let b_tabline = substitute(b_tabline, '%\d*\*', '', 'g') + let b_tabline = s:evaluate_tabline(b.build()) for i in s:get_visible_tabs(&columns - strlen(b_tabline)) if i < 0 From d29c7b27fa720ac511ca2e38e3d2768d9f65374a Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 12 Mar 2018 20:53:26 +0000 Subject: [PATCH 08/54] Evaluate tabline fragments to get the length of tab titles --- autoload/airline/extensions/tabline/tabs.vim | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 1cd1e5b..61715e5 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -25,7 +25,7 @@ function! airline#extensions#tabline#tabs#invalidate() let s:current_bufnr = -1 endfunction -function! s:get_visible_tabs(width) +function! s:get_visible_tabs(width, titles) let tablist = range(1, tabpagenr('$')) let curbuf = bufnr('%') @@ -40,8 +40,8 @@ function! s:get_visible_tabs(width) let total_width = 0 let max_width = 0 - for nr in tablist - let width = len(airline#extensions#tabline#title(nr)) + 4 + for title in a:titles + let width = strlen(s:evaluate_tabline(title)) + 1 let total_width += width let max_width = max([max_width, width]) endfor @@ -136,7 +136,18 @@ function! airline#extensions#tabline#tabs#get() let b_tabline = s:evaluate_tabline(b.build()) - for i in s:get_visible_tabs(&columns - strlen(b_tabline)) + let tab_titles = [] + for i in range(1, tabpagenr('$')) + let val = '%(' + + if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) + let val .= airline#extensions#tabline#tabs#tabnr_formatter(tab_nr_type, i) + endif + + call add(tab_titles, val.'%'.i.'T %{airline#extensions#tabline#title('.i.')} %)') + endfor + + for i in s:get_visible_tabs(&columns - strlen(b_tabline), tab_titles) if i < 0 call b.insert_raw('%#airline_tab#...', tabs_position) let tabs_position += 1 @@ -155,12 +166,8 @@ function! airline#extensions#tabline#tabs#get() else let group = 'airline_tab' endif - let val = '%(' - if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) - let val .= airline#extensions#tabline#tabs#tabnr_formatter(tab_nr_type, i) - endif - call b.insert_section(group, val.'%'.i.'T %{airline#extensions#tabline#title('.i.')} %)', tabs_position) + call b.insert_section(group, get(tab_titles, i-1, ''), tabs_position) let tabs_position += 1 endfor From e1a4cd764f7d2c97284e9fa6e52c986ad4a19270 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Tue, 13 Mar 2018 00:57:48 +0000 Subject: [PATCH 09/54] Adjust tab columns to allow for ellipsis and the left/right split --- autoload/airline/extensions/tabline/tabs.vim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 61715e5..d713719 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -46,14 +46,17 @@ function! s:get_visible_tabs(width, titles) let max_width = max([max_width, width]) endfor + " leave space for end ellipsis (...) and the left/right split (2 spaces) + let tab_columns = a:width - 8 + " only show current and surrounding tabs if there are too many tabs let position = index(tablist, curbuf) - if total_width > a:width && position > -1 + if total_width > tab_columns && position > -1 let tab_count = len(tablist) " determine how many tabs to show based on the longest tab width, " use one on the right side and put the rest on the left - let tab_max = a:width / max_width + let tab_max = tab_columns / max_width let tab_right = 1 let tab_left = max([0, tab_max - tab_right]) From f93894f6ac28e6bb1c633e2d18952ae290c8820a Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Wed, 14 Mar 2018 13:55:30 +0000 Subject: [PATCH 10/54] Move tab title generation into its own function --- autoload/airline/extensions/tabline/tabs.vim | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index d713719..60524a9 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -98,6 +98,16 @@ function! s:evaluate_tabline(tabline) return tabline endfunction +function! s:get_title(tab_nr_type, i) + let val = '%(' + + if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) + let val .= airline#extensions#tabline#tabs#tabnr_formatter(a:tab_nr_type, a:i) + endif + + return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' +endfunction + function! airline#extensions#tabline#tabs#get() let curbuf = bufnr('%') let curtab = tabpagenr() @@ -141,13 +151,7 @@ function! airline#extensions#tabline#tabs#get() let tab_titles = [] for i in range(1, tabpagenr('$')) - let val = '%(' - - if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) - let val .= airline#extensions#tabline#tabs#tabnr_formatter(tab_nr_type, i) - endif - - call add(tab_titles, val.'%'.i.'T %{airline#extensions#tabline#title('.i.')} %)') + call add(tab_titles, s:get_title(tab_nr_type, i)) endfor for i in s:get_visible_tabs(&columns - strlen(b_tabline), tab_titles) From 7480245ebff8629f69eb1f9ebaff918eb3358533 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Wed, 14 Mar 2018 14:24:22 +0000 Subject: [PATCH 11/54] Calculate used length of tabs directly as they are added --- autoload/airline/extensions/tabline/tabs.vim | 153 ++++++++----------- 1 file changed, 65 insertions(+), 88 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 60524a9..1096850 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -25,68 +25,6 @@ function! airline#extensions#tabline#tabs#invalidate() let s:current_bufnr = -1 endfunction -function! s:get_visible_tabs(width, titles) - let tablist = range(1, tabpagenr('$')) - let curbuf = bufnr('%') - - if get(g:, 'airline#extensions#tabline#current_first', 0) - " always have current tabpage first - if index(tablist, curtab) > -1 - call remove(tablist, index(tablist, curtab)) - endif - let tablist = [curtab] + tablist - endif - - let total_width = 0 - let max_width = 0 - - for title in a:titles - let width = strlen(s:evaluate_tabline(title)) + 1 - let total_width += width - let max_width = max([max_width, width]) - endfor - - " leave space for end ellipsis (...) and the left/right split (2 spaces) - let tab_columns = a:width - 8 - - " only show current and surrounding tabs if there are too many tabs - let position = index(tablist, curbuf) - if total_width > tab_columns && position > -1 - let tab_count = len(tablist) - - " determine how many tabs to show based on the longest tab width, - " use one on the right side and put the rest on the left - let tab_max = tab_columns / max_width - let tab_right = 1 - let tab_left = max([0, tab_max - tab_right]) - - let start = max([0, position - tab_left]) - let end = min([tab_count, position + tab_right]) - - " fill up available space on the right - if position < tab_left - let end += (tab_left - position) - endif - - " fill up available space on the left - if end > tab_count - 1 - tab_right - let start -= max([0, tab_right - (tab_count - 1 - position)]) - endif - - let tablist = eval('tablist[' . start . ':' . end . ']') - - if start > 0 - call insert(tablist, -1, 0) - endif - - if end < tab_count - 1 - call add(tablist, -1) - endif - endif - - return tablist -endfunction - function! s:evaluate_tabline(tabline) let tabline = a:tabline let tabline = substitute(tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') @@ -148,35 +86,74 @@ function! airline#extensions#tabline#tabs#get() endif let b_tabline = s:evaluate_tabline(b.build()) + let num_tabs = tabpagenr('$') + let left_tab = curtab - 1 + let right_tab = curtab + 1 + let left_position = tabs_position + let right_position = tabs_position + 1 + let remaining_space = &columns - strlen(s:evaluate_tabline(b.build())) - 8 - let tab_titles = [] - for i in range(1, tabpagenr('$')) - call add(tab_titles, s:get_title(tab_nr_type, i)) - endfor - - for i in s:get_visible_tabs(&columns - strlen(b_tabline), tab_titles) - if i < 0 - call b.insert_raw('%#airline_tab#...', tabs_position) - let tabs_position += 1 - continue - endif - if i == curtab - let group = 'airline_tabsel' - if g:airline_detect_modified - for bi in tabpagebuflist(i) - if getbufvar(bi, '&modified') - let group = 'airline_tabmod' - endif - endfor + " Add the current tab + let tab_title = s:get_title(tab_nr_type, curtab) + let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + let group = 'airline_tabsel' + if g:airline_detect_modified + for bi in tabpagebuflist(curtab) + if getbufvar(bi, '&modified') + let group = 'airline_tabmod' endif - let s:current_modified = (group == 'airline_tabmod') ? 1 : 0 - else - let group = 'airline_tab' - endif + endfor + endif + let s:current_modified = (group == 'airline_tabmod') ? 1 : 0 + call b.insert_section(group, tab_title, left_position) - call b.insert_section(group, get(tab_titles, i-1, ''), tabs_position) - let tabs_position += 1 - endfor + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current tabpage first + let left_position += 1 + endif + + " Add the tab to the right + if right_tab <= num_tabs + let tab_title = s:get_title(tab_nr_type, right_tab) + let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + call b.insert_section('airline_tab', tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + + while remaining_space > 0 + if left_tab > 0 + let tab_title = s:get_title(tab_nr_type, left_tab) + let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + if remaining_space >= 0 + call b.insert_section('airline_tab', tab_title, left_position) + let right_position += 1 + let left_tab -= 1 + endif + elseif right_tab <= num_tabs + let tab_title = s:get_title(tab_nr_type, right_tab) + let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + if remaining_space >= 0 + call b.insert_section('airline_tab', tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + else + break + endif + endwhile + + if left_tab > 0 + if get(g:, 'airline#extensions#tabline#current_first', 0) + let left_position -= 1 + endif + call b.insert_raw('%#airline_tab#...', left_position) + let right_position += 1 + endif + + if right_tab <= num_tabs + call b.insert_raw('%#airline_tab#...', right_position) + endif let s:current_bufnr = curbuf let s:current_tabnr = curtab From 980e78b4bf0d1e3a359ed96997058e3f86580852 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Wed, 14 Mar 2018 14:51:19 +0000 Subject: [PATCH 12/54] Add configurable variable airline#extensions#tabline#skipped_tabs_marker --- autoload/airline/extensions/tabline/tabs.vim | 11 +++++++---- doc/airline.txt | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 1096850..cc4aefc 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -31,7 +31,7 @@ function! s:evaluate_tabline(tabline) 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, '%=', ' ', 'g') let tabline = substitute(tabline, '%\d*\*', '', 'g') return tabline endfunction @@ -91,7 +91,10 @@ function! airline#extensions#tabline#tabs#get() let right_tab = curtab + 1 let left_position = tabs_position let right_position = tabs_position + 1 - let remaining_space = &columns - strlen(s:evaluate_tabline(b.build())) - 8 + let remaining_space = &columns - strlen(s:evaluate_tabline(b.build())) + + let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#skipped_tabs_marker', '...') + let remaining_space -= 4 + 2 * strlen(s:evaluate_tabline(skipped_tabs_marker)) " Add the current tab let tab_title = s:get_title(tab_nr_type, curtab) @@ -147,12 +150,12 @@ function! airline#extensions#tabline#tabs#get() if get(g:, 'airline#extensions#tabline#current_first', 0) let left_position -= 1 endif - call b.insert_raw('%#airline_tab#...', left_position) + call b.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) let right_position += 1 endif if right_tab <= num_tabs - call b.insert_raw('%#airline_tab#...', right_position) + call b.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) endif let s:current_bufnr = curbuf diff --git a/doc/airline.txt b/doc/airline.txt index c0ac19b..e148818 100644 --- a/doc/airline.txt +++ b/doc/airline.txt @@ -709,6 +709,9 @@ with the middle mouse button to delete that buffer. * rename label for tabs (default: 'tabs') (c) > let g:airline#extensions#tabline#tabs_label = 't' +* change the symbol for skipped tabs/buffers (default '...') > + let g:airline#extensions#tabline#skipped_tabs_marker = '…' + * always show current tabpage/buffer first > let airline#extensions#tabline#current_first = 1 < default: 0 From 6819443d6a44aaf8f52028c15c76c6cf3090f420 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Wed, 14 Mar 2018 15:07:41 +0000 Subject: [PATCH 13/54] Fix typo in evaluating %( %) rules --- autoload/airline/extensions/tabline/tabs.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index cc4aefc..a04af46 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -29,7 +29,7 @@ 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, '%(\([^)]\+\)%)', '\1', 'g') let tabline = substitute(tabline, '%\d\+[TX]', '', 'g') let tabline = substitute(tabline, '%=', ' ', 'g') let tabline = substitute(tabline, '%\d*\*', '', 'g') From 5d2d764368d731a5e8db981a16695822cda5bbe8 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Wed, 14 Mar 2018 15:13:40 +0000 Subject: [PATCH 14/54] Use strchars to calculate string lengths This also adds a compatability wrapper, so that versions older than Vim 7.3 are supported. This is inspired by, and includes s:strchars from, @ruipgpinheiro's commit e2d1295a3d3708e8d2a5eb30cac840fc9520bb8b --- autoload/airline/extensions/tabline/tabs.vim | 22 ++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index a04af46..7bc15d4 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -46,6 +46,16 @@ function! s:get_title(tab_nr_type, i) return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' endfunction +" Compatibility wrapper for strchars, in case this vim version does not +" have it natively +function! s:strchars(str) + if exists('*strchars') + return strchars(a:str) + else + return strlen(substitute(a:str, '.', 'a', 'g')) + endif +endfunction + function! airline#extensions#tabline#tabs#get() let curbuf = bufnr('%') let curtab = tabpagenr() @@ -91,14 +101,14 @@ function! airline#extensions#tabline#tabs#get() let right_tab = curtab + 1 let left_position = tabs_position let right_position = tabs_position + 1 - let remaining_space = &columns - strlen(s:evaluate_tabline(b.build())) + let remaining_space = &columns - s:strchars(s:evaluate_tabline(b.build())) let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#skipped_tabs_marker', '...') - let remaining_space -= 4 + 2 * strlen(s:evaluate_tabline(skipped_tabs_marker)) + let remaining_space -= 4 + 2 * s:strchars(s:evaluate_tabline(skipped_tabs_marker)) " Add the current tab let tab_title = s:get_title(tab_nr_type, curtab) - let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 let group = 'airline_tabsel' if g:airline_detect_modified for bi in tabpagebuflist(curtab) @@ -118,7 +128,7 @@ function! airline#extensions#tabline#tabs#get() " Add the tab to the right if right_tab <= num_tabs let tab_title = s:get_title(tab_nr_type, right_tab) - let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 call b.insert_section('airline_tab', tab_title, right_position) let right_position += 1 let right_tab += 1 @@ -127,7 +137,7 @@ function! airline#extensions#tabline#tabs#get() while remaining_space > 0 if left_tab > 0 let tab_title = s:get_title(tab_nr_type, left_tab) - let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 if remaining_space >= 0 call b.insert_section('airline_tab', tab_title, left_position) let right_position += 1 @@ -135,7 +145,7 @@ function! airline#extensions#tabline#tabs#get() endif elseif right_tab <= num_tabs let tab_title = s:get_title(tab_nr_type, right_tab) - let remaining_space -= strlen(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 if remaining_space >= 0 call b.insert_section('airline_tab', tab_title, right_position) let right_position += 1 From 88dedb586ab4ff880ff74e9bb9a9a5c35d90fb18 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Wed, 14 Mar 2018 15:25:03 +0000 Subject: [PATCH 15/54] Update tabs tabline when the width of the terminal changes --- autoload/airline/extensions/tabline/tabs.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 7bc15d4..beed74c 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -64,7 +64,7 @@ function! airline#extensions#tabline#tabs#get() catch " no-op endtry - if curbuf == s:current_bufnr && curtab == s:current_tabnr + 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 @@ -170,6 +170,7 @@ function! airline#extensions#tabline#tabs#get() 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 From a8f92cc68abe7b263248c3532ce8b5cf7bcb3533 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 14:07:50 +0000 Subject: [PATCH 16/54] Rename skipped_tabs_marker to overflow_marker This is set to g:airline_symbols.ellipsis, which this commit also adds. --- autoload/airline/extensions/tabline/tabs.vim | 2 +- autoload/airline/init.vim | 3 ++- doc/airline.txt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index beed74c..0af67ab 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -103,7 +103,7 @@ function! airline#extensions#tabline#tabs#get() let right_position = tabs_position + 1 let remaining_space = &columns - s:strchars(s:evaluate_tabline(b.build())) - let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#skipped_tabs_marker', '...') + let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) let remaining_space -= 4 + 2 * s:strchars(s:evaluate_tabline(skipped_tabs_marker)) " Add the current tab diff --git a/autoload/airline/init.vim b/autoload/airline/init.vim index 228d012..eeb3601 100644 --- a/autoload/airline/init.vim +++ b/autoload/airline/init.vim @@ -70,7 +70,8 @@ function! airline#init#bootstrap() \ 'spell': 'SPELL', \ 'modified': '+', \ 'space': ' ', - \ 'keymap': 'Keymap:' + \ 'keymap': 'Keymap:', + \ 'ellipsis': '...' \ }, 'keep') if get(g:, 'airline_powerline_fonts', 0) diff --git a/doc/airline.txt b/doc/airline.txt index e148818..3d6e7f9 100644 --- a/doc/airline.txt +++ b/doc/airline.txt @@ -710,7 +710,7 @@ with the middle mouse button to delete that buffer. let g:airline#extensions#tabline#tabs_label = 't' * change the symbol for skipped tabs/buffers (default '...') > - let g:airline#extensions#tabline#skipped_tabs_marker = '…' + let g:airline#extensions#tabline#overflow_marker = '…' * always show current tabpage/buffer first > let airline#extensions#tabline#current_first = 1 From 2b0fe51f995f0d0c1f76e3902f304467c8b52484 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 14:36:39 +0000 Subject: [PATCH 17/54] Replace %= with empty string in evaluate_tabline --- autoload/airline/extensions/tabline/tabs.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 0af67ab..4261e03 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -31,7 +31,7 @@ function! s:evaluate_tabline(tabline) 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, '%=', '', 'g') let tabline = substitute(tabline, '%\d*\*', '', 'g') return tabline endfunction From d3ec54d42e030be79280092dbae94bdf25c18115 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 15:15:47 +0000 Subject: [PATCH 18/54] Remove magic contant for skipped_tabs_marker in tabline calculation --- autoload/airline/extensions/tabline/tabs.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 4261e03..80a8a0a 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -104,7 +104,7 @@ function! airline#extensions#tabline#tabs#get() let remaining_space = &columns - s:strchars(s:evaluate_tabline(b.build())) let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let remaining_space -= 4 + 2 * s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + let remaining_space -= 2 * s:strchars(s:evaluate_tabline(skipped_tabs_marker)) " Add the current tab let tab_title = s:get_title(tab_nr_type, curtab) From 1837b2ee39f6e52333ef0a14de4a833b231d7501 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 15:37:15 +0000 Subject: [PATCH 19/54] Use the size of the seperators to get the tabline's remaining space --- autoload/airline/extensions/tabline/tabs.vim | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 80a8a0a..c822e1d 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -103,12 +103,20 @@ function! airline#extensions#tabline#tabs#get() let right_position = tabs_position + 1 let remaining_space = &columns - s:strchars(s:evaluate_tabline(b.build())) + let left_sep_size = s:strchars(s:evaluate_tabline(b._context.left_sep)) + let left_alt_sep_size = s:strchars(s:evaluate_tabline(b._context.left_alt_sep)) + let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let remaining_space -= 2 * s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + " The left marker will have left_alt_sep, and the right will have left_sep. + let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size " Add the current tab let tab_title = s:get_title(tab_nr_type, curtab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + " There are always two left_seps (either side of the selected tab) and all + " other seperators are left_alt_seps. + let remaining_space -= 2 * left_sep_size - left_alt_sep_size let group = 'airline_tabsel' if g:airline_detect_modified for bi in tabpagebuflist(curtab) @@ -128,7 +136,7 @@ function! airline#extensions#tabline#tabs#get() " Add the tab to the right if right_tab <= num_tabs let tab_title = s:get_title(tab_nr_type, right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size call b.insert_section('airline_tab', tab_title, right_position) let right_position += 1 let right_tab += 1 @@ -137,7 +145,7 @@ function! airline#extensions#tabline#tabs#get() while remaining_space > 0 if left_tab > 0 let tab_title = s:get_title(tab_nr_type, left_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 call b.insert_section('airline_tab', tab_title, left_position) let right_position += 1 @@ -145,7 +153,7 @@ function! airline#extensions#tabline#tabs#get() endif elseif right_tab <= num_tabs let tab_title = s:get_title(tab_nr_type, right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + 1 + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 call b.insert_section('airline_tab', tab_title, right_position) let right_position += 1 From 57f2619c67184deced99a1ceac83546f3b30c9bb Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 15:39:54 +0000 Subject: [PATCH 20/54] Remove unused variable b_tabline --- autoload/airline/extensions/tabline/tabs.vim | 1 - 1 file changed, 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index c822e1d..4639f33 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -95,7 +95,6 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'buffers') endif - let b_tabline = s:evaluate_tabline(b.build()) let num_tabs = tabpagenr('$') let left_tab = curtab - 1 let right_tab = curtab + 1 From 5907d3909e7063d471706587aeb91d3cea4f9853 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 01:23:43 +0000 Subject: [PATCH 21/54] Add dedicated tabline builder --- autoload/airline/extensions/tabline.vim | 2 +- autoload/airline/extensions/tabline/builder.vim | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 autoload/airline/extensions/tabline/builder.vim diff --git a/autoload/airline/extensions/tabline.vim b/autoload/airline/extensions/tabline.vim index 9700023..52cf19b 100644 --- a/autoload/airline/extensions/tabline.vim +++ b/autoload/airline/extensions/tabline.vim @@ -181,7 +181,7 @@ function! airline#extensions#tabline#new_builder() let builder_context.left_alt_sep = get(g:, 'airline#extensions#tabline#left_alt_sep' , '|') endif - return airline#builder#new(builder_context) + return airline#extensions#tabline#builder#new(builder_context) endfunction function! airline#extensions#tabline#group_of_bufnr(tab_bufs, bufnr) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim new file mode 100644 index 0000000..681026f --- /dev/null +++ b/autoload/airline/extensions/tabline/builder.vim @@ -0,0 +1,12 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:prototype = {} + +function! airline#extensions#tabline#builder#new(context) + let builder = airline#builder#new(a:context) + call extend(builder, s:prototype, 'force') + return builder +endfunction From 6286b6d8d8ade2d6b63ee39471e6d7103090885d Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 16:44:49 +0000 Subject: [PATCH 22/54] Move get_group into its own function for tabs --- autoload/airline/extensions/tabline/tabs.vim | 34 ++++++++++++-------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 4639f33..145ba42 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -36,6 +36,23 @@ function! s:evaluate_tabline(tabline) return tabline endfunction +function! s:get_group(i) + 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! s:get_title(tab_nr_type, i) let val = '%(' @@ -116,16 +133,7 @@ function! airline#extensions#tabline#tabs#get() " There are always two left_seps (either side of the selected tab) and all " other seperators are left_alt_seps. let remaining_space -= 2 * left_sep_size - left_alt_sep_size - 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 - call b.insert_section(group, tab_title, left_position) + call b.insert_section(s:get_group(curtab), tab_title, left_position) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first @@ -136,7 +144,7 @@ function! airline#extensions#tabline#tabs#get() if right_tab <= num_tabs let tab_title = s:get_title(tab_nr_type, right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call b.insert_section('airline_tab', tab_title, right_position) + call b.insert_section(s:get_group(right_tab), tab_title, right_position) let right_position += 1 let right_tab += 1 endif @@ -146,7 +154,7 @@ function! airline#extensions#tabline#tabs#get() let tab_title = s:get_title(tab_nr_type, left_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 - call b.insert_section('airline_tab', tab_title, left_position) + call b.insert_section(s:get_group(left_tab), tab_title, left_position) let right_position += 1 let left_tab -= 1 endif @@ -154,7 +162,7 @@ function! airline#extensions#tabline#tabs#get() let tab_title = s:get_title(tab_nr_type, right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 - call b.insert_section('airline_tab', tab_title, right_position) + call b.insert_section(s:get_group(right_tab), tab_title, right_position) let right_position += 1 let right_tab += 1 endif From b99da65412b8c648d116f4cd6487da5f04bf9229 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 16:54:38 +0000 Subject: [PATCH 23/54] Create insert_tabs function on builder for tabs tabline --- autoload/airline/extensions/tabline/tabs.vim | 123 ++++++++++--------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 145ba42..52b6855 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -87,7 +87,6 @@ function! airline#extensions#tabline#tabs#get() endif endif - let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) let b = airline#extensions#tabline#new_builder() call airline#extensions#tabline#add_label(b, 'tabs') @@ -112,76 +111,80 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'buffers') endif - let num_tabs = tabpagenr('$') - let left_tab = curtab - 1 - let right_tab = curtab + 1 - let left_position = tabs_position - let right_position = tabs_position + 1 - let remaining_space = &columns - s:strchars(s:evaluate_tabline(b.build())) + function! b.insert_tabs(tabs_position, curtab) dict + let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) + let num_tabs = tabpagenr('$') + let left_tab = a:curtab - 1 + let right_tab = a:curtab + 1 + let left_position = a:tabs_position + let right_position = a:tabs_position + 1 + let remaining_space = &columns - s:strchars(s:evaluate_tabline(self.build())) - let left_sep_size = s:strchars(s:evaluate_tabline(b._context.left_sep)) - let left_alt_sep_size = s:strchars(s:evaluate_tabline(b._context.left_alt_sep)) + let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) + let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) - let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) - " The left marker will have left_alt_sep, and the right will have left_sep. - let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size + let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) + let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + " The left marker will have left_alt_sep, and the right will have left_sep. + let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size - " Add the current tab - let tab_title = s:get_title(tab_nr_type, curtab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) - " There are always two left_seps (either side of the selected tab) and all - " other seperators are left_alt_seps. - let remaining_space -= 2 * left_sep_size - left_alt_sep_size - call b.insert_section(s:get_group(curtab), tab_title, left_position) + " Add the current tab + let tab_title = s:get_title(tab_nr_type, a:curtab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + " There are always two left_seps (either side of the selected tab) and all + " other seperators are left_alt_seps. + let remaining_space -= 2 * left_sep_size - left_alt_sep_size + call self.insert_section(s:get_group(a:curtab), tab_title, left_position) - if get(g:, 'airline#extensions#tabline#current_first', 0) - " always have current tabpage first - let left_position += 1 - endif + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current tabpage first + let left_position += 1 + endif - " Add the tab to the right - if right_tab <= num_tabs - let tab_title = s:get_title(tab_nr_type, right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call b.insert_section(s:get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 - endif - - while remaining_space > 0 - if left_tab > 0 - let tab_title = s:get_title(tab_nr_type, left_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 - call b.insert_section(s:get_group(left_tab), tab_title, left_position) - let right_position += 1 - let left_tab -= 1 - endif - elseif right_tab <= num_tabs + " Add the tab to the right + if right_tab <= num_tabs let tab_title = s:get_title(tab_nr_type, right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 - call b.insert_section(s:get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 + call self.insert_section(s:get_group(right_tab), tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + + while remaining_space > 0 + if left_tab > 0 + let tab_title = s:get_title(tab_nr_type, left_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if remaining_space >= 0 + call self.insert_section(s:get_group(left_tab), tab_title, left_position) + let right_position += 1 + let left_tab -= 1 + endif + elseif right_tab <= num_tabs + let tab_title = s:get_title(tab_nr_type, right_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if remaining_space >= 0 + call self.insert_section(s:get_group(right_tab), tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + else + break endif - else - break - endif - endwhile + endwhile - if left_tab > 0 - if get(g:, 'airline#extensions#tabline#current_first', 0) - let left_position -= 1 + if left_tab > 0 + if get(g:, 'airline#extensions#tabline#current_first', 0) + let left_position -= 1 + endif + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) + let right_position += 1 endif - call b.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) - let right_position += 1 - endif - if right_tab <= num_tabs - call b.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) - endif + if right_tab <= num_tabs + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) + endif + endfunction + call b.insert_tabs(tabs_position, curtab) let s:current_bufnr = curbuf let s:current_tabnr = curtab From 71814fb19ffe6f6f8d0cb64a89ea90d6951c2df4 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 17:04:19 +0000 Subject: [PATCH 24/54] Add get_title and get_group to tabs tabline builder --- autoload/airline/extensions/tabline/tabs.vim | 70 ++++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 52b6855..6778ff4 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -36,33 +36,6 @@ function! s:evaluate_tabline(tabline) return tabline endfunction -function! s:get_group(i) - 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! s:get_title(tab_nr_type, i) - let val = '%(' - - if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) - let val .= airline#extensions#tabline#tabs#tabnr_formatter(a:tab_nr_type, a:i) - endif - - return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' -endfunction - " Compatibility wrapper for strchars, in case this vim version does not " have it natively function! s:strchars(str) @@ -111,6 +84,33 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'buffers') endif + 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(tab_nr_type, i) dict + let val = '%(' + + if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) + let val .= airline#extensions#tabline#tabs#tabnr_formatter(a:tab_nr_type, a:i) + endif + + return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' + endfunction + function! b.insert_tabs(tabs_position, curtab) dict let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) let num_tabs = tabpagenr('$') @@ -129,12 +129,12 @@ function! airline#extensions#tabline#tabs#get() let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size " Add the current tab - let tab_title = s:get_title(tab_nr_type, a:curtab) + let tab_title = self.get_title(tab_nr_type, a:curtab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) " There are always two left_seps (either side of the selected tab) and all " other seperators are left_alt_seps. let remaining_space -= 2 * left_sep_size - left_alt_sep_size - call self.insert_section(s:get_group(a:curtab), tab_title, left_position) + call self.insert_section(self.get_group(a:curtab), tab_title, left_position) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first @@ -143,27 +143,27 @@ function! airline#extensions#tabline#tabs#get() " Add the tab to the right if right_tab <= num_tabs - let tab_title = s:get_title(tab_nr_type, right_tab) + let tab_title = self.get_title(tab_nr_type, right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call self.insert_section(s:get_group(right_tab), tab_title, right_position) + call self.insert_section(self.get_group(right_tab), tab_title, right_position) let right_position += 1 let right_tab += 1 endif while remaining_space > 0 if left_tab > 0 - let tab_title = s:get_title(tab_nr_type, left_tab) + let tab_title = self.get_title(tab_nr_type, left_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 - call self.insert_section(s:get_group(left_tab), tab_title, left_position) + call self.insert_section(self.get_group(left_tab), tab_title, left_position) let right_position += 1 let left_tab -= 1 endif elseif right_tab <= num_tabs - let tab_title = s:get_title(tab_nr_type, right_tab) + let tab_title = self.get_title(tab_nr_type, right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 - call self.insert_section(s:get_group(right_tab), tab_title, right_position) + call self.insert_section(self.get_group(right_tab), tab_title, right_position) let right_position += 1 let right_tab += 1 endif From 3f87d28abb37e145806845aed83cfa87e3255442 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 17:05:58 +0000 Subject: [PATCH 25/54] Move insert_tabs into tabs tabline builder prototype Also move evaluate_tabline and strchars methods that it uses --- .../airline/extensions/tabline/builder.vim | 95 +++++++++++++++++++ autoload/airline/extensions/tabline/tabs.vim | 94 ------------------ 2 files changed, 95 insertions(+), 94 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 681026f..5e5dc93 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,6 +5,101 @@ scriptencoding utf-8 let s:prototype = {} +function! s:prototype.insert_tabs(tabs_position, curtab) dict + let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) + let num_tabs = tabpagenr('$') + let left_tab = a:curtab - 1 + let right_tab = a:curtab + 1 + let left_position = a:tabs_position + let right_position = a:tabs_position + 1 + let remaining_space = &columns - s:strchars(s:evaluate_tabline(self.build())) + + let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) + let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) + + let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) + let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + " The left marker will have left_alt_sep, and the right will have left_sep. + let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size + + " Add the current tab + let tab_title = self.get_title(tab_nr_type, a:curtab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + " There are always two left_seps (either side of the selected tab) and all + " other seperators are left_alt_seps. + let remaining_space -= 2 * left_sep_size - left_alt_sep_size + call self.insert_section(self.get_group(a:curtab), tab_title, left_position) + + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current tabpage first + let left_position += 1 + endif + + " Add the tab to the right + if right_tab <= num_tabs + let tab_title = self.get_title(tab_nr_type, right_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + call self.insert_section(self.get_group(right_tab), tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + + while remaining_space > 0 + if left_tab > 0 + let tab_title = self.get_title(tab_nr_type, left_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if remaining_space >= 0 + call self.insert_section(self.get_group(left_tab), tab_title, left_position) + let right_position += 1 + let left_tab -= 1 + endif + elseif right_tab <= num_tabs + let tab_title = self.get_title(tab_nr_type, right_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if remaining_space >= 0 + call self.insert_section(self.get_group(right_tab), tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + else + break + endif + endwhile + + if left_tab > 0 + if get(g:, 'airline#extensions#tabline#current_first', 0) + let left_position -= 1 + endif + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) + let right_position += 1 + endif + + if right_tab <= num_tabs + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) + endif +endfunction + +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') + return tabline +endfunction + +" Compatibility wrapper for strchars, in case this vim version does not +" have it natively +function! s:strchars(str) + if exists('*strchars') + return strchars(a:str) + else + return strlen(substitute(a:str, '.', 'a', 'g')) + endif +endfunction + function! airline#extensions#tabline#builder#new(context) let builder = airline#builder#new(a:context) call extend(builder, s:prototype, 'force') diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 6778ff4..b4ea6ea 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -25,27 +25,6 @@ function! airline#extensions#tabline#tabs#invalidate() let s:current_bufnr = -1 endfunction -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') - return tabline -endfunction - -" Compatibility wrapper for strchars, in case this vim version does not -" have it natively -function! s:strchars(str) - if exists('*strchars') - return strchars(a:str) - else - return strlen(substitute(a:str, '.', 'a', 'g')) - endif -endfunction - function! airline#extensions#tabline#tabs#get() let curbuf = bufnr('%') let curtab = tabpagenr() @@ -111,79 +90,6 @@ function! airline#extensions#tabline#tabs#get() return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' endfunction - function! b.insert_tabs(tabs_position, curtab) dict - let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) - let num_tabs = tabpagenr('$') - let left_tab = a:curtab - 1 - let right_tab = a:curtab + 1 - let left_position = a:tabs_position - let right_position = a:tabs_position + 1 - let remaining_space = &columns - s:strchars(s:evaluate_tabline(self.build())) - - let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) - let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) - - let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) - " The left marker will have left_alt_sep, and the right will have left_sep. - let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size - - " Add the current tab - let tab_title = self.get_title(tab_nr_type, a:curtab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) - " There are always two left_seps (either side of the selected tab) and all - " other seperators are left_alt_seps. - let remaining_space -= 2 * left_sep_size - left_alt_sep_size - call self.insert_section(self.get_group(a:curtab), tab_title, left_position) - - if get(g:, 'airline#extensions#tabline#current_first', 0) - " always have current tabpage first - let left_position += 1 - endif - - " Add the tab to the right - if right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call self.insert_section(self.get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 - endif - - while remaining_space > 0 - if left_tab > 0 - let tab_title = self.get_title(tab_nr_type, left_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 - call self.insert_section(self.get_group(left_tab), tab_title, left_position) - let right_position += 1 - let left_tab -= 1 - endif - elseif right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 - call self.insert_section(self.get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 - endif - else - break - endif - endwhile - - if left_tab > 0 - if get(g:, 'airline#extensions#tabline#current_first', 0) - let left_position -= 1 - endif - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) - let right_position += 1 - endif - - if right_tab <= num_tabs - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) - endif - endfunction call b.insert_tabs(tabs_position, curtab) let s:current_bufnr = curbuf From 349d01ba3947fc8f955ddbc884a4f70789c065ac Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 17:10:49 +0000 Subject: [PATCH 26/54] Generate tabs directly in tabline/builder.build --- .../airline/extensions/tabline/builder.vim | 129 ++++++++++-------- autoload/airline/extensions/tabline/tabs.vim | 40 +++--- 2 files changed, 89 insertions(+), 80 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 5e5dc93..1a53cac 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,78 +5,88 @@ scriptencoding utf-8 let s:prototype = {} -function! s:prototype.insert_tabs(tabs_position, curtab) dict - let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) - let num_tabs = tabpagenr('$') - let left_tab = a:curtab - 1 - let right_tab = a:curtab + 1 - let left_position = a:tabs_position - let right_position = a:tabs_position + 1 - let remaining_space = &columns - s:strchars(s:evaluate_tabline(self.build())) +function! s:prototype.insert_tabs(curtab) dict + let self._tabs_position = self.get_position() + let self._curtab = a:curtab +endfunction - let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) - let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) +function! s:prototype.build() dict + if has_key(self, "_tabs_position") + let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) + let num_tabs = tabpagenr('$') + let curtab = self._curtab + let left_tab = curtab - 1 + let right_tab = curtab + 1 + let left_position = self._tabs_position + let right_position = self._tabs_position + 1 + let remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) - let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) - " The left marker will have left_alt_sep, and the right will have left_sep. - let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size + let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) + let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) - " Add the current tab - let tab_title = self.get_title(tab_nr_type, a:curtab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) - " There are always two left_seps (either side of the selected tab) and all - " other seperators are left_alt_seps. - let remaining_space -= 2 * left_sep_size - left_alt_sep_size - call self.insert_section(self.get_group(a:curtab), tab_title, left_position) + let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) + let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + " The left marker will have left_alt_sep, and the right will have left_sep. + let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size - if get(g:, 'airline#extensions#tabline#current_first', 0) - " always have current tabpage first - let left_position += 1 - endif + " Add the current tab + let tab_title = self.get_title(tab_nr_type, curtab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + " There are always two left_seps (either side of the selected tab) and all + " other seperators are left_alt_seps. + let remaining_space -= 2 * left_sep_size - left_alt_sep_size + call self.insert_section(self.get_group(curtab), tab_title, left_position) - " Add the tab to the right - if right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call self.insert_section(self.get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 - endif + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current tabpage first + let left_position += 1 + endif - while remaining_space > 0 - if left_tab > 0 - let tab_title = self.get_title(tab_nr_type, left_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 - call self.insert_section(self.get_group(left_tab), tab_title, left_position) - let right_position += 1 - let left_tab -= 1 - endif - elseif right_tab <= num_tabs + " Add the tab to the right + if right_tab <= num_tabs let tab_title = self.get_title(tab_nr_type, right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 - call self.insert_section(self.get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 + call self.insert_section(self.get_group(right_tab), tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + + while remaining_space > 0 + if left_tab > 0 + let tab_title = self.get_title(tab_nr_type, left_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if remaining_space >= 0 + call self.insert_section(self.get_group(left_tab), tab_title, left_position) + let right_position += 1 + let left_tab -= 1 + endif + elseif right_tab <= num_tabs + let tab_title = self.get_title(tab_nr_type, right_tab) + let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if remaining_space >= 0 + call self.insert_section(self.get_group(right_tab), tab_title, right_position) + let right_position += 1 + let right_tab += 1 + endif + else + break endif - else - break - endif - endwhile + endwhile - if left_tab > 0 - if get(g:, 'airline#extensions#tabline#current_first', 0) - let left_position -= 1 + if left_tab > 0 + if get(g:, 'airline#extensions#tabline#current_first', 0) + let left_position -= 1 + endif + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) + let right_position += 1 + endif + + if right_tab <= num_tabs + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) endif - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) - let right_position += 1 endif - if right_tab <= num_tabs - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) - endif + return self._build() endfunction function! s:evaluate_tabline(tabline) @@ -102,6 +112,7 @@ 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/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index b4ea6ea..2e2704c 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -43,26 +43,6 @@ function! airline#extensions#tabline#tabs#get() call airline#extensions#tabline#add_label(b, 'tabs') - let tabs_position = b.get_position() - - 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 - call airline#extensions#tabline#add_label(b, 'buffers') - endif - function! b.get_group(i) dict let curtab = tabpagenr() let group = 'airline_tab' @@ -90,7 +70,25 @@ function! airline#extensions#tabline#tabs#get() return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' endfunction - call b.insert_tabs(tabs_position, curtab) + call b.insert_tabs(curtab) + + 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 + call airline#extensions#tabline#add_label(b, 'buffers') + endif let s:current_bufnr = curbuf let s:current_tabnr = curtab From ada8cd7641273037f6167dd28a2243dfe850845b Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 17:41:08 +0000 Subject: [PATCH 27/54] Use variables in the tabs tabline builder to track position --- .../airline/extensions/tabline/builder.vim | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 1a53cac..d6823c2 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -15,10 +15,10 @@ function! s:prototype.build() dict let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) let num_tabs = tabpagenr('$') let curtab = self._curtab - let left_tab = curtab - 1 - let right_tab = curtab + 1 - let left_position = self._tabs_position - let right_position = self._tabs_position + 1 + let self._left_tab = curtab - 1 + let self._right_tab = curtab + 1 + let self._left_position = self._tabs_position + let self._right_position = self._tabs_position + 1 let remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) @@ -35,54 +35,54 @@ function! s:prototype.build() dict " There are always two left_seps (either side of the selected tab) and all " other seperators are left_alt_seps. let remaining_space -= 2 * left_sep_size - left_alt_sep_size - call self.insert_section(self.get_group(curtab), tab_title, left_position) + call self.insert_section(self.get_group(curtab), tab_title, self._left_position) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first - let left_position += 1 + let self._left_position += 1 endif " Add the tab to the right - if right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, right_tab) + if self._right_tab <= num_tabs + let tab_title = self.get_title(tab_nr_type, self._right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call self.insert_section(self.get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 + call self.insert_section(self.get_group(self._right_tab), tab_title, self._right_position) + let self._right_position += 1 + let self._right_tab += 1 endif while remaining_space > 0 - if left_tab > 0 - let tab_title = self.get_title(tab_nr_type, left_tab) + if self._left_tab > 0 + let tab_title = self.get_title(tab_nr_type, self._left_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 - call self.insert_section(self.get_group(left_tab), tab_title, left_position) - let right_position += 1 - let left_tab -= 1 + call self.insert_section(self.get_group(self._left_tab), tab_title, self._left_position) + let self._right_position += 1 + let self._left_tab -= 1 endif - elseif right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, right_tab) + elseif self._right_tab <= num_tabs + let tab_title = self.get_title(tab_nr_type, self._right_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size if remaining_space >= 0 - call self.insert_section(self.get_group(right_tab), tab_title, right_position) - let right_position += 1 - let right_tab += 1 + call self.insert_section(self.get_group(self._right_tab), tab_title, self._right_position) + let self._right_position += 1 + let self._right_tab += 1 endif else break endif endwhile - if left_tab > 0 + if self._left_tab > 0 if get(g:, 'airline#extensions#tabline#current_first', 0) - let left_position -= 1 + let self._left_position -= 1 endif - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, left_position) - let right_position += 1 + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, self._left_position) + let self._right_position += 1 endif - if right_tab <= num_tabs - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, right_position) + if self._right_tab <= num_tabs + call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, self._right_position) endif endif From 1328610188420b5609767df366ae5325325eb7af Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 17:46:33 +0000 Subject: [PATCH 28/54] Initialise tabs tabline builder variables in insert_tabs --- .../airline/extensions/tabline/builder.vim | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index d6823c2..f56b9a9 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -6,19 +6,16 @@ scriptencoding utf-8 let s:prototype = {} function! s:prototype.insert_tabs(curtab) dict - let self._tabs_position = self.get_position() - let self._curtab = a:curtab + let self._left_tab = a:curtab + let self._right_tab = a:curtab + 1 + let self._left_position = self.get_position() + let self._right_position = self._left_position endfunction function! s:prototype.build() dict - if has_key(self, "_tabs_position") + if has_key(self, '_left_position') let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) let num_tabs = tabpagenr('$') - let curtab = self._curtab - let self._left_tab = curtab - 1 - let self._right_tab = curtab + 1 - let self._left_position = self._tabs_position - let self._right_position = self._tabs_position + 1 let remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) @@ -30,12 +27,14 @@ function! s:prototype.build() dict let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size " Add the current tab - let tab_title = self.get_title(tab_nr_type, curtab) + let tab_title = self.get_title(tab_nr_type, self._left_tab) let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) " There are always two left_seps (either side of the selected tab) and all " other seperators are left_alt_seps. let remaining_space -= 2 * left_sep_size - left_alt_sep_size - call self.insert_section(self.get_group(curtab), tab_title, self._left_position) + call self.insert_section(self.get_group(self._left_tab), tab_title, self._left_position) + let self._right_position += 1 + let self._left_tab -= 1 if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first From 9b41fe5de95f1b3faa9a21f81b7c3229f13ebc06 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 18:01:39 +0000 Subject: [PATCH 29/54] Replace tabs tabline remaining_space with a member variable --- .../airline/extensions/tabline/builder.vim | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index f56b9a9..b8d69bf 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -16,7 +16,7 @@ function! s:prototype.build() dict if has_key(self, '_left_position') let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) let num_tabs = tabpagenr('$') - let remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) + let self._remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) @@ -24,14 +24,14 @@ function! s:prototype.build() dict let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) " The left marker will have left_alt_sep, and the right will have left_sep. - let remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size + let self._remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size " Add the current tab let tab_title = self.get_title(tab_nr_type, self._left_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) " There are always two left_seps (either side of the selected tab) and all " other seperators are left_alt_seps. - let remaining_space -= 2 * left_sep_size - left_alt_sep_size + let self._remaining_space -= 2 * left_sep_size - left_alt_sep_size call self.insert_section(self.get_group(self._left_tab), tab_title, self._left_position) let self._right_position += 1 let self._left_tab -= 1 @@ -44,25 +44,25 @@ function! s:prototype.build() dict " Add the tab to the right if self._right_tab <= num_tabs let tab_title = self.get_title(tab_nr_type, self._right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size call self.insert_section(self.get_group(self._right_tab), tab_title, self._right_position) let self._right_position += 1 let self._right_tab += 1 endif - while remaining_space > 0 + while self._remaining_space > 0 if self._left_tab > 0 let tab_title = self.get_title(tab_nr_type, self._left_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 + let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if self._remaining_space >= 0 call self.insert_section(self.get_group(self._left_tab), tab_title, self._left_position) let self._right_position += 1 let self._left_tab -= 1 endif elseif self._right_tab <= num_tabs let tab_title = self.get_title(tab_nr_type, self._right_tab) - let remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if remaining_space >= 0 + let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size + if self._remaining_space >= 0 call self.insert_section(self.get_group(self._right_tab), tab_title, self._right_position) let self._right_position += 1 let self._right_tab += 1 From 6db0af6f8dfecf166b29071392f016ad2c8b739d Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 18:09:18 +0000 Subject: [PATCH 30/54] Factor out tab insertion into its own function --- .../airline/extensions/tabline/builder.vim | 50 +++++++++---------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index b8d69bf..5e3621b 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -12,6 +12,17 @@ function! s:prototype.insert_tabs(curtab) dict let self._right_position = self._left_position endfunction +function! s:prototype.try_insert_tab(tab, pos, tab_nr_type, sep_size, force) dict + let tab_title = self.get_title(a:tab_nr_type, a:tab) + let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size + if a:force || self._remaining_space >= 0 + call self.insert_section(self.get_group(a:tab), tab_title, a:pos) + let self._right_position += 1 + return 1 + endif + return 0 +endfunction + function! s:prototype.build() dict if has_key(self, '_left_position') let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) @@ -25,16 +36,14 @@ function! s:prototype.build() dict let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) " The left marker will have left_alt_sep, and the right will have left_sep. let self._remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size - - " Add the current tab - let tab_title = self.get_title(tab_nr_type, self._left_tab) - let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + " " There are always two left_seps (either side of the selected tab) and all " other seperators are left_alt_seps. - let self._remaining_space -= 2 * left_sep_size - left_alt_sep_size - call self.insert_section(self.get_group(self._left_tab), tab_title, self._left_position) - let self._right_position += 1 - let self._left_tab -= 1 + let self._remaining_space -= left_sep_size - left_alt_sep_size + + " Add the current tab + let self._left_tab -= + \ self.try_insert_tab(self._left_tab, self._left_position, tab_nr_type, left_sep_size, 1) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first @@ -43,30 +52,17 @@ function! s:prototype.build() dict " Add the tab to the right if self._right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, self._right_tab) - let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - call self.insert_section(self.get_group(self._right_tab), tab_title, self._right_position) - let self._right_position += 1 - let self._right_tab += 1 + let self._right_tab += + \ self.try_insert_tab(self._right_tab, self._right_position, tab_nr_type, left_alt_sep_size, 1) endif while self._remaining_space > 0 if self._left_tab > 0 - let tab_title = self.get_title(tab_nr_type, self._left_tab) - let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if self._remaining_space >= 0 - call self.insert_section(self.get_group(self._left_tab), tab_title, self._left_position) - let self._right_position += 1 - let self._left_tab -= 1 - endif + let self._left_tab -= + \ self.try_insert_tab(self._left_tab, self._left_position, tab_nr_type, left_alt_sep_size, 0) elseif self._right_tab <= num_tabs - let tab_title = self.get_title(tab_nr_type, self._right_tab) - let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + left_alt_sep_size - if self._remaining_space >= 0 - call self.insert_section(self.get_group(self._right_tab), tab_title, self._right_position) - let self._right_position += 1 - let self._right_tab += 1 - endif + let self._right_tab += + \ self.try_insert_tab(self._right_tab, self._right_position, tab_nr_type, left_alt_sep_size, 0) else break endif From 5ecc25d6d6799097e8ae98d74a39c6e09a08a48b Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 18:14:50 +0000 Subject: [PATCH 31/54] Move tab_nr_type into tabs get_title --- autoload/airline/extensions/tabline/builder.vim | 13 ++++++------- autoload/airline/extensions/tabline/tabs.vim | 5 +++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 5e3621b..16ba3a3 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -12,8 +12,8 @@ function! s:prototype.insert_tabs(curtab) dict let self._right_position = self._left_position endfunction -function! s:prototype.try_insert_tab(tab, pos, tab_nr_type, sep_size, force) dict - let tab_title = self.get_title(a:tab_nr_type, a:tab) +function! s:prototype.try_insert_tab(tab, pos, sep_size, force) dict + let tab_title = self.get_title(a:tab) let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size if a:force || self._remaining_space >= 0 call self.insert_section(self.get_group(a:tab), tab_title, a:pos) @@ -25,7 +25,6 @@ endfunction function! s:prototype.build() dict if has_key(self, '_left_position') - let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) let num_tabs = tabpagenr('$') let self._remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) @@ -43,7 +42,7 @@ function! s:prototype.build() dict " Add the current tab let self._left_tab -= - \ self.try_insert_tab(self._left_tab, self._left_position, tab_nr_type, left_sep_size, 1) + \ self.try_insert_tab(self._left_tab, self._left_position, left_sep_size, 1) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first @@ -53,16 +52,16 @@ function! s:prototype.build() dict " Add the tab to the right if self._right_tab <= num_tabs let self._right_tab += - \ self.try_insert_tab(self._right_tab, self._right_position, tab_nr_type, left_alt_sep_size, 1) + \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 1) endif while self._remaining_space > 0 if self._left_tab > 0 let self._left_tab -= - \ self.try_insert_tab(self._left_tab, self._left_position, tab_nr_type, left_alt_sep_size, 0) + \ self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) elseif self._right_tab <= num_tabs let self._right_tab += - \ self.try_insert_tab(self._right_tab, self._right_position, tab_nr_type, left_alt_sep_size, 0) + \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) else break endif diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 2e2704c..d238473 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -60,11 +60,12 @@ function! airline#extensions#tabline#tabs#get() return group endfunction - function! b.get_title(tab_nr_type, i) dict + function! b.get_title(i) dict let val = '%(' if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) - let val .= airline#extensions#tabline#tabs#tabnr_formatter(a:tab_nr_type, a:i) + 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.')} %)' From a7bff3b30bb89652eb9bde51280f29221cecf34c Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 18:20:37 +0000 Subject: [PATCH 32/54] Pass number of tabs as an argument to insert_tabs --- autoload/airline/extensions/tabline/builder.vim | 10 +++++----- autoload/airline/extensions/tabline/tabs.vim | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 16ba3a3..8b1dfa4 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,7 +5,8 @@ scriptencoding utf-8 let s:prototype = {} -function! s:prototype.insert_tabs(curtab) dict +function! s:prototype.insert_tabs(curtab, numtabs) dict + let self._num_tabs = a:numtabs let self._left_tab = a:curtab let self._right_tab = a:curtab + 1 let self._left_position = self.get_position() @@ -25,7 +26,6 @@ endfunction function! s:prototype.build() dict if has_key(self, '_left_position') - let num_tabs = tabpagenr('$') let self._remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) @@ -50,7 +50,7 @@ function! s:prototype.build() dict endif " Add the tab to the right - if self._right_tab <= num_tabs + if self._right_tab <= self._num_tabs let self._right_tab += \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 1) endif @@ -59,7 +59,7 @@ function! s:prototype.build() dict if self._left_tab > 0 let self._left_tab -= \ self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) - elseif self._right_tab <= num_tabs + elseif self._right_tab <= self._num_tabs let self._right_tab += \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) else @@ -75,7 +75,7 @@ function! s:prototype.build() dict let self._right_position += 1 endif - if self._right_tab <= num_tabs + if self._right_tab <= self._num_tabs call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, self._right_position) endif endif diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index d238473..eea7301 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -71,7 +71,7 @@ function! airline#extensions#tabline#tabs#get() return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' endfunction - call b.insert_tabs(curtab) + call b.insert_tabs(curtab, tabpagenr('$')) call b.add_section('airline_tabfill', '') call b.split() From e6b6f36d90d5e335b0a7f1b2de57cd1e4efc6acf Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 19:21:15 +0000 Subject: [PATCH 33/54] Remove %@...@ patterns in evaluate_tabline if has('tablineat') --- autoload/airline/extensions/tabline/builder.vim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 8b1dfa4..976b357 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -91,6 +91,9 @@ function! s:evaluate_tabline(tabline) 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 From 3cd8daa162dc91b99ee1339b1332b9bdfc89878b Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 19:41:58 +0000 Subject: [PATCH 34/54] Add support for get_pretitle and get_posttitle to tabline builder --- autoload/airline/extensions/tabline/builder.vim | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 976b357..bdc166f 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -17,8 +17,23 @@ function! s:prototype.try_insert_tab(tab, pos, sep_size, force) dict let tab_title = self.get_title(a:tab) let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size if a:force || self._remaining_space >= 0 - call self.insert_section(self.get_group(a:tab), tab_title, a:pos) + let pos = a:pos + if has_key(self, "get_pretitle") + call self.insert_raw(self.get_pretitle(a:tab), pos) + let self._right_position += 1 + let pos += 1 + endif + + call self.insert_section(self.get_group(a:tab), tab_title, pos) let self._right_position += 1 + let pos += 1 + + if has_key(self, "get_posttitle") + call self.insert_raw(self.get_posttitle(a:tab), pos) + let self._right_position += 1 + let pos += 1 + endif + return 1 endif return 0 From d9e68039b8c462aa1bf45d9a0e72fb6e1704a2ea Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 19:53:08 +0000 Subject: [PATCH 35/54] Take the first tab number in tabline/builder.insert_tabs --- autoload/airline/extensions/tabline/builder.vim | 15 ++++++++------- autoload/airline/extensions/tabline/tabs.vim | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index bdc166f..b22f5aa 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,8 +5,9 @@ scriptencoding utf-8 let s:prototype = {} -function! s:prototype.insert_tabs(curtab, numtabs) dict - let self._num_tabs = a:numtabs +function! s:prototype.insert_tabs(curtab, first_tab, last_tab) dict + let self._first_tab = a:first_tab + let self._last_tab = a:last_tab let self._left_tab = a:curtab let self._right_tab = a:curtab + 1 let self._left_position = self.get_position() @@ -65,16 +66,16 @@ function! s:prototype.build() dict endif " Add the tab to the right - if self._right_tab <= self._num_tabs + if self._right_tab <= self._last_tab let self._right_tab += \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 1) endif while self._remaining_space > 0 - if self._left_tab > 0 + if self._left_tab >= self._first_tab let self._left_tab -= \ self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) - elseif self._right_tab <= self._num_tabs + elseif self._right_tab <= self._last_tab let self._right_tab += \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) else @@ -82,7 +83,7 @@ function! s:prototype.build() dict endif endwhile - if self._left_tab > 0 + if self._left_tab >= self._first_tab if get(g:, 'airline#extensions#tabline#current_first', 0) let self._left_position -= 1 endif @@ -90,7 +91,7 @@ function! s:prototype.build() dict let self._right_position += 1 endif - if self._right_tab <= self._num_tabs + if self._right_tab <= self._last_tab call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, self._right_position) endif endif diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index eea7301..9e3270d 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -71,7 +71,7 @@ function! airline#extensions#tabline#tabs#get() return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' endfunction - call b.insert_tabs(curtab, tabpagenr('$')) + call b.insert_tabs(curtab, 1, tabpagenr('$')) call b.add_section('airline_tabfill', '') call b.split() From 275ec4fe63d9776a2c2cbf72b1f371b9e01273b8 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 19:36:30 +0000 Subject: [PATCH 36/54] Use tabline builder for buffers tabline --- .../airline/extensions/tabline/buffers.vim | 59 ++++++++++++------- .../airline/extensions/tabline/builder.vim | 6 +- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index f137ef1..f7a80ff 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -69,24 +69,45 @@ function! airline#extensions#tabline#buffers#get() if show_buf_label_first call airline#extensions#tabline#add_label(b, 'buffers') endif - let pgroup = '' - for nr in s:get_visible_buffers() - if nr < 0 - call b.add_raw('%#airline_tabhid#...') - continue + + 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 - let group = airline#extensions#tabline#group_of_bufnr(tab_bufs, nr) - - if nr == cur + 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 - " Neovim feature: Have clickable buffers - if has("tablineat") - call b.add_raw('%'.nr.'@airline#extensions#tabline#buffers#clickbuf@') - endif + 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) if get(g:, 'airline_powerline_fonts', 0) let space = s:spc else @@ -95,20 +116,16 @@ function! airline#extensions#tabline#buffers#get() if get(g:, 'airline#extensions#tabline#buffer_idx_mode', 0) if len(s:number_map) > 0 - call b.add_section(group, space. get(s:number_map, index, '') . '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)' . s:spc) + return space. get(s:number_map, a:i, '') . '%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)' . s:spc else - call b.add_section(group, '['.index.s:spc.'%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)'.']') + return '['.a:i.s:spc.'%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)'.']' endif - let index += 1 else - call b.add_section(group, space.'%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)'.s:spc) + return space.'%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)'.s:spc endif + endfunction - if has("tablineat") - call b.add_raw('%X') - endif - let pgroup=group - endfor + call b.insert_tabs(index(b.buffers, cur), 0, len(b.buffers) - 1) call b.add_section('airline_tabfill', '') call b.split() diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index b22f5aa..7b838d4 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -87,18 +87,20 @@ function! s:prototype.build() dict if get(g:, 'airline#extensions#tabline#current_first', 0) let self._left_position -= 1 endif - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, self._left_position) + call self.insert_raw('%#'.self.overflow_group.'#'.skipped_tabs_marker, self._left_position) let self._right_position += 1 endif if self._right_tab <= self._last_tab - call self.insert_raw('%#airline_tab#'.skipped_tabs_marker, self._right_position) + call self.insert_raw('%#'.self.overflow_group.'#'.skipped_tabs_marker, self._right_position) endif endif return self._build() endfunction +let s:prototype.overflow_group = 'airline_tab' + function! s:evaluate_tabline(tabline) let tabline = a:tabline let tabline = substitute(tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') From 4a342afb9055f5c09f6c348d1c5a61e67828b2c0 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 20:07:44 +0000 Subject: [PATCH 37/54] Add an option to centre the active tab in the tabline --- autoload/airline/extensions/tabline/builder.vim | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 7b838d4..86dc27b 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -44,6 +44,8 @@ function! s:prototype.build() dict if has_key(self, '_left_position') let self._remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) + let center_active = get(g:, 'airline#extensions#tabline#center_active', 0) + let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) @@ -66,19 +68,24 @@ function! s:prototype.build() dict endif " Add the tab to the right - if self._right_tab <= self._last_tab + if !center_active && self._right_tab <= self._last_tab let self._right_tab += \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 1) endif while self._remaining_space > 0 + let done = 0 if self._left_tab >= self._first_tab let self._left_tab -= \ self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) - elseif self._right_tab <= self._last_tab + let done = 1 + endif + if self._right_tab <= self._last_tab && (center_active || !done) let self._right_tab += \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) - else + let done = 1 + endif + if !done break endif endwhile From 7844d8bf72e26a162fbfcf85fec3376306abfc83 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 20:29:25 +0000 Subject: [PATCH 38/54] Remove get_visible_buffers --- .../airline/extensions/tabline/buffers.vim | 69 +++---------------- 1 file changed, 9 insertions(+), 60 deletions(-) diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index f7a80ff..729cade 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -125,7 +125,8 @@ function! airline#extensions#tabline#buffers#get() endif endfunction - call b.insert_tabs(index(b.buffers, cur), 0, len(b.buffers) - 1) + let last_buffer = len(b.buffers) - 1 + call b.insert_tabs(index(b.buffers, cur), 0, last_buffer) call b.add_section('airline_tabfill', '') call b.split() @@ -140,68 +141,16 @@ function! airline#extensions#tabline#buffers#get() let s:current_bufnr = cur let s:current_tabline = b.build() + let s:current_visible_buffers = copy(b.buffers) + if b._right_tab <= last_buffer + call remove(s:current_visible_buffers, b._right_tab, last_buffer) + endif + if b._left_tab > 0 + call remove(s:current_visible_buffers, 0, b._left_tab) + endif return s:current_tabline endfunction -function! s:get_visible_buffers() - let buffers = airline#extensions#tabline#buflist#list() - let cur = bufnr('%') - if get(g:, 'airline#extensions#tabline#current_first', 0) - if index(buffers, cur) > -1 - call remove(buffers, index(buffers, cur)) - endif - let buffers = [cur] + buffers - endif - - let total_width = 0 - let max_width = 0 - - for nr in buffers - let width = len(airline#extensions#tabline#get_buffer_name(nr)) + 4 - let total_width += width - let max_width = max([max_width, width]) - endfor - - " only show current and surrounding buffers if there are too many buffers - let position = index(buffers, cur) - let vimwidth = &columns - if total_width > vimwidth && position > -1 - let buf_count = len(buffers) - - " determine how many buffers to show based on the longest buffer width, - " use one on the right side and put the rest on the left - let buf_max = vimwidth / max_width - let buf_right = 1 - let buf_left = max([0, buf_max - buf_right]) - - let start = max([0, position - buf_left]) - let end = min([buf_count, position + buf_right]) - - " fill up available space on the right - if position < buf_left - let end += (buf_left - position) - endif - - " fill up available space on the left - if end > buf_count - 1 - buf_right - let start -= max([0, buf_right - (buf_count - 1 - position)]) - endif - - let buffers = eval('buffers[' . start . ':' . end . ']') - - if start > 0 - call insert(buffers, -1, 0) - endif - - if end < buf_count - 1 - call add(buffers, -1) - endif - endif - - let s:current_visible_buffers = buffers - return buffers -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', From d13305fc5d6b1f37c56cf54a1e987f48381498ef Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 15 Mar 2018 20:40:36 +0000 Subject: [PATCH 39/54] Redraw buffer tabline when the terminal width changes --- autoload/airline/extensions/tabline/buffers.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index 729cade..a9dfe3b 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -52,7 +52,7 @@ function! airline#extensions#tabline#buffers#get() " no-op endtry let cur = bufnr('%') - if cur == s:current_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 @@ -140,6 +140,7 @@ function! airline#extensions#tabline#buffers#get() 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_tab <= last_buffer From 896c14bded5b2e5852c5509b1ab84f526b9512a9 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sat, 17 Mar 2018 19:59:47 +0000 Subject: [PATCH 40/54] Reset _remaining_space if a title can't be inserted This gives us a chance to add the title on the other side if it will fit, so that we fill more space in the tabline. --- autoload/airline/extensions/tabline/builder.vim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 86dc27b..940ccb0 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -36,6 +36,8 @@ function! s:prototype.try_insert_tab(tab, pos, sep_size, force) dict endif return 1 + else + let self._remaining_space += s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size endif return 0 endfunction @@ -76,14 +78,12 @@ function! s:prototype.build() dict while self._remaining_space > 0 let done = 0 if self._left_tab >= self._first_tab - let self._left_tab -= - \ self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) - let done = 1 + let done = self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) + let self._left_tab -= done endif if self._right_tab <= self._last_tab && (center_active || !done) - let self._right_tab += - \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) - let done = 1 + let done = self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) + let self._right_tab += done endif if !done break From 84bf60c405dc057455b8848fb3324166ea526f97 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sun, 18 Mar 2018 00:15:29 +0000 Subject: [PATCH 41/54] Statusline: Use separator widths to calculate whether a title will fit --- autoload/airline/builder.vim | 21 +++++-- .../airline/extensions/tabline/builder.vim | 55 +++++++++++++++---- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/autoload/airline/builder.vim b/autoload/airline/builder.vim index b536d4c..5853c23 100644 --- a/autoload/airline/builder.vim +++ b/autoload/airline/builder.vim @@ -34,7 +34,7 @@ function! s:prototype.get_position() dict return len(self._sections) endfunction -function! s:get_prev_group(sections, i) +function! airline#builder#get_prev_group(sections, i) let x = a:i - 1 while x >= 0 let group = a:sections[x][0] @@ -46,6 +46,19 @@ function! s:get_prev_group(sections, i) return '' endfunction +function! airline#builder#get_next_group(sections, i) + let x = a:i + 1 + let l = len(a:sections) + while x < l + let group = a:sections[x][0] + if group != '' && group != '|' + return group + endif + let x = x + 1 + endwhile + return '' +endfunction + function! s:prototype.build() dict let side = 1 let line = '' @@ -60,7 +73,7 @@ function! s:prototype.build() dict let group = section[0] let contents = section[1] let pgroup = prev_group - let prev_group = s:get_prev_group(self._sections, i) + let prev_group = airline#builder#get_prev_group(self._sections, i) if group ==# 'airline_c' && &buftype ==# 'terminal' && self._context.active let group = 'airline_term' elseif group ==# 'airline_c' && !self._context.active && has_key(self._context, 'bufnr') @@ -114,7 +127,7 @@ function! s:prototype.build() dict return line endfunction -function! s:should_change_group(group1, group2) +function! airline#builder#should_change_group(group1, group2) if a:group1 == a:group2 return 0 endif @@ -144,7 +157,7 @@ function! s:get_transitioned_seperator(self, prev_group, group, side) endfunction function! s:get_seperator(self, prev_group, group, side) - if s:should_change_group(a:prev_group, a:group) + if airline#builder#should_change_group(a:prev_group, a:group) return s:get_transitioned_seperator(a:self, a:prev_group, a:group, a:side) else return a:side ? a:self._context.left_alt_sep : a:self._context.right_alt_sep diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 940ccb0..6925699 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -14,7 +14,7 @@ function! s:prototype.insert_tabs(curtab, first_tab, last_tab) dict let self._right_position = self._left_position endfunction -function! s:prototype.try_insert_tab(tab, pos, sep_size, force) dict +function! s:prototype.try_insert_tab(tab, group, pos, sep_size, force) dict let tab_title = self.get_title(a:tab) let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size if a:force || self._remaining_space >= 0 @@ -25,7 +25,7 @@ function! s:prototype.try_insert_tab(tab, pos, sep_size, force) dict let pos += 1 endif - call self.insert_section(self.get_group(a:tab), tab_title, pos) + call self.insert_section(a:group, tab_title, pos) let self._right_position += 1 let pos += 1 @@ -42,6 +42,20 @@ function! s:prototype.try_insert_tab(tab, pos, sep_size, force) dict return 0 endfunction +function! s:get_separator_change(new_group, old_group, end_group, sep_size, alt_sep_size) + let sep_change = 0 + if !empty(a:end_group) + let sep_change += airline#builder#should_change_group(a:new_group, a:end_group) ? a:sep_size : a:alt_sep_size + endif + if !empty(a:old_group) + let sep_change += airline#builder#should_change_group(a:new_group, a:old_group) ? a:sep_size : a:alt_sep_size + if !empty(a:end_group) + let sep_change -= airline#builder#should_change_group(a:old_group, a:end_group) ? a:sep_size : a:alt_sep_size + endif + endif + return sep_change +endfunction + function! s:prototype.build() dict if has_key(self, '_left_position') let self._remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) @@ -53,16 +67,21 @@ function! s:prototype.build() dict let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) - " The left marker will have left_alt_sep, and the right will have left_sep. - let self._remaining_space -= 2 * skipped_tabs_marker_size + left_sep_size + left_alt_sep_size - " - " There are always two left_seps (either side of the selected tab) and all - " other seperators are left_alt_seps. - let self._remaining_space -= left_sep_size - left_alt_sep_size + " Allow space for the markers before we begin filling in titles. + let self._remaining_space -= 2 * skipped_tabs_marker_size + + 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) " Add the current tab + let group = self.get_group(self._left_tab) + let sep_change = + \ s:get_separator_change(group, "", outer_left_group, left_sep_size, left_alt_sep_size) + + \ s:get_separator_change(group, "", outer_right_group, left_sep_size, left_alt_sep_size) + let last_left_group = group + let last_right_group = group let self._left_tab -= - \ self.try_insert_tab(self._left_tab, self._left_position, left_sep_size, 1) + \ self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 1) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first @@ -71,18 +90,30 @@ function! s:prototype.build() dict " Add the tab to the right if !center_active && self._right_tab <= self._last_tab + let group = self.get_group(self._right_tab) + let sep_change = + \ s:get_separator_change(group, last_right_group, outer_right_group, left_sep_size, left_alt_sep_size) + let last_right_group = group let self._right_tab += - \ self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 1) + \ self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 1) endif while self._remaining_space > 0 let done = 0 if self._left_tab >= self._first_tab - let done = self.try_insert_tab(self._left_tab, self._left_position, left_alt_sep_size, 0) + let group = self.get_group(self._left_tab) + let sep_change = + \ s:get_separator_change(group, last_left_group, outer_left_group, left_sep_size, left_alt_sep_size) + let last_left_group = group + let done = self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 0) let self._left_tab -= done endif if self._right_tab <= self._last_tab && (center_active || !done) - let done = self.try_insert_tab(self._right_tab, self._right_position, left_alt_sep_size, 0) + let group = self.get_group(self._right_tab) + let sep_change = + \ s:get_separator_change(group, last_right_group, outer_right_group, left_sep_size, left_alt_sep_size) + let last_right_group = group + let done = self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 0) let self._right_tab += done endif if !done From a2e0ed982fac53f7023d4145de2900926037d13c Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sun, 18 Mar 2018 01:13:30 +0000 Subject: [PATCH 42/54] Rename left{,_alt}_sep_size to {,alt_}sep_size --- autoload/airline/extensions/tabline/builder.vim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 6925699..df2ac34 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -62,8 +62,8 @@ function! s:prototype.build() dict let center_active = get(g:, 'airline#extensions#tabline#center_active', 0) - let left_sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) - let left_alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) + let sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) + let alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) @@ -76,8 +76,8 @@ function! s:prototype.build() dict " Add the current tab let group = self.get_group(self._left_tab) let sep_change = - \ s:get_separator_change(group, "", outer_left_group, left_sep_size, left_alt_sep_size) + - \ s:get_separator_change(group, "", outer_right_group, left_sep_size, left_alt_sep_size) + \ s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) + + \ s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) let last_left_group = group let last_right_group = group let self._left_tab -= @@ -92,7 +92,7 @@ function! s:prototype.build() dict if !center_active && self._right_tab <= self._last_tab let group = self.get_group(self._right_tab) let sep_change = - \ s:get_separator_change(group, last_right_group, outer_right_group, left_sep_size, left_alt_sep_size) + \ s:get_separator_change(group, last_right_group, outer_right_group, sep_size, alt_sep_size) let last_right_group = group let self._right_tab += \ self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 1) @@ -103,7 +103,7 @@ function! s:prototype.build() dict if self._left_tab >= self._first_tab let group = self.get_group(self._left_tab) let sep_change = - \ s:get_separator_change(group, last_left_group, outer_left_group, left_sep_size, left_alt_sep_size) + \ s:get_separator_change(group, last_left_group, outer_left_group, sep_size, alt_sep_size) let last_left_group = group let done = self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 0) let self._left_tab -= done @@ -111,7 +111,7 @@ function! s:prototype.build() dict if self._right_tab <= self._last_tab && (center_active || !done) let group = self.get_group(self._right_tab) let sep_change = - \ s:get_separator_change(group, last_right_group, outer_right_group, left_sep_size, left_alt_sep_size) + \ s:get_separator_change(group, last_right_group, outer_right_group, sep_size, alt_sep_size) let last_right_group = group let done = self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 0) let self._right_tab += done From 75f53ef6e5e20369c55cde4b1eeb1eec3282d3aa Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sun, 18 Mar 2018 01:15:11 +0000 Subject: [PATCH 43/54] Rename last_{left,right}_group to {left,right}_group --- autoload/airline/extensions/tabline/builder.vim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index df2ac34..fc1c44a 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -78,8 +78,8 @@ function! s:prototype.build() dict let sep_change = \ s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) + \ s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) - let last_left_group = group - let last_right_group = group + let left_group = group + let right_group = group let self._left_tab -= \ self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 1) @@ -92,8 +92,8 @@ function! s:prototype.build() dict if !center_active && self._right_tab <= self._last_tab let group = self.get_group(self._right_tab) let sep_change = - \ s:get_separator_change(group, last_right_group, outer_right_group, sep_size, alt_sep_size) - let last_right_group = group + \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) + let right_group = group let self._right_tab += \ self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 1) endif @@ -103,16 +103,16 @@ function! s:prototype.build() dict if self._left_tab >= self._first_tab let group = self.get_group(self._left_tab) let sep_change = - \ s:get_separator_change(group, last_left_group, outer_left_group, sep_size, alt_sep_size) - let last_left_group = group + \ s:get_separator_change(group, left_group, outer_left_group, sep_size, alt_sep_size) + let left_group = group let done = self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 0) let self._left_tab -= done endif if self._right_tab <= self._last_tab && (center_active || !done) let group = self.get_group(self._right_tab) let sep_change = - \ s:get_separator_change(group, last_right_group, outer_right_group, sep_size, alt_sep_size) - let last_right_group = group + \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) + let right_group = group let done = self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 0) let self._right_tab += done endif From 3914d5b4758eb4149d4728d6429c9ea2c3475a2d Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sun, 18 Mar 2018 01:17:53 +0000 Subject: [PATCH 44/54] Rename skipped_tabs_marker to overflow_marker --- autoload/airline/extensions/tabline/builder.vim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index fc1c44a..03c09ff 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -65,10 +65,10 @@ function! s:prototype.build() dict let sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) let alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) - let skipped_tabs_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let skipped_tabs_marker_size = s:strchars(s:evaluate_tabline(skipped_tabs_marker)) + let overflow_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) + let overflow_marker_size = s:strchars(s:evaluate_tabline(overflow_marker)) " Allow space for the markers before we begin filling in titles. - let self._remaining_space -= 2 * skipped_tabs_marker_size + let self._remaining_space -= 2 * overflow_marker_size 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) @@ -125,12 +125,12 @@ function! s:prototype.build() dict if get(g:, 'airline#extensions#tabline#current_first', 0) let self._left_position -= 1 endif - call self.insert_raw('%#'.self.overflow_group.'#'.skipped_tabs_marker, self._left_position) + call self.insert_raw('%#'.self.overflow_group.'#'.overflow_marker, self._left_position) let self._right_position += 1 endif if self._right_tab <= self._last_tab - call self.insert_raw('%#'.self.overflow_group.'#'.skipped_tabs_marker, self._right_position) + call self.insert_raw('%#'.self.overflow_group.'#'.overflow_marker, self._right_position) endif endif From 0b47adf0872ea238c0b049ded62ec17394c4c5f4 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 19 Mar 2018 14:27:06 +0000 Subject: [PATCH 45/54] Rename tab -> title in tabline/builder method names --- autoload/airline/extensions/tabline/buffers.vim | 2 +- autoload/airline/extensions/tabline/builder.vim | 12 ++++++------ autoload/airline/extensions/tabline/tabs.vim | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index a9dfe3b..512d517 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -126,7 +126,7 @@ function! airline#extensions#tabline#buffers#get() endfunction let last_buffer = len(b.buffers) - 1 - call b.insert_tabs(index(b.buffers, cur), 0, last_buffer) + call b.insert_titles(index(b.buffers, cur), 0, last_buffer) call b.add_section('airline_tabfill', '') call b.split() diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 03c09ff..1a09a59 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,7 +5,7 @@ scriptencoding utf-8 let s:prototype = {} -function! s:prototype.insert_tabs(curtab, first_tab, last_tab) dict +function! s:prototype.insert_titles(curtab, first_tab, last_tab) dict let self._first_tab = a:first_tab let self._last_tab = a:last_tab let self._left_tab = a:curtab @@ -14,7 +14,7 @@ function! s:prototype.insert_tabs(curtab, first_tab, last_tab) dict let self._right_position = self._left_position endfunction -function! s:prototype.try_insert_tab(tab, group, pos, sep_size, force) dict +function! s:prototype.try_insert_title(tab, group, pos, sep_size, force) dict let tab_title = self.get_title(a:tab) let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size if a:force || self._remaining_space >= 0 @@ -81,7 +81,7 @@ function! s:prototype.build() dict let left_group = group let right_group = group let self._left_tab -= - \ self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 1) + \ self.try_insert_title(self._left_tab, group, self._left_position, sep_change, 1) if get(g:, 'airline#extensions#tabline#current_first', 0) " always have current tabpage first @@ -95,7 +95,7 @@ function! s:prototype.build() dict \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) let right_group = group let self._right_tab += - \ self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 1) + \ self.try_insert_title(self._right_tab, group, self._right_position, sep_change, 1) endif while self._remaining_space > 0 @@ -105,7 +105,7 @@ function! s:prototype.build() dict let sep_change = \ s:get_separator_change(group, left_group, outer_left_group, sep_size, alt_sep_size) let left_group = group - let done = self.try_insert_tab(self._left_tab, group, self._left_position, sep_change, 0) + let done = self.try_insert_title(self._left_tab, group, self._left_position, sep_change, 0) let self._left_tab -= done endif if self._right_tab <= self._last_tab && (center_active || !done) @@ -113,7 +113,7 @@ function! s:prototype.build() dict let sep_change = \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) let right_group = group - let done = self.try_insert_tab(self._right_tab, group, self._right_position, sep_change, 0) + let done = self.try_insert_title(self._right_tab, group, self._right_position, sep_change, 0) let self._right_tab += done endif if !done diff --git a/autoload/airline/extensions/tabline/tabs.vim b/autoload/airline/extensions/tabline/tabs.vim index 9e3270d..e32cc4a 100644 --- a/autoload/airline/extensions/tabline/tabs.vim +++ b/autoload/airline/extensions/tabline/tabs.vim @@ -71,7 +71,7 @@ function! airline#extensions#tabline#tabs#get() return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' endfunction - call b.insert_tabs(curtab, 1, tabpagenr('$')) + call b.insert_titles(curtab, 1, tabpagenr('$')) call b.add_section('airline_tabfill', '') call b.split() From 5b7b9cf65649b9a130e2626307d7f69562e60203 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 19 Mar 2018 14:34:38 +0000 Subject: [PATCH 46/54] Rename remaining tab -> title in tabline/builder --- .../airline/extensions/tabline/buffers.vim | 8 +-- .../airline/extensions/tabline/builder.vim | 64 +++++++++---------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index 512d517..ff6e34f 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -143,11 +143,11 @@ function! airline#extensions#tabline#buffers#get() let s:column_width = &columns let s:current_tabline = b.build() let s:current_visible_buffers = copy(b.buffers) - if b._right_tab <= last_buffer - call remove(s:current_visible_buffers, b._right_tab, last_buffer) + if b._right_title <= last_buffer + call remove(s:current_visible_buffers, b._right_title, last_buffer) endif - if b._left_tab > 0 - call remove(s:current_visible_buffers, 0, b._left_tab) + if b._left_title > 0 + call remove(s:current_visible_buffers, 0, b._left_title) endif return s:current_tabline endfunction diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 1a09a59..2ce97c7 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,39 +5,39 @@ scriptencoding utf-8 let s:prototype = {} -function! s:prototype.insert_titles(curtab, first_tab, last_tab) dict - let self._first_tab = a:first_tab - let self._last_tab = a:last_tab - let self._left_tab = a:curtab - let self._right_tab = a:curtab + 1 +function! s:prototype.insert_titles(current, first, last) dict + let self._first_title = a:first + let self._last_title = a:last + let self._left_title = a:current + let self._right_title = a:current + 1 let self._left_position = self.get_position() let self._right_position = self._left_position endfunction -function! s:prototype.try_insert_title(tab, group, pos, sep_size, force) dict - let tab_title = self.get_title(a:tab) - let self._remaining_space -= s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size +function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict + let title = self.get_title(a:index) + let self._remaining_space -= s:strchars(s:evaluate_tabline(title)) + a:sep_size if a:force || self._remaining_space >= 0 let pos = a:pos if has_key(self, "get_pretitle") - call self.insert_raw(self.get_pretitle(a:tab), pos) + 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, tab_title, pos) + 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:tab), pos) + call self.insert_raw(self.get_posttitle(a:index), pos) let self._right_position += 1 let pos += 1 endif return 1 else - let self._remaining_space += s:strchars(s:evaluate_tabline(tab_title)) + a:sep_size + let self._remaining_space += s:strchars(s:evaluate_tabline(title)) + a:sep_size endif return 0 endfunction @@ -73,55 +73,55 @@ function! s:prototype.build() dict 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) - " Add the current tab - let group = self.get_group(self._left_tab) + " Add the current title + let group = self.get_group(self._left_title) let sep_change = \ s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) + \ s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) let left_group = group let right_group = group - let self._left_tab -= - \ self.try_insert_title(self._left_tab, group, self._left_position, sep_change, 1) + 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 tabpage first + " always have current title first let self._left_position += 1 endif - " Add the tab to the right - if !center_active && self._right_tab <= self._last_tab - let group = self.get_group(self._right_tab) + " Add the title to the right + if !center_active && self._right_title <= self._last_title + let group = self.get_group(self._right_title) let sep_change = \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) let right_group = group - let self._right_tab += - \ self.try_insert_title(self._right_tab, group, self._right_position, sep_change, 1) + 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_tab >= self._first_tab - let group = self.get_group(self._left_tab) + if self._left_title >= self._first_title + let group = self.get_group(self._left_title) let sep_change = \ s:get_separator_change(group, left_group, outer_left_group, sep_size, alt_sep_size) let left_group = group - let done = self.try_insert_title(self._left_tab, group, self._left_position, sep_change, 0) - let self._left_tab -= done + let done = self.try_insert_title(self._left_title, group, self._left_position, sep_change, 0) + let self._left_title -= done endif - if self._right_tab <= self._last_tab && (center_active || !done) - let group = self.get_group(self._right_tab) + if self._right_title <= self._last_title && (center_active || !done) + let group = self.get_group(self._right_title) let sep_change = \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) let right_group = group - let done = self.try_insert_title(self._right_tab, group, self._right_position, sep_change, 0) - let self._right_tab += done + 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_tab >= self._first_tab + if self._left_title >= self._first_title if get(g:, 'airline#extensions#tabline#current_first', 0) let self._left_position -= 1 endif @@ -129,7 +129,7 @@ function! s:prototype.build() dict let self._right_position += 1 endif - if self._right_tab <= self._last_tab + if self._right_title <= self._last_title call self.insert_raw('%#'.self.overflow_group.'#'.overflow_marker, self._right_position) endif endif From 51bb8dd7e045d500f4938ef3b71d349f70033373 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 19 Mar 2018 14:58:50 +0000 Subject: [PATCH 47/54] Move strchars into util.vim --- .../airline/extensions/tabline/builder.vim | 22 +++++-------------- autoload/airline/util.vim | 10 +++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 2ce97c7..d0a0a31 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -16,7 +16,7 @@ endfunction function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict let title = self.get_title(a:index) - let self._remaining_space -= s:strchars(s:evaluate_tabline(title)) + a:sep_size + let self._remaining_space -= airline#util#strchars(s:evaluate_tabline(title)) + a:sep_size if a:force || self._remaining_space >= 0 let pos = a:pos if has_key(self, "get_pretitle") @@ -37,7 +37,7 @@ function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict return 1 else - let self._remaining_space += s:strchars(s:evaluate_tabline(title)) + a:sep_size + let self._remaining_space += airline#util#strchars(s:evaluate_tabline(title)) + a:sep_size endif return 0 endfunction @@ -58,15 +58,15 @@ endfunction function! s:prototype.build() dict if has_key(self, '_left_position') - let self._remaining_space = &columns - s:strchars(s:evaluate_tabline(self._build())) + let self._remaining_space = &columns - airline#util#strchars(s:evaluate_tabline(self._build())) let center_active = get(g:, 'airline#extensions#tabline#center_active', 0) - let sep_size = s:strchars(s:evaluate_tabline(self._context.left_sep)) - let alt_sep_size = s:strchars(s:evaluate_tabline(self._context.left_alt_sep)) + let sep_size = airline#util#strchars(s:evaluate_tabline(self._context.left_sep)) + let alt_sep_size = airline#util#strchars(s:evaluate_tabline(self._context.left_alt_sep)) let overflow_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let overflow_marker_size = s:strchars(s:evaluate_tabline(overflow_marker)) + let overflow_marker_size = airline#util#strchars(s:evaluate_tabline(overflow_marker)) " Allow space for the markers before we begin filling in titles. let self._remaining_space -= 2 * overflow_marker_size @@ -153,16 +153,6 @@ function! s:evaluate_tabline(tabline) return tabline endfunction -" Compatibility wrapper for strchars, in case this vim version does not -" have it natively -function! s:strchars(str) - if exists('*strchars') - return strchars(a:str) - else - return strlen(substitute(a:str, '.', 'a', 'g')) - endif -endfunction - function! airline#extensions#tabline#builder#new(context) let builder = airline#builder#new(a:context) let builder._build = builder.build diff --git a/autoload/airline/util.vim b/autoload/airline/util.vim index e0bec92..23c44c4 100644 --- a/autoload/airline/util.vim +++ b/autoload/airline/util.vim @@ -86,3 +86,13 @@ else return 0 endfunction endif + +" Compatibility wrapper for strchars, in case this vim version does not +" have it natively +function! airline#util#strchars(str) + if exists('*strchars') + return strchars(a:str) + else + return strlen(substitute(a:str, '.', 'a', 'g')) + endif +endfunction From 7396dc7a1033d6a21c13b5ac1eb04b9e5d99aa37 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 19 Mar 2018 15:01:56 +0000 Subject: [PATCH 48/54] Create helper function tabline_evaluated_length --- autoload/airline/extensions/tabline/builder.vim | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index d0a0a31..bfd1e7f 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -16,7 +16,7 @@ endfunction function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict let title = self.get_title(a:index) - let self._remaining_space -= airline#util#strchars(s:evaluate_tabline(title)) + a:sep_size + let self._remaining_space -= s:tabline_evaluated_length(title) + a:sep_size if a:force || self._remaining_space >= 0 let pos = a:pos if has_key(self, "get_pretitle") @@ -37,7 +37,7 @@ function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict return 1 else - let self._remaining_space += airline#util#strchars(s:evaluate_tabline(title)) + a:sep_size + let self._remaining_space += s:tabline_evaluated_length(title) + a:sep_size endif return 0 endfunction @@ -58,15 +58,15 @@ endfunction function! s:prototype.build() dict if has_key(self, '_left_position') - let self._remaining_space = &columns - airline#util#strchars(s:evaluate_tabline(self._build())) + 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 = airline#util#strchars(s:evaluate_tabline(self._context.left_sep)) - let alt_sep_size = airline#util#strchars(s:evaluate_tabline(self._context.left_alt_sep)) + 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 overflow_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) - let overflow_marker_size = airline#util#strchars(s:evaluate_tabline(overflow_marker)) + let overflow_marker_size = s:tabline_evaluated_length(overflow_marker) " Allow space for the markers before we begin filling in titles. let self._remaining_space -= 2 * overflow_marker_size @@ -153,6 +153,10 @@ function! s:evaluate_tabline(tabline) 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 From 2528de7d817cc1326b8f0121d8a558e3c2064891 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Mon, 19 Mar 2018 15:57:46 +0000 Subject: [PATCH 49/54] Add comments to tabline/builder --- .../airline/extensions/tabline/builder.vim | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index bfd1e7f..44157e3 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -5,15 +5,39 @@ 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 - let self._last_title = a:last - let self._left_title = a:current - let self._right_title = a:current + 1 - let self._left_position = self.get_position() - let self._right_position = self._left_position + 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 self._remaining_space -= s:tabline_evaluated_length(title) + a:sep_size @@ -42,20 +66,30 @@ function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict return 0 endfunction +" Compute the size of the change in tabs 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(new_group, old_group, end_group, sep_size, alt_sep_size) let sep_change = 0 - if !empty(a:end_group) + if !empty(a:end_group) " Separator between title and the end let sep_change += airline#builder#should_change_group(a:new_group, a:end_group) ? a:sep_size : a:alt_sep_size endif - if !empty(a:old_group) + 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:end_group) + if !empty(a:end_group) " Remove mis-predicted separator let sep_change -= airline#builder#should_change_group(a:old_group, a: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') let self._remaining_space = &columns - s:tabline_evaluated_length(self._build()) @@ -88,8 +122,8 @@ function! s:prototype.build() dict let self._left_position += 1 endif - " Add the title to the right if !center_active && self._right_title <= self._last_title + " Add the title to the right let group = self.get_group(self._right_title) let sep_change = \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) @@ -101,6 +135,7 @@ function! s:prototype.build() dict 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) let sep_change = \ s:get_separator_change(group, left_group, outer_left_group, sep_size, alt_sep_size) @@ -108,7 +143,10 @@ function! s:prototype.build() dict 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) let sep_change = \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) @@ -139,6 +177,9 @@ 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') From df2f380c9ed39947f34f6f3b60c255bf8859717e Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 22 Mar 2018 15:41:25 +0000 Subject: [PATCH 50/54] Add get_separator_change_with_end to tabline builder --- autoload/airline/extensions/tabline/builder.vim | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 44157e3..f1e792f 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -66,19 +66,23 @@ function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict return 0 endfunction -" Compute the size of the change in tabs caused by separators +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(new_group, old_group, end_group, sep_size, alt_sep_size) +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:end_group) " Separator between title and the end - let sep_change += airline#builder#should_change_group(a:new_group, a:end_group) ? a:sep_size : a:alt_sep_size + 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:end_group) " Remove mis-predicted separator - let sep_change -= airline#builder#should_change_group(a:old_group, a:end_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 From 4b1913ad138b5c1ef8bdd7627aeb267fb4b004ad Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 22 Mar 2018 16:01:06 +0000 Subject: [PATCH 51/54] Use insert_section for overflow markers in tabline builder --- .../airline/extensions/tabline/builder.vim | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index f1e792f..73a25e2 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -103,19 +103,33 @@ function! s:prototype.build() dict 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 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. - let self._remaining_space -= 2 * overflow_marker_size - 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) - let sep_change = - \ s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) + - \ s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) + 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 -= @@ -129,8 +143,11 @@ function! s:prototype.build() dict if !center_active && self._right_title <= self._last_title " Add the title to the right let group = self.get_group(self._right_title) - let sep_change = - \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) + 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) @@ -141,8 +158,11 @@ function! s:prototype.build() dict if self._left_title >= self._first_title " Insert next title to the left let group = self.get_group(self._left_title) - let sep_change = - \ s:get_separator_change(group, left_group, outer_left_group, sep_size, alt_sep_size) + 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 @@ -152,8 +172,11 @@ function! s:prototype.build() dict if self._right_title <= self._last_title && (center_active || !done) " Insert next title to the right let group = self.get_group(self._right_title) - let sep_change = - \ s:get_separator_change(group, right_group, outer_right_group, sep_size, alt_sep_size) + 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 @@ -167,12 +190,12 @@ function! s:prototype.build() dict if get(g:, 'airline#extensions#tabline#current_first', 0) let self._left_position -= 1 endif - call self.insert_raw('%#'.self.overflow_group.'#'.overflow_marker, self._left_position) + 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_raw('%#'.self.overflow_group.'#'.overflow_marker, self._right_position) + call self.insert_section(self.overflow_group, overflow_marker, self._right_position) endif endif From c75106f12d9a7762cb55603afc58b63390442920 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Thu, 22 Mar 2018 16:03:01 +0000 Subject: [PATCH 52/54] Don't change remaining_space in tabline builder until necessary --- autoload/airline/extensions/tabline/builder.vim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 73a25e2..7e7d49f 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -40,8 +40,8 @@ endfunction " 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 self._remaining_space -= s:tabline_evaluated_length(title) + a:sep_size - if a:force || self._remaining_space >= 0 + 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) @@ -59,9 +59,8 @@ function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict let pos += 1 endif + let self._remaining_space -= title_size return 1 - else - let self._remaining_space += s:tabline_evaluated_length(title) + a:sep_size endif return 0 endfunction From aee733aa877911c9ae192fd1d6b9f8a0a169883c Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sun, 1 Apr 2018 00:16:29 +0100 Subject: [PATCH 53/54] Don't show titles in the tabline if there aren't any airline#extensions#tabline#buflist#list doesn't pick up some buffers (most notably Netrw buffers), so there are sometimes no buffers to show and the tabline code fails with an error. This avoids that situation. It would be better to detect these and show titles for them, but for now this restores the old behaviour. --- autoload/airline/extensions/tabline/builder.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/builder.vim b/autoload/airline/extensions/tabline/builder.vim index 7e7d49f..20964b1 100644 --- a/autoload/airline/extensions/tabline/builder.vim +++ b/autoload/airline/extensions/tabline/builder.vim @@ -94,7 +94,7 @@ endfunction " 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') + 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) From 47c36d281912f5201a5a2a8ae3fc9655059be600 Mon Sep 17 00:00:00 2001 From: mrmr1993 Date: Sun, 1 Apr 2018 01:16:20 +0100 Subject: [PATCH 54/54] Don't let the current buffer be -1 when calculating the tabline --- autoload/airline/extensions/tabline/buffers.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autoload/airline/extensions/tabline/buffers.vim b/autoload/airline/extensions/tabline/buffers.vim index ff6e34f..ea19df1 100644 --- a/autoload/airline/extensions/tabline/buffers.vim +++ b/autoload/airline/extensions/tabline/buffers.vim @@ -125,8 +125,9 @@ function! airline#extensions#tabline#buffers#get() endif endfunction + let current_buffer = max([index(b.buffers, cur), 0]) let last_buffer = len(b.buffers) - 1 - call b.insert_titles(index(b.buffers, cur), 0, last_buffer) + call b.insert_titles(current_buffer, 0, last_buffer) call b.add_section('airline_tabfill', '') call b.split()