2018-01-05 17:37:59 +08:00
|
|
|
" MIT License. Copyright (c) 2013-2018 Bailey Ling et al.
|
2013-08-18 04:44:53 +08:00
|
|
|
" vim: et ts=2 sts=2 sw=2
|
|
|
|
|
2016-09-24 08:16:30 +08:00
|
|
|
scriptencoding utf-8
|
|
|
|
|
2013-08-18 04:44:53 +08:00
|
|
|
let s:prototype = {}
|
|
|
|
|
2016-12-13 15:44:39 +08:00
|
|
|
function! s:prototype.split(...) dict
|
2014-10-19 01:30:21 +08:00
|
|
|
call add(self._sections, ['|', a:0 ? a:1 : '%='])
|
2013-08-18 04:44:53 +08:00
|
|
|
endfunction
|
|
|
|
|
2016-12-13 15:44:39 +08:00
|
|
|
function! s:prototype.add_section_spaced(group, contents) dict
|
2016-05-13 03:34:29 +08:00
|
|
|
let spc = empty(a:contents) ? '' : g:airline_symbols.space
|
|
|
|
call self.add_section(a:group, spc.a:contents.spc)
|
2013-10-02 09:23:17 +08:00
|
|
|
endfunction
|
|
|
|
|
2016-12-13 15:44:39 +08:00
|
|
|
function! s:prototype.add_section(group, contents) dict
|
2014-10-19 01:30:21 +08:00
|
|
|
call add(self._sections, [a:group, a:contents])
|
|
|
|
endfunction
|
|
|
|
|
2016-12-13 15:44:39 +08:00
|
|
|
function! s:prototype.add_raw(text) dict
|
2014-10-19 01:30:21 +08:00
|
|
|
call add(self._sections, ['', a:text])
|
|
|
|
endfunction
|
|
|
|
|
2018-03-13 04:27:52 +08:00
|
|
|
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
|
|
|
|
|
2018-03-18 08:15:29 +08:00
|
|
|
function! airline#builder#get_prev_group(sections, i)
|
2014-11-23 00:52:54 +08:00
|
|
|
let x = a:i - 1
|
|
|
|
while x >= 0
|
|
|
|
let group = a:sections[x][0]
|
|
|
|
if group != '' && group != '|'
|
|
|
|
return group
|
|
|
|
endif
|
|
|
|
let x = x - 1
|
|
|
|
endwhile
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2018-03-18 08:15:29 +08:00
|
|
|
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
|
|
|
|
|
2016-12-13 15:44:39 +08:00
|
|
|
function! s:prototype.build() dict
|
2014-10-19 01:30:21 +08:00
|
|
|
let side = 1
|
|
|
|
let line = ''
|
2014-10-19 01:59:24 +08:00
|
|
|
let i = 0
|
|
|
|
let length = len(self._sections)
|
2014-11-23 00:52:54 +08:00
|
|
|
let split = 0
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
let is_empty = 0
|
|
|
|
let prev_group = ''
|
2014-10-19 01:30:21 +08:00
|
|
|
|
2014-10-19 01:59:24 +08:00
|
|
|
while i < length
|
|
|
|
let section = self._sections[i]
|
2014-10-19 01:30:21 +08:00
|
|
|
let group = section[0]
|
|
|
|
let contents = section[1]
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
let pgroup = prev_group
|
2018-03-18 08:15:29 +08:00
|
|
|
let prev_group = airline#builder#get_prev_group(self._sections, i)
|
2017-08-22 21:30:15 +08:00
|
|
|
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')
|
2016-09-09 00:39:29 +08:00
|
|
|
let group = 'airline_c'. self._context.bufnr
|
2016-09-26 17:33:25 +08:00
|
|
|
elseif prev_group ==# 'airline_c' && !self._context.active && has_key(self._context, 'bufnr')
|
|
|
|
let prev_group = 'airline_c'. self._context.bufnr
|
2016-09-09 00:39:29 +08:00
|
|
|
endif
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
if is_empty
|
|
|
|
let prev_group = pgroup
|
|
|
|
endif
|
|
|
|
let is_empty = s:section_is_empty(self, contents)
|
|
|
|
|
|
|
|
if is_empty
|
|
|
|
" need to fix highlighting groups, since we
|
|
|
|
" have skipped a section, we actually need
|
2016-09-24 08:16:30 +08:00
|
|
|
" the previous previous group and so the
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
" seperator goes from the previous previous group
|
|
|
|
" to the current group
|
|
|
|
let pgroup = group
|
|
|
|
endif
|
2014-10-19 01:30:21 +08:00
|
|
|
|
2014-10-19 01:59:24 +08:00
|
|
|
if group == ''
|
|
|
|
let line .= contents
|
|
|
|
elseif group == '|'
|
2014-10-19 01:30:21 +08:00
|
|
|
let side = 0
|
|
|
|
let line .= contents
|
2014-11-23 00:52:54 +08:00
|
|
|
let split = 1
|
2014-10-19 01:59:24 +08:00
|
|
|
else
|
2014-11-23 00:52:54 +08:00
|
|
|
if prev_group == ''
|
2014-10-19 01:59:24 +08:00
|
|
|
let line .= '%#'.group.'#'
|
2014-11-23 00:52:54 +08:00
|
|
|
elseif split
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
if !is_empty
|
|
|
|
let line .= s:get_transitioned_seperator(self, prev_group, group, side)
|
|
|
|
endif
|
2014-11-23 00:52:54 +08:00
|
|
|
let split = 0
|
|
|
|
else
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
if !is_empty
|
|
|
|
let line .= s:get_seperator(self, prev_group, group, side)
|
|
|
|
endif
|
2014-10-19 01:59:24 +08:00
|
|
|
endif
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
let line .= is_empty ? '' : s:get_accented_line(self, group, contents)
|
2014-10-19 01:30:21 +08:00
|
|
|
endif
|
2014-10-19 01:59:24 +08:00
|
|
|
|
|
|
|
let i = i + 1
|
|
|
|
endwhile
|
2014-10-19 01:30:21 +08:00
|
|
|
|
|
|
|
if !self._context.active
|
2016-09-09 00:39:29 +08:00
|
|
|
"let line = substitute(line, '%#airline_c#', '%#airline_c'.self._context.bufnr.'#', '')
|
2014-10-19 01:30:21 +08:00
|
|
|
let line = substitute(line, '%#.\{-}\ze#', '\0_inactive', 'g')
|
2013-09-07 11:06:08 +08:00
|
|
|
endif
|
2014-10-19 01:30:21 +08:00
|
|
|
return line
|
|
|
|
endfunction
|
2013-09-07 11:06:08 +08:00
|
|
|
|
2018-03-18 08:15:29 +08:00
|
|
|
function! airline#builder#should_change_group(group1, group2)
|
2014-11-16 03:49:02 +08:00
|
|
|
if a:group1 == a:group2
|
|
|
|
return 0
|
|
|
|
endif
|
|
|
|
let color1 = airline#highlighter#get_highlight(a:group1)
|
|
|
|
let color2 = airline#highlighter#get_highlight(a:group2)
|
2016-02-06 05:19:48 +08:00
|
|
|
if g:airline_gui_mode ==# 'gui'
|
2014-11-16 03:49:02 +08:00
|
|
|
return color1[1] != color2[1] || color1[0] != color2[0]
|
|
|
|
else
|
|
|
|
return color1[3] != color2[3] || color1[2] != color2[2]
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-11-23 00:52:54 +08:00
|
|
|
function! s:get_transitioned_seperator(self, prev_group, group, side)
|
2014-10-19 01:59:24 +08:00
|
|
|
let line = ''
|
2018-01-04 22:45:36 +08:00
|
|
|
if get(a:self._context, 'tabline', 0) && get(g:, 'airline#extensions#tabline#alt_sep', 0) && a:group ==# 'airline_tabsel' && a:side
|
|
|
|
call airline#highlighter#add_separator(a:prev_group, a:group, 0)
|
|
|
|
let line .= '%#'.a:prev_group.'_to_'.a:group.'#'
|
|
|
|
let line .= a:self._context.right_sep.'%#'.a:group.'#'
|
|
|
|
else
|
|
|
|
call airline#highlighter#add_separator(a:prev_group, a:group, a:side)
|
|
|
|
let line .= '%#'.a:prev_group.'_to_'.a:group.'#'
|
|
|
|
let line .= a:side ? a:self._context.left_sep : a:self._context.right_sep
|
|
|
|
let line .= '%#'.a:group.'#'
|
|
|
|
endif
|
2014-11-23 00:52:54 +08:00
|
|
|
return line
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:get_seperator(self, prev_group, group, side)
|
2018-03-18 08:15:29 +08:00
|
|
|
if airline#builder#should_change_group(a:prev_group, a:group)
|
2014-11-23 00:52:54 +08:00
|
|
|
return s:get_transitioned_seperator(a:self, a:prev_group, a:group, a:side)
|
2014-11-16 03:49:02 +08:00
|
|
|
else
|
2014-11-23 00:52:54 +08:00
|
|
|
return a:side ? a:self._context.left_alt_sep : a:self._context.right_alt_sep
|
2014-10-19 01:59:24 +08:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-10-19 01:30:21 +08:00
|
|
|
function! s:get_accented_line(self, group, contents)
|
|
|
|
if a:self._context.active
|
2018-11-08 23:44:26 +08:00
|
|
|
" active window
|
2013-09-23 05:15:02 +08:00
|
|
|
let contents = []
|
|
|
|
let content_parts = split(a:contents, '__accent')
|
|
|
|
for cpart in content_parts
|
|
|
|
let accent = matchstr(cpart, '_\zs[^#]*\ze')
|
|
|
|
call add(contents, cpart)
|
|
|
|
endfor
|
|
|
|
let line = join(contents, a:group)
|
|
|
|
let line = substitute(line, '__restore__', a:group, 'g')
|
|
|
|
else
|
2018-11-08 23:44:26 +08:00
|
|
|
" inactive window
|
2013-09-23 05:15:02 +08:00
|
|
|
let line = substitute(a:contents, '%#__accent[^#]*#', '', 'g')
|
|
|
|
let line = substitute(line, '%#__restore__#', '', 'g')
|
|
|
|
endif
|
2014-10-19 01:30:21 +08:00
|
|
|
return line
|
2013-08-18 04:44:53 +08:00
|
|
|
endfunction
|
2013-08-16 09:12:02 +08:00
|
|
|
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
function! s:section_is_empty(self, content)
|
|
|
|
let start=1
|
|
|
|
|
2016-09-28 03:44:00 +08:00
|
|
|
" do not check for inactive windows or the tabline
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
if a:self._context.active == 0
|
|
|
|
return 0
|
2016-09-28 03:44:00 +08:00
|
|
|
elseif get(a:self._context, 'tabline', 0)
|
|
|
|
return 0
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
endif
|
|
|
|
|
|
|
|
" only check, if airline#skip_empty_sections == 1
|
|
|
|
if get(g:, 'airline_skip_empty_sections', 0) == 0
|
|
|
|
return 0
|
|
|
|
endif
|
2017-04-10 15:17:23 +08:00
|
|
|
|
|
|
|
" only check, if airline#skip_empty_sections == 1
|
2017-04-12 04:10:43 +08:00
|
|
|
if get(w:, 'airline_skip_empty_sections', -1) == 0
|
2017-04-10 15:17:23 +08:00
|
|
|
return 0
|
|
|
|
endif
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
" assume accents sections to be never empty
|
|
|
|
" (avoides, that on startup the mode message becomes empty)
|
|
|
|
if match(a:content, '%#__accent_[^#]*#.*__restore__#') > -1
|
|
|
|
return 0
|
|
|
|
endif
|
2016-09-25 04:06:41 +08:00
|
|
|
if empty(a:content)
|
|
|
|
return 1
|
|
|
|
endif
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
let list=matchlist(a:content, '%{\zs.\{-}\ze}', 1, start)
|
|
|
|
if empty(list)
|
|
|
|
return 0 " no function in statusline text
|
|
|
|
endif
|
|
|
|
while len(list) > 0
|
|
|
|
let expr = list[0]
|
|
|
|
try
|
|
|
|
" catch all exceptions, just in case
|
|
|
|
if !empty(eval(expr))
|
|
|
|
return 0
|
|
|
|
endif
|
|
|
|
catch
|
|
|
|
return 0
|
|
|
|
endtry
|
|
|
|
let start += 1
|
|
|
|
let list=matchlist(a:content, '%{\zs.\{-}\ze}', 1, start)
|
|
|
|
endw
|
|
|
|
return 1
|
|
|
|
endfunction
|
|
|
|
|
2013-08-24 21:40:20 +08:00
|
|
|
function! airline#builder#new(context)
|
2013-08-18 04:44:53 +08:00
|
|
|
let builder = copy(s:prototype)
|
2013-08-24 13:08:22 +08:00
|
|
|
let builder._context = a:context
|
2014-10-19 01:30:21 +08:00
|
|
|
let builder._sections = []
|
2013-09-05 03:20:06 +08:00
|
|
|
|
|
|
|
call extend(builder._context, {
|
|
|
|
\ 'left_sep': g:airline_left_sep,
|
|
|
|
\ 'left_alt_sep': g:airline_left_alt_sep,
|
|
|
|
\ 'right_sep': g:airline_right_sep,
|
|
|
|
\ 'right_alt_sep': g:airline_right_alt_sep,
|
|
|
|
\ }, 'keep')
|
2013-08-16 09:12:02 +08:00
|
|
|
return builder
|
|
|
|
endfunction
|