From d16e82d468eb0d5bb1e662ac4812c0ca6fc0fc64 Mon Sep 17 00:00:00 2001 From: Yaroslav Date: Tue, 25 Feb 2020 14:47:03 +0300 Subject: reorganized repo to be easier to use with GNU stow; added script to stow --- .../airline/extensions/tabline/builder.vim | 232 +++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim (limited to 'dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim') diff --git a/dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim b/dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim new file mode 100644 index 0000000..20964b1 --- /dev/null +++ b/dotfiles/.vim/autoload/airline/extensions/tabline/builder.vim @@ -0,0 +1,232 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:prototype = {} + +" Set the point in the tabline where the builder should insert the titles. +" +" Subsequent calls will overwrite the previous ones, so only the last call +" determines to location to insert titles. +" +" NOTE: The titles are not inserted until |build| is called, so that the +" remaining contents of the tabline can be taken into account. +" +" Callers should define at least |get_title| and |get_group| on the host +" object before calling |build|. +function! s:prototype.insert_titles(current, first, last) dict + let self._first_title = a:first " lowest index + let self._last_title = a:last " highest index + let self._left_title = a:current " next index to add on the left + let self._right_title = a:current + 1 " next index to add on the right + let self._left_position = self.get_position() " left end of titles + let self._right_position = self._left_position " right end of the titles +endfunction + +" Insert a title for entry number |index|, of group |group| at position |pos|, +" if there is space for it. Returns 1 if it is inserted, 0 otherwise +" +" |force| inserts the title even if there isn't enough space left for it. +" |sep_size| adjusts the size change that the title is considered to take up, +" to account for changes to the separators +" +" The title is defined by |get_title| on the hosting object, called with +" |index| as its only argument. +" |get_pretitle| and |get_posttitle| may be defined on the host object to +" insert some formatting before or after the title. These should be 0-width. +" +" This method updates |_right_position| and |_remaining_space| on the host +" object, if the title is inserted. +function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict + let title = self.get_title(a:index) + let title_size = s:tabline_evaluated_length(title) + a:sep_size + if a:force || self._remaining_space >= title_size + let pos = a:pos + if has_key(self, "get_pretitle") + call self.insert_raw(self.get_pretitle(a:index), pos) + let self._right_position += 1 + let pos += 1 + endif + + call self.insert_section(a:group, title, pos) + let self._right_position += 1 + let pos += 1 + + if has_key(self, "get_posttitle") + call self.insert_raw(self.get_posttitle(a:index), pos) + let self._right_position += 1 + let pos += 1 + endif + + let self._remaining_space -= title_size + return 1 + endif + return 0 +endfunction + +function! s:get_separator_change(new_group, old_group, end_group, sep_size, alt_sep_size) + return s:get_separator_change_with_end(a:new_group, a:old_group, a:end_group, a:end_group, a:sep_size, a:alt_sep_size) +endfunction + +" Compute the change in size of the tabline caused by separators +" +" This should be kept up-to-date with |s:get_transitioned_seperator| and +" |s:get_separator| in autoload/airline/builder.vim +function! s:get_separator_change_with_end(new_group, old_group, new_end_group, old_end_group, sep_size, alt_sep_size) + let sep_change = 0 + if !empty(a:new_end_group) " Separator between title and the end + let sep_change += airline#builder#should_change_group(a:new_group, a:new_end_group) ? a:sep_size : a:alt_sep_size + endif + if !empty(a:old_group) " Separator between the title and the one adjacent + let sep_change += airline#builder#should_change_group(a:new_group, a:old_group) ? a:sep_size : a:alt_sep_size + if !empty(a:old_end_group) " Remove mis-predicted separator + let sep_change -= airline#builder#should_change_group(a:old_group, a:old_end_group) ? a:sep_size : a:alt_sep_size + endif + endif + return sep_change +endfunction + +" This replaces the build function of the |airline#builder#new| object, to +" insert titles as specified by the last call to |insert_titles| before +" passing to the original build function. +" +" Callers should define at least |get_title| and |get_group| on the host +" object if |insert_titles| has been called on it. +function! s:prototype.build() dict + if has_key(self, '_left_position') && self._first_title <= self._last_title + let self._remaining_space = &columns - s:tabline_evaluated_length(self._build()) + + let center_active = get(g:, 'airline#extensions#tabline#center_active', 0) + + let sep_size = s:tabline_evaluated_length(self._context.left_sep) + let alt_sep_size = s:tabline_evaluated_length(self._context.left_alt_sep) + + let outer_left_group = airline#builder#get_prev_group(self._sections, self._left_position) + let outer_right_group = airline#builder#get_next_group(self._sections, self._right_position) + + let overflow_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) + let overflow_marker_size = s:tabline_evaluated_length(overflow_marker) + " Allow space for the markers before we begin filling in titles. + if self._left_title > self._first_title + let self._remaining_space -= overflow_marker_size + + \ s:get_separator_change(self.overflow_group, "", outer_left_group, sep_size, alt_sep_size) + endif + if self._left_title < self._last_title + let self._remaining_space -= overflow_marker_size + + \ s:get_separator_change(self.overflow_group, "", outer_right_group, sep_size, alt_sep_size) + endif + + " Add the current title + let group = self.get_group(self._left_title) + if self._left_title == self._first_title + let sep_change = s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) + else + let sep_change = s:get_separator_change(group, "", self.overflow_group, sep_size, alt_sep_size) + endif + if self._left_title == self._last_title + let sep_change += s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) + else + let sep_change += s:get_separator_change(group, "", self.overflow_group, sep_size, alt_sep_size) + endif + let left_group = group + let right_group = group + let self._left_title -= + \ self.try_insert_title(self._left_title, group, self._left_position, sep_change, 1) + + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current title first + let self._left_position += 1 + endif + + if !center_active && self._right_title <= self._last_title + " Add the title to the right + let group = self.get_group(self._right_title) + if self._right_title == self._last_title + let sep_change = s:get_separator_change_with_end(group, right_group, outer_right_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size + else + let sep_change = s:get_separator_change(group, right_group, self.overflow_group, sep_size, alt_sep_size) + endif + let right_group = group + let self._right_title += + \ self.try_insert_title(self._right_title, group, self._right_position, sep_change, 1) + endif + + while self._remaining_space > 0 + let done = 0 + if self._left_title >= self._first_title + " Insert next title to the left + let group = self.get_group(self._left_title) + if self._left_title == self._first_title + let sep_change = s:get_separator_change_with_end(group, left_group, outer_left_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size + else + let sep_change = s:get_separator_change(group, left_group, self.overflow_group, sep_size, alt_sep_size) + endif + let left_group = group + let done = self.try_insert_title(self._left_title, group, self._left_position, sep_change, 0) + let self._left_title -= done + endif + " If center_active is set, this |if| operates as an independent |if|, + " otherwise as an |elif|. + if self._right_title <= self._last_title && (center_active || !done) + " Insert next title to the right + let group = self.get_group(self._right_title) + if self._right_title == self._last_title + let sep_change = s:get_separator_change_with_end(group, right_group, outer_right_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size + else + let sep_change = s:get_separator_change(group, right_group, self.overflow_group, sep_size, alt_sep_size) + endif + let right_group = group + let done = self.try_insert_title(self._right_title, group, self._right_position, sep_change, 0) + let self._right_title += done + endif + if !done + break + endif + endwhile + + if self._left_title >= self._first_title + if get(g:, 'airline#extensions#tabline#current_first', 0) + let self._left_position -= 1 + endif + call self.insert_section(self.overflow_group, overflow_marker, self._left_position) + let self._right_position += 1 + endif + + if self._right_title <= self._last_title + call self.insert_section(self.overflow_group, overflow_marker, self._right_position) + endif + endif + + return self._build() +endfunction + +let s:prototype.overflow_group = 'airline_tab' + +" Extract the text content a tabline will render. (Incomplete). +" +" See :help 'statusline' for the list of fields. +function! s:evaluate_tabline(tabline) + let tabline = a:tabline + let tabline = substitute(tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') + let tabline = substitute(tabline, '%#[^#]\+#', '', 'g') + let tabline = substitute(tabline, '%(\([^)]\+\)%)', '\1', 'g') + let tabline = substitute(tabline, '%\d\+[TX]', '', 'g') + let tabline = substitute(tabline, '%=', '', 'g') + let tabline = substitute(tabline, '%\d*\*', '', 'g') + if has('tablineat') + let tabline = substitute(tabline, '%@[^@]\+@', '', 'g') + endif + return tabline +endfunction + +function! s:tabline_evaluated_length(tabline) + return airline#util#strchars(s:evaluate_tabline(a:tabline)) +endfunction + +function! airline#extensions#tabline#builder#new(context) + let builder = airline#builder#new(a:context) + let builder._build = builder.build + call extend(builder, s:prototype, 'force') + return builder +endfunction -- cgit v1.2.3