Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'feature/customizability' into develop

This merge introduces a lot of changes to Powerline. Most importantly,
it's a lot easier to customize it through
Pl#Theme#(Insert|Remove)Segment(), and through upcoming colorscheme
changing functions.

IMPORTANT! DO NOT set g:Powerline_cache_file = '', this will cause an
error on vim startup! If you want to disable the cache, set
g:Powerline_cache_enabled = 0 instead.

This commit includes the following (temporary) regressions:

* Removes Solarized theme
* Removes Control-P theme
* Minor changes to existing buffer themes

Some workarounds have to be found to make the Control-P theme work
again, and the Solarized theme has to be recreated using the new
colorscheme functions. This is on top of my todo list and should be
fixed within a couple of days.

For insertion/removal of segments, check out
autoload/Powerline/Segments* for available segments, and
autoload/Powerline/Themes/distinguished.vim for the current placement of
segments.

To add e.g. the current file size after the file info in the statusline,
add this to your vimrc:

call Pl#Theme#InsertSegment('filesize', 'after', 'fileinfo')

To remove e.g. the file info from the statusline, add this to your
vimrc:

call Pl#Theme#RemoveSegment('fileinfo')

You can also replace segments using
Pl#Theme#ReplaceSegment('old_segment', 'new_segment').

Closes #37, #42, #50.
  • Loading branch information...
commit 404c8b0d400e98e685a2bbc81cdea1169f837071 2 parents 4d8a928 + 168e5a0
@Lokaltog authored
Showing with 1,176 additions and 1,336 deletions.
  1. +1 −1  README.rst
  2. +42 −508 autoload/Pl.vim
  3. +153 −0 autoload/Pl/Colorscheme.vim
  4. +53 −4 autoload/Pl/{Colors.vim → Hi.vim}
  5. +39 −0 autoload/Pl/Match.vim
  6. +35 −0 autoload/Pl/Mod.vim
  7. +329 −0 autoload/Pl/Parser.vim
  8. +178 −0 autoload/Pl/Segment.vim
  9. +86 −0 autoload/Pl/Theme.vim
  10. +35 −0 autoload/Powerline/Colorschemes/distinguished.vim
  11. +41 −0 autoload/Powerline/Functions.vim
  12. +3 −0  autoload/Powerline/Functions/cfi.vim
  13. +12 −0 autoload/Powerline/Functions/ft_man.vim
  14. +7 −0 autoload/Powerline/Functions/fugitive.vim
  15. +16 −0 autoload/Powerline/Functions/syntastic.vim
  16. +11 −0 autoload/Powerline/Matches.vim
  17. +25 −0 autoload/Powerline/Segments.vim
  18. +5 −0 autoload/Powerline/Segments/cfi.vim
  19. +3 −0  autoload/Powerline/Segments/ft_man.vim
  20. +5 −0 autoload/Powerline/Segments/fugitive.vim
  21. +5 −0 autoload/Powerline/Segments/syntastic.vim
  22. +80 −0 autoload/Powerline/Themes/distinguished.vim
  23. +0 −273 doc/Powerline.txt
  24. +12 −12 plugin/Powerline.vim
  25. +0 −97 powerline/distinguished.vim
  26. +0 −93 powerline/distinguished/00-default.vim
  27. +0 −27 powerline/distinguished/50-command-t.vim
  28. +0 −21 powerline/distinguished/50-control-p.vim
  29. +0 −43 powerline/distinguished/50-gundo.vim
  30. +0 −27 powerline/distinguished/50-help.vim
  31. +0 −21 powerline/distinguished/50-lusty.vim
  32. +0 −27 powerline/distinguished/50-manpage.vim
  33. +0 −15 powerline/distinguished/50-minibufexplorer.vim
  34. +0 −21 powerline/distinguished/50-syntastic.vim
  35. +0 −21 powerline/distinguished/50-tagbar.vim
  36. +0 −53 powerline/solarized.vim
  37. +0 −72 powerline/solarized/00-default.vim
View
2  README.rst
@@ -72,7 +72,7 @@ Troubleshooting
---------------
I can't see the fancy symbols, what's wrong?
- Make sure that you have ``let g:Powerline_symbols = 'fancy`` in your
+ Make sure that you have ``let g:Powerline_symbols = 'fancy'`` in your
``vimrc`` file. The settings may be loaded too late if you have this in
``gvimrc``, so always put this in your ``vimrc``.
View
550 autoload/Pl.vim
@@ -3,481 +3,30 @@
" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
" Source repository: https://github.com/Lokaltog/vim-powerline
-" Script resources {{{
- let s:symbols = {
- \ 'compatible': {
- \ 'dividers': [ '', [0x2502], '', [0x2502] ]
- \ , 'symbols' : {
- \ 'branch': 'BR:'
- \ , 'ro' : 'RO'
- \ , 'ft' : 'FT'
- \ , 'line' : 'LN'
- \ }
- \ },
- \ 'unicode': {
- \ 'dividers': [ [0x25b6], [0x276f], [0x25c0], [0x276e] ]
- \ , 'symbols' : {
- \ 'branch' : [0x26a1]
- \ , 'ro' : [0x2613]
- \ , 'ft' : [0x2691]
- \ , 'line' : [0x204b]
- \ },
- \ },
- \ 'fancy': {
- \ 'dividers': [ [0x2b80], [0x2b81], [0x2b82], [0x2b83] ]
- \ , 'symbols' : {
- \ 'branch' : [0x2b60]
- \ , 'ro' : [0x2b64]
- \ , 'ft' : [0x2b62, 0x2b63]
- \ , 'line' : [0x2b61]
- \ }
- \ }
- \ }
-
- let s:EMPTY = ['', 0]
- let s:HI_FALLBACK = { 'cterm': 0, 'gui': 0x000000 }
- let s:MODES = { 'current': '', 'insert': '', 'noncurrent': '' }
-
- let s:LEFT_SIDE = 0
- let s:RIGHT_SIDE = 2
-
- let s:HARD_DIVIDER = 0
- let s:SOFT_DIVIDER = 1
-
- " Cache revision, this must be incremented whenever the cache format is changed
- let s:CACHE_REVISION = 1
-" }}}
" Script variables {{{
- let s:hi_groups = {}
- let s:hi_current_group = {}
- let s:hi_cmds = []
-
- let s:match_statuslines = []
- let s:stored_statuslines = {}
-" }}}
-" Statusline functions {{{
- function! Pl#Statusline(...) " {{{
- let modes = copy(s:MODES)
-
- for mode in keys(modes)
- let matches = []
-
- let [segment, hi_curr, matches] = s:GroupHandler(mode, a:000, s:LEFT_SIDE, [])
-
- let modes[mode] = segment
- endfor
-
- call add(s:match_statuslines, {
- \ 'matches': matches,
- \ 'modes': modes
- \ })
- endfunction " }}}
- function! Pl#StoreStatusline(key, ...) " {{{
- let modes = copy(s:MODES)
-
- for mode in keys(modes)
- let matches = []
-
- let [segment, hi_curr, matches] = s:GroupHandler(mode, a:000, s:LEFT_SIDE, [])
-
- let modes[mode] = segment
- endfor
-
- let s:stored_statuslines[a:key] = modes
- endfunction " }}}
- function! Pl#Match(expr, re) " {{{
- return ['match', a:expr, a:re]
- endfunction " }}}
- function! Pl#Segment(text, ...) " {{{
- let text = a:text
- let hi = {}
-
- " Handle optional arguments (colors and conditions)
- " Arguments can either be a highlighting array or a boolean (0/1)
- for arg in a:000
- if type(arg) == type(0)
- " Boolean argument
- if ! arg
- " The argument is false, return empty segment
- return s:EMPTY
- endif
- elseif type(arg) == type([])
- " Color argument
- let hi[arg[0]] = arg[1]
- else
- " Unknown argument
- return s:EMPTY
- endif
-
- unlet arg
- endfor
-
- " Search/replace symbols
- for [key, symbol] in items(s:symbols[g:Powerline_symbols].symbols)
- let text = substitute(
- \ text,
- \ '\v\$('. key .')',
- \ '\=s:ParseChars(s:symbols[g:Powerline_symbols].symbols[submatch(1)])',
- \ 'g')
- endfor
-
- return ['segment', text, hi]
- endfunction " }}}
- function! Pl#SegmentGroup(...) " {{{
- let segments = []
- let hi = {}
-
- " Handle arguments (colors and segments)
- for arg in a:000
- if arg[0] == 'segment' || arg[0] == 'segment_group'
- " Add segment
- call add(segments, arg)
- elseif arg != s:EMPTY
- " Add highlighting
- let hi[arg[0]] = arg[1]
- endif
- endfor
-
- return ['segment_group', segments, hi]
- endfunction " }}}
- function! Pl#Split(...) " {{{
- let hi = {}
-
- " Handle arguments (colors)
- for arg in a:000
- if arg != s:EMPTY
- " Add highlighting
- let hi[arg[0]] = arg[1]
- endif
- endfor
-
- return ['segment_split', '%=', hi]
- endfunction " }}}
- function! Pl#FG(cterm, ...) " {{{
- if a:0 && a:1
- let gui = a:1
- else
- let gui = Pl#Colors#cterm2gui(a:cterm)
- endif
-
- let color = { 'cterm': toupper(a:cterm), 'gui': toupper(gui) }
-
- return ['fg', color]
- endfunction " }}}
- function! Pl#BG(cterm, ...) " {{{
- if a:0 && a:1
- let gui = a:1
- else
- let gui = Pl#Colors#cterm2gui(a:cterm)
- endif
-
- let color = { 'cterm': toupper(a:cterm), 'gui': toupper(gui) }
-
- return ['bg', color]
- endfunction " }}}
- function! Pl#Attr(...) " {{{
- return ['attr', sort(copy(a:000))]
- endfunction " }}}
- function! Pl#HiCurrent(...) " {{{
- let hi = s:GetHi('hi_current', a:000)
- let s:hi_current_group['hi_current'] = s:hi_groups[hi]
-
- return ['hi_current', hi]
- endfunction " }}}
- function! Pl#HiInsert(...) " {{{
- let hi = s:GetHi('hi_insert', a:000)
- let s:hi_current_group['hi_insert'] = s:hi_groups[hi]
-
- return ['hi_insert', hi]
- endfunction " }}}
- function! Pl#HiNonCurrent(...) " {{{
- let hi = s:GetHi('hi_noncurrent', a:000)
- let s:hi_current_group['hi_noncurrent'] = s:hi_groups[hi]
+ let g:Pl#THEME = []
+ let g:Pl#HL = []
- return ['hi_noncurrent', hi]
- endfunction " }}}
-" }}}
-" Internal functions {{{
- function! s:GroupHandler(type, args, side, matches, ...) " {{{
- " Recursive function for handling segment groups
- let side = a:side
- let ret = ''
- let args = []
- let level = a:0 ? a:1 : 0
- let matches = a:matches
-
- let hi_group = 'hi_'. a:type
- let hi_curr = {}
-
- " Remove empty and invalid segments from argument array
- for i in range(0, len(a:args) - 1)
- let item = a:args[i]
-
- if empty(item[0])
- " If the current segment for some reason is false/empty (e.g. if
- " one of the segment conditions is false), skip the entire segment
- continue
- endif
-
- if item[0] == 'segment' && ! has_key(item[2], hi_group)
- " If this segment is missing highlighting for this type,
- " skip the entire segment (e.g. if HiNonCurrent is missing)
- continue
- endif
-
- call add(args, item)
- endfor
-
- for i in range(0, len(args) - 1)
- unlet! a_prev a_curr a_next
-
- " Prepare some resources (fetch previous, current and next segment)
- let a_prev = (i == 0) ? s:EMPTY : copy(get(args, i - 1))
- let a_curr = copy(get(args, i))
- let a_next = (i == (len(args) - 1)) ? s:EMPTY : copy(get(args, i + 1))
-
- let add_divider = 1
-
- " If we're in a segment group (level > 0), don't add dividers
- if level && a_next[0] != 'segment_group' && a_prev[0] != 'segment_group'
- let add_divider = 0
- endif
-
- " Render segment groups as segments, and handle them as segments in the next if block
- if a_curr[0] == 'segment_group'
- let [segment, hi_curr, matches] = s:GroupHandler(a:type, a_curr[1], side, matches, level + 1)
-
- let a_curr[0] = 'segment'
- let a_curr[1] = segment
- endif
-
- " Handle the different argument types
- if a_curr[0] == 'segment' " {{{
- " Use soft divider w/ current hi group by default
- let divider_color = a_curr[2][hi_group]
- let divider_type = s:SOFT_DIVIDER
-
- " Check if we should use a hard divider {{{
- " Fetch current highlighting colors
- unlet! hi_curr hi_cmp
-
- let hi_curr = s:hi_groups[a_curr[2][hi_group]]
-
- if side == s:LEFT_SIDE
- " Compare curr/next highlighting
- let hi_cmp = exists('a_next[2]') && has_key(a_next[2], hi_group) ? s:hi_groups[a_next[2][hi_group]] : []
- else
- " Compare curr/prev highlighting
- let hi_cmp = exists('a_prev[2]') && has_key(a_prev[2], hi_group) ? s:hi_groups[a_prev[2][hi_group]] : []
- endif
-
- if ! empty(hi_cmp)
- " Compare the highlighting groups
- "
- " If the background color for GUI and term is equal, use soft divider with the current segment's highlighting
- " If not, use hard divider with a new highlighting group
- "
- " Note that if the previous/next segment is the split, a hard divider is always used
- if hi_curr['bg'] != hi_cmp['bg'] || (a_next[0] == 'segment_split' || a_prev[0] == 'segment_split')
- let divider_type = s:HARD_DIVIDER
-
- " Create new highlighting group
- " Use FG = CURRENT BG, BG = CMP BG
- let divider_color = s:GetHi(hi_group, [
- \ Pl#FG(hi_curr['bg']['cterm'], hi_curr['bg']['gui']),
- \ Pl#BG(hi_cmp['bg']['cterm'], hi_cmp['bg']['gui'])
- \ ])
- endif
- endif
- " }}}
-
- " Prepare segment
- let segment = a_curr[1]
-
- " Add highlighting
- let segment = '%#'. a_curr[2][hi_group] .'#'. segment
-
- if add_divider
- let segment = s:AddDivider(segment, side, divider_color, divider_type)
- endif
-
- let segment = '%('. segment .'%)'
- " }}}
- elseif a_curr[0] == 'segment_split' " {{{
- " Change divider side
- let side = s:RIGHT_SIDE
-
- " Add segment text
- let segment = a_curr[1]
- " }}}
- elseif a_curr[0] == 'match' " {{{
- " Handle match parameters
- call add(matches, [a_curr[1], a_curr[2]])
-
- continue
- " }}}
- endif
-
- " Append segment to statusline
- let ret .= segment
- endfor
-
- " Return an empty statusline if we're missing all highlighting for this mode
- if empty(hi_curr)
- let ret = ''
- endif
-
- return [ret, hi_curr, matches]
- endfunction " }}}
- function! s:GetHi(type, args) " {{{
- let hi = { 'fg': [], 'bg': [], 'attr': [] }
-
- " Store our arguments
- for arg in a:args
- if ! has_key(hi, arg[0])
- " Invalid argument
- continue
- endif
-
- let hi[arg[0]] = arg[1]
- endfor
-
- " Make sure that we have both FG and BG colors
- " Falls back to the current active FG/BG color if the color isn't passed to this function
- if ! len(hi['fg'])
- let hi['fg'] = has_key(s:hi_current_group, a:type) ? s:hi_current_group[a:type]['fg'] : s:HI_FALLBACK
- endif
-
- if ! len(hi['bg'])
- let hi['bg'] = has_key(s:hi_current_group, a:type) ? s:hi_current_group[a:type]['bg'] : s:HI_FALLBACK
- endif
-
- " Make sure that we have properly formatted attributes
- if ! len(hi['attr'])
- let hi['attr'] = 'NONE'
- else
- let hi['attr'] = join(hi['attr'], ',')
- endif
-
- " Return the finished highlighting group name
- return s:CreateHiGroup(hi)
- endfunction " }}}
- function! s:CreateHiGroup(hi) " {{{
- let fg = a:hi['fg']
- let bg = a:hi['bg']
- let attr = a:hi['attr']
-
- " Create a short and unique highlighting group name
- " It uses the hex values of all the color properties and an attribute flag at the end
- " NONE colors are translated to NN for cterm and NNNNNN for gui colors
- let hi_group = printf('Pl%s%s%s%s%s'
- \ , (fg['cterm'] == 'NONE' ? 'NN' : printf('%02x', fg['cterm']))
- \ , (fg['gui'] == 'NONE' ? 'NNNNNN' : printf('%06x', fg['gui'] ))
- \ , (bg['cterm'] == 'NONE' ? 'NN' : printf('%02x', bg['cterm']))
- \ , (bg['gui'] == 'NONE' ? 'NNNNNN' : printf('%06x', bg['gui'] ))
- \ , substitute(attr, '\v([a-zA-Z])[a-zA-Z]*,?', '\1', 'g')
- \ )
-
- if ! s:HlExists(hi_group) || ! has_key(s:hi_groups, hi_group)
- " Create the highlighting group
- let hi_cmd = printf('hi %s ctermfg=%s ctermbg=%s cterm=%s guifg=%s guibg=%s gui=%s'
- \ , hi_group
- \ , (fg['cterm'] == 'NONE' ? 'NONE' : printf('%d', fg['cterm']))
- \ , (bg['cterm'] == 'NONE' ? 'NONE' : printf('%d', bg['cterm']))
- \ , attr
- \ , (fg['gui'] == 'NONE' ? 'NONE' : printf('#%06x', fg['gui']))
- \ , (bg['gui'] == 'NONE' ? 'NONE' : printf('#%06x', bg['gui']))
- \ , attr
- \ )
-
- exec hi_cmd
-
- " Add command to hi_cmds array for caching
- call add(s:hi_cmds, hi_cmd)
-
- " Store the raw highlighting information in a global script variable
- " This will be used in s:GetHiCurrent()
- let s:hi_groups[hi_group] = a:hi
- endif
-
- " Return only the highlighting group name
- return hi_group
- endfunction " }}}
- function! s:HlExists(hl) " {{{
- if ! hlexists(a:hl)
- return 0
- endif
-
- redir => hlstatus
- silent exec 'hi' a:hl
- redir END
-
- return (hlstatus !~ 'cleared')
- endfunction " }}}
- function! s:AddDivider(text, side, color, ...) " {{{
- " Adds divider symbol to text
- let divider_type = a:1
-
- " Fetch and parse divider symbol
- let divider_raw = copy(s:symbols[g:Powerline_symbols].dividers[a:side + divider_type])
- let divider = s:ParseChars(divider_raw)
-
- if a:side == s:LEFT_SIDE
- " Left side
- " Divider to the right
- return printf('%s%%#%s#%s', a:text, a:color, divider)
- else
- " Right side
- " Divider to the left
- return printf('%%#%s#%s%s', a:color, divider, a:text)
- endif
- endfunction " }}}
- function! s:ParseChars(arg) " {{{
- " Handles symbol arrays which can be either an array of hex values,
- " or a string. Will convert the hex array to a string, or return the
- " string as-is.
- let arg = copy(a:arg)
-
- if type(arg) == type([])
- " Hex array
- call map(arg, 'nr2char(v:val)')
-
- return join(arg, '')
- endif
-
- " Anything else, just return it as it is
- return arg
- endfunction " }}}
+ " Cache revision, this must be incremented whenever the cache format is changed
+ let s:CACHE_REVISION = 2
" }}}
" Script initialization {{{
function! Pl#LoadCached() " {{{
- if filereadable(g:Powerline_cache_file)
+ if filereadable(g:Powerline_cache_file) && g:Powerline_cache_enabled
exec 'source' escape(g:Powerline_cache_file, ' \')
if ! exists('g:Powerline_cache_revision') || g:Powerline_cache_revision != s:CACHE_REVISION
- " Cache revision differs, force statusline reloading
+ " Cache revision differs, cache is invalid
unlet! g:Powerline_cache_revision
- \ g:Powerline_match_statuslines
- \ g:Powerline_stored_statuslines
- \ g:Powerline_hi_cmds
return 0
endif
" Create highlighting groups
- for hi_cmd in g:Powerline_hi_cmds
+ for hi_cmd in g:Pl#HL
exec hi_cmd
endfor
- " Assign statuslines
- let s:match_statuslines = g:Powerline_match_statuslines
- let s:stored_statuslines = g:Powerline_stored_statuslines
-
- unlet! g:Powerline_cache_revision
- \ g:Powerline_match_statuslines
- \ g:Powerline_stored_statuslines
- \ g:Powerline_hi_cmds
-
return 1
endif
@@ -489,78 +38,63 @@
call delete(g:Powerline_cache_file)
endif
- " Load main statusline file
- " If &rtp contains more than one matching files, take the first one
- let main_path = split(globpath(&rtp, 'powerline/'. g:Powerline_theme .'.vim', 1), '\n')[0]
- if ! empty(main_path) && filereadable(main_path)
- exec 'source' escape(main_path, ' \')
- endif
-
- " Load cached statuslines
- " Reload and cache statuslines if no cached statuslines exist
if ! Pl#LoadCached()
- for path in split(globpath(&rtp, 'powerline/'. g:Powerline_theme .'/*', 1), '\n')
- exec 'source' escape(path, ' \')
+ " Autoload the theme dict first
+ let raw_theme = g:Powerline#Themes#{g:Powerline_theme}#theme
+
+ " Create list with parsed statuslines
+ for buffer_statusline in raw_theme
+ call add(g:Pl#THEME, {
+ \ 'matches': buffer_statusline.matches,
+ \ 'mode_statuslines': Pl#Parser#GetStatusline(buffer_statusline.segments)
+ \ })
endfor
- " Prepare colors and statuslines for caching
+ if ! g:Powerline_cache_enabled
+ " Don't cache anything if caching is disabled or cache file isn't writeable
+ return
+ endif
+
+ " Prepare commands and statuslines for caching
let cache = [
\ 'let g:Powerline_cache_revision = '. string(s:CACHE_REVISION),
- \ 'let g:Powerline_hi_cmds = '. string(s:hi_cmds),
- \ 'let g:Powerline_match_statuslines = '. string(s:match_statuslines),
- \ 'let g:Powerline_stored_statuslines = '. string(s:stored_statuslines)
+ \ 'let g:Pl#HL = '. string(g:Pl#HL),
+ \ 'let g:Pl#THEME = '. string(g:Pl#THEME),
\ ]
- if empty(g:Powerline_cache_file)
- " Don't cache anything if g:Powerline_cache_file is empty
- return
- endif
-
call writefile(cache, g:Powerline_cache_file)
endif
endfunction " }}}
" }}}
" Statusline updater {{{
- function! Pl#GetStatusline(statuslines, current) " {{{
- let current_mode = mode()
- let current_window = a:current
-
- if current_window && current_mode == 'i'
- let statusline_mode = 'insert'
- elseif current_window
- let statusline_mode = 'current'
+ function! Pl#Statusline(statuslines, current) " {{{
+ let mode = mode()
+
+ if ! a:current
+ let mode = 'N' " Normal (non-current)
+ elseif mode =~# '\v(v|V|)'
+ let mode = 'v' " Visual mode
+ elseif mode =~# '\vi'
+ let mode = 'i' " Insert mode
+ elseif mode =~# '\v(R|Rv)'
+ let mode = 'r' " Replace mode
else
- let statusline_mode = 'noncurrent'
+ " Fallback to normal mode
+ let mode = 'n' " Normal (current)
endif
- return a:statuslines[statusline_mode]
- endfunction " }}}
- function! Pl#GetStoredStatusline(key) " {{{
- return s:stored_statuslines[a:key]
+ return a:statuslines[mode]
endfunction " }}}
function! Pl#UpdateStatusline(current) " {{{
- if empty(s:match_statuslines)
+ if empty(g:Pl#THEME)
" Load statuslines if they aren't loaded yet
call Pl#Load()
endif
- for statusline in s:match_statuslines
- let valid = 1
-
- " Validate matches
- if len(statusline['matches'])
- for [eval, re] in statusline['matches']
- if match(eval(eval), '\v'. re) == -1
- let valid = 0
-
- break
- endif
- endfor
- endif
-
- if valid
+ for buffer_statusline in g:Pl#THEME
+ if Pl#Match#Validate(buffer_statusline.matches)
" Update window-local statusline
- let &l:statusline = '%!Pl#GetStatusline('. string(statusline['modes']) .','. a:current .')'
+ let &l:statusline = '%!Pl#Statusline('. string(buffer_statusline.mode_statuslines) .','. a:current .')'
endif
endfor
endfunction " }}}
View
153 autoload/Pl/Colorscheme.vim
@@ -0,0 +1,153 @@
+function! Pl#Colorscheme#Init(hi) " {{{
+ let colorscheme = {}
+
+ for hi in a:hi
+ " Ensure that the segments are a list
+ let segments = type(hi[0]) == type('') ? [ hi[0] ] : hi[0]
+ let mode_hi_dict = hi[1]
+
+ for segment in segments
+ let colorscheme[segment] = mode_hi_dict
+ endfor
+ endfor
+
+ return colorscheme
+endfunction " }}}
+function! Pl#Colorscheme#Apply(colorscheme, buffer_segments) " {{{
+ " TODO This function should be recursive and work on both segments and groups
+ " TODO We could probably handle the NS stuff here...
+
+ " Set color parameters for all segments in a:buffer_segments
+ let colorscheme = g:Powerline#Colorschemes#{a:colorscheme}#colorscheme
+ let buffer_segments = a:buffer_segments
+
+ " This is a bit complex, I'll walk you through exactly what happens here...
+ "
+ " First of all we loop through the buffer_segments, which are the segments that
+ " this specific buffer will have.
+ for buffer_segment in buffer_segments
+ " The buffer_segment consists of a 'matches' list and a 'segments' list.
+ " The 'matches' list has conditions to limit this statusline to specific buffers/windows.
+ " The 'segments' list has each segment and segment group for this buffer
+ for segment in buffer_segment.segments
+ let type = get(segment, 'type', '')
+
+ if type == 'segment_group'
+ " We're going to handle segment groups different from single segments. Segment groups
+ " have child segments which may have their own highlighting (e.g. fileinfo.flags),
+ " and these child segments may be grouped (e.g. fileinfo.flags.ro) to provide very
+ " specific highlighting. So here we'll handle all that:
+
+ " Set the default/fallback colors for this group
+ for i in range(len(segment.variants), 0, -1)
+ " Check for available highlighting for the main group segment
+ "
+ " This works like the segment highlighting below
+ " TODO Create a function for this
+ let seg_variants = join(segment.variants[0:i], '.')
+
+ let seg_name = i > 0 ? segment.name .'.'. seg_variants : segment.name
+ let seg_ns_name = len(segment.ns) > 0 ? segment.ns .':'. seg_name : seg_name
+
+ if has_key(colorscheme, seg_ns_name)
+ " We have a namespaced highlight group
+ let segment.colors = colorscheme[seg_ns_name]
+ break
+ elseif has_key(colorscheme, seg_name)
+ " We have a non-namespaced group
+ let segment.colors = colorscheme[seg_name]
+ break
+ endif
+ endfor
+
+ " The reason why we need to deepcopy the group's segments is that the child segments
+ " all point to the same base segments and that screws up highlighting if we highlight
+ " some child segments with different namespaced colors
+ let segment.segments = deepcopy(segment.segments)
+
+ " Apply colors to each child segment
+ for child_segment in segment.segments
+ " Check if this child segment is grouped (e.g. fileinfo.flags.group.subgroup)
+ " We're going to prioritize the most specific grouping and then work back to the
+ " most common group (e.g. fileinfo.flags)
+
+ " FIXME We don't have the variants from before because group children aren't run through Pl#Segment#Get
+ let child_segment.variants = [seg_name] + split(child_segment.name, '\.')
+
+ " Use the parent group's namespace
+ let child_segment.ns = segment.ns
+
+ for i in range(len(child_segment.variants), 0, -1)
+ " Check for available highlighting for the main group segment
+ let child_seg_name = join(child_segment.variants[0:i], '.')
+
+ let child_seg_ns_name = len(child_segment.ns) > 0 ? child_segment.ns .':'. child_seg_name : child_seg_name
+
+ if has_key(colorscheme, child_seg_ns_name)
+ " We have a namespaced highlight group
+ let child_segment.colors = colorscheme[child_seg_ns_name]
+ break
+ elseif has_key(colorscheme, child_seg_name)
+ " We have a non-namespaced group
+ let child_segment.colors = colorscheme[child_seg_name]
+ break
+ endif
+ endfor
+ endfor
+ elseif type == 'segment'
+ for i in range(len(segment.variants), 0, -1)
+ " Check for available highlighting
+ "
+ " This is done in the following manner, using the segment gundo:static_filename.text.buffer as an example:
+ "
+ " * Look for the hl group: gundo:static_filename.text.buffer
+ " * Look for the hl group: static_filename.text.buffer
+ " * Look for the hl group: gundo:static_filename.text
+ " * Look for the hl group: static_filename.text
+ " * Look for the hl group: gundo:static_filename
+ " * Look for the hl group: static_filename
+ " * Return the segment without highlighting, causing an error in the parser
+ let seg_variants = join(segment.variants[0:i], '.')
+
+ let seg_name = i > 0 ? segment.name .'.'. seg_variants : segment.name
+ let seg_ns_name = len(segment.ns) > 0 ? segment.ns .':'. seg_name : seg_name
+
+ if has_key(colorscheme, seg_ns_name)
+ " We have a namespaced highlight group
+ let segment.colors = colorscheme[seg_ns_name]
+ break
+ elseif has_key(colorscheme, seg_name)
+ " We have a non-namespaced group
+ let segment.colors = colorscheme[seg_name]
+ break
+ endif
+ endfor
+ endif
+
+ unlet! segment
+ endfor
+ endfor
+
+ " Good luck parsing this return value
+ "
+ " It's a huge dict with all segments for all buffers with their respective syntax highlighting.
+ " It will be parsed by the main Powerline code, where all the data will be shortened to a simple
+ " array consiting of a statusline for each mode, with generated highlighting groups and dividers.
+ return buffer_segments
+endfunction " }}}
+function! Pl#Colorscheme#HiSegment(segments, normal, ...) " {{{
+ let mode_hi_dict = {
+ \ 'n': a:normal
+ \ }
+
+ if a:0 && type(a:1) == type({})
+ for [modes, hl] in items(a:1)
+ for mode in split(modes, '\zs')
+ let mode_hi_dict[mode] = hl
+ endfor
+ endfor
+ endif
+
+ " a:segments may be either a string or a list of strings to use this highlighting
+ return [a:segments, mode_hi_dict]
+endfunction " }}}
View
57 autoload/Pl/Colors.vim → autoload/Pl/Hi.vim
@@ -1,5 +1,5 @@
" cterm -> gui color dict {{{
-let s:cterm2gui = {
+let s:cterm2gui_dict = {
\ 16: 0x000000, 17: 0x00005f, 18: 0x000087, 19: 0x0000af, 20: 0x0000d7, 21: 0x0000ff,
\ 22: 0x005f00, 23: 0x005f5f, 24: 0x005f87, 25: 0x005faf, 26: 0x005fd7, 27: 0x005fff,
\ 28: 0x008700, 29: 0x00875f, 30: 0x008787, 31: 0x0087af, 32: 0x0087d7, 33: 0x0087ff,
@@ -42,14 +42,63 @@ let s:cterm2gui = {
\ 250: 0xbcbcbc, 251: 0xc6c6c6, 252: 0xd0d0d0, 253: 0xdadada, 254: 0xe4e4e4, 255: 0xeeeeee
\ }
" }}}
-function! Pl#Colors#cterm2gui(cterm) " {{{
+function! s:Cterm2GUI(cterm) " {{{
if toupper(a:cterm) == 'NONE'
return 'NONE'
endif
- if ! has_key(s:cterm2gui, a:cterm)
+ if ! has_key(s:cterm2gui_dict, a:cterm)
return 0xff0000
endif
- return s:cterm2gui[a:cterm]
+ return s:cterm2gui_dict[a:cterm]
+endfunction " }}}
+function! Pl#Hi#Create(...) " {{{
+ let hi = {
+ \ 'cterm': ['', ''],
+ \ 'gui' : ['', ''],
+ \ 'attr' : []
+ \ }
+
+ " Fetch highlighting details from parameters
+ for param in a:000
+ " String parameters are always attributes
+ if type(param) == type('')
+ if tolower(param) == 'none'
+ let param = 'NONE'
+ endif
+
+ call add(hi['attr'], param)
+
+ continue
+ endif
+
+ " Other parameters are either Pl#Hi#Cterm or Pl#Hi#GUI return values (lists)
+ let hi[param[0]] = [toupper(param[1]), toupper(param[2])]
+
+ unlet! param
+ endfor
+
+ " Fallback to term colors in gvim
+ if empty(hi['gui'][0]) && ! empty(hi['cterm'][0])
+ let hi['gui'][0] = s:Cterm2GUI(hi['cterm'][0])
+ endif
+ if empty(hi['gui'][1]) && ! empty(hi['cterm'][1])
+ let hi['gui'][1] = s:Cterm2GUI(hi['cterm'][1])
+ endif
+
+ " Return dict with properly formatted color values
+ return {
+ \ 'ctermfg': (empty(hi['cterm'][0]) ? '' : (string(hi['cterm'][0]) == 'NONE' ? 'NONE' : hi['cterm'][0])),
+ \ 'ctermbg': (empty(hi['cterm'][1]) ? '' : (string(hi['cterm'][1]) == 'NONE' ? 'NONE' : hi['cterm'][1])),
+ \ 'guifg': (empty(hi['gui'][0]) ? '' : (string(hi['gui'][0]) == 'NONE' ? 'NONE' : hi['gui'][0])),
+ \ 'guibg': (empty(hi['gui'][1]) ? '' : (string(hi['gui'][1]) == 'NONE' ? 'NONE' : hi['gui'][1])),
+ \ 'attr': (! len(hi['attr']) ? 'NONE' : join(hi['attr'], ','))
+ \ }
+endfunction " }}}
+function! Pl#Hi#Cterm(fg, ...) " {{{
+ return ['cterm', a:fg, (a:0 ? a:1 : '')]
+endfunction " }}}
+function! Pl#Hi#GUI(fg, ...) " {{{
+ return ['gui', a:fg, (a:0 ? a:1 : '')]
endfunction " }}}
View
39 autoload/Pl/Match.vim
@@ -0,0 +1,39 @@
+function! Pl#Match#Add(pat, expr) " {{{
+ return [a:pat, a:expr]
+endfunction " }}}
+function! Pl#Match#Any(...) " {{{
+ let matches = []
+
+ for match_name in a:000
+ if empty(match_name)
+ " Skip empty match parameters
+ continue
+ endif
+
+ if has_key(g:Powerline#Matches#matches, match_name)
+ call add(matches, g:Powerline#Matches#matches[match_name])
+ endif
+
+ unlet! match_name
+ endfor
+
+ return ['match', 'any', matches]
+endfunction " }}}
+function! Pl#Match#Validate(match) " {{{
+ let [m, match, matches] = a:match
+
+ if ! len(matches)
+ " Empty match array matches everything
+ return 1
+ endif
+
+ if match == 'any'
+ for [eval, re] in matches
+ if match(eval(eval), '\v'. re) != -1
+ return 1
+ endif
+ endfor
+
+ return 0
+ endif
+endfunction " }}}
View
35 autoload/Pl/Mod.vim
@@ -0,0 +1,35 @@
+let g:Pl#Mod#theme = []
+
+function! Pl#Mod#UpdateTheme(theme) " {{{
+ let theme = deepcopy(a:theme)
+
+ for mod in g:Pl#Mod#theme
+ " We have to loop through instead of using index() because some
+ " segments are lists!
+ let target_seg_idx = -1
+
+ for i in range(0, len(theme) - 1)
+ unlet! segment
+ let segment = theme[i]
+
+ if type(segment) == type(mod.target_segment) && segment == mod.target_segment
+ let target_seg_idx = i
+ break
+ endif
+ endfor
+
+ if mod.action == 'insert'
+ " Insert segment
+ if target_seg_idx != -1
+ call insert(theme, mod.new_segment, (mod.where == 'before' ? target_seg_idx : target_seg_idx + 1))
+ endif
+ elseif mod.action == 'remove'
+ " Remove segment
+ if target_seg_idx != -1
+ call remove(theme, target_seg_idx)
+ endif
+ endif
+ endfor
+
+ return theme
+endfunction " }}}
View
329 autoload/Pl/Parser.vim
@@ -0,0 +1,329 @@
+let g:Pl#Parser#Symbols = {
+ \ 'compatible': {
+ \ 'dividers': [ '', [0x2502], '', [0x2502] ]
+ \ , 'symbols' : {
+ \ 'BRANCH': 'BR:'
+ \ , 'RO' : 'RO'
+ \ , 'FT' : 'FT'
+ \ , 'LINE' : 'LN'
+ \ , 'COL' : 'C'
+ \ }
+ \ },
+ \ 'unicode': {
+ \ 'dividers': [ [0x25b6], [0x276f], [0x25c0], [0x276e] ]
+ \ , 'symbols' : {
+ \ 'BRANCH': [0x26a1]
+ \ , 'RO' : [0x2613]
+ \ , 'FT' : [0x2691]
+ \ , 'LINE' : [0x204b]
+ \ , 'COL' : [0x2551]
+ \ },
+ \ },
+ \ 'fancy': {
+ \ 'dividers': [ [0x2b80], [0x2b81], [0x2b82], [0x2b83] ]
+ \ , 'symbols' : {
+ \ 'BRANCH': [0x2b60]
+ \ , 'RO' : [0x2b64]
+ \ , 'FT' : [0x2b62, 0x2b63]
+ \ , 'LINE' : [0x2b61]
+ \ , 'COL' : [0x2551]
+ \ }
+ \ }
+\ }
+
+let s:LEFT_SIDE = 0
+let s:RIGHT_SIDE = 2
+
+let s:PADDING = 1
+
+let s:EMPTY_SEGMENT = { 'type': 'empty' }
+
+let s:HARD_DIVIDER = 0
+let s:SOFT_DIVIDER = 1
+
+function! Pl#Parser#GetStatusline(segments) " {{{
+ let statusline = {
+ \ 'n': '',
+ \ 'N': '',
+ \ 'v': '',
+ \ 'i': '',
+ \ 'r': ''
+ \ }
+
+ " Run through the different modes and create the statuslines
+ for mode in keys(statusline)
+ " Create an empty statusline list
+ let stl = []
+
+ call extend(stl, s:ParseSegments(mode, s:LEFT_SIDE, a:segments))
+
+ let statusline[mode] .= join(stl, '')
+ endfor
+
+ return statusline
+endfunction " }}}
+function! Pl#Parser#ParseChars(arg) " {{{
+ " Handles symbol arrays which can be either an array of hex values,
+ " or a string. Will convert the hex array to a string, or return the
+ " string as-is.
+ let arg = a:arg
+
+ if type(arg) == type([])
+ " Hex array
+ call map(arg, 'nr2char(v:val)')
+
+ return join(arg, '')
+ endif
+
+ " Anything else, just return it as it is
+ return arg
+endfunction " }}}
+function! s:ParseSegments(mode, side, segments, ...) " {{{
+ let mode = a:mode
+ let side = a:side
+ let segments = a:segments
+
+ let level = exists('a:1') ? a:1 : 0
+ let base_color = exists('a:2') ? a:2 : {}
+
+ let ret = []
+
+ for i in range(0, len(segments) - 1)
+ unlet! seg_prev seg_curr seg_next
+
+ " Prepare some resources (fetch previous, current and next segment)
+ let seg_curr = deepcopy(get(segments, i))
+
+ " Find previous segment
+ let seg_prev = s:EMPTY_SEGMENT
+
+ for j in range(i - 1, 0, -1)
+ let seg = deepcopy(get(segments, j))
+ if get(seg, 'name') ==# 'TRUNCATE'
+ " Skip truncate segments
+ continue
+ endif
+
+ " Look ahead for another segment that's visible in this mode
+ if index(get(seg, 'modes'), mode) != -1
+ " Use this segment
+ let seg_prev = seg
+
+ break
+ endif
+ endfor
+
+ "" Find next segment
+ let seg_next = s:EMPTY_SEGMENT
+
+ for j in range(i + 1, len(segments) - 1, 1)
+ let seg = deepcopy(get(segments, j))
+ if get(seg, 'name') ==# 'TRUNCATE'
+ " Skip truncate segments
+ continue
+ endif
+
+ " Look ahead for another segment that's visible in this mode
+ if index(get(seg, 'modes'), mode) != -1
+ " Use this segment
+ let seg_next = seg
+
+ break
+ endif
+ endfor
+
+ if index(get(seg_curr, 'modes', []), mode) == -1
+ " The segment is invisible in this mode, skip it
+ " FIXME When two segments after each other are hidden, a gap appears where the segments would be, this is probably due to segment padding
+ continue
+ endif
+
+ " Handle the different segment types
+ if seg_curr.type == 'segment'
+ if seg_curr.name ==# 'TRUNCATE'
+ " Truncate statusline
+ call add(ret, '%<')
+ elseif seg_curr.name ==# 'SPLIT'
+ " Split statusline
+
+ " Switch sides
+ let side = s:RIGHT_SIDE
+
+ " Handle highlighting
+ let mode_colors = get(seg_curr.colors, mode, seg_curr.colors['n'])
+ let hl_group = s:HlCreate(mode_colors)
+
+ " Add segment text
+ call add(ret, '%#'. hl_group .'#%=')
+ else
+ " Add segment text
+ let text = seg_curr.text
+
+ " Decide on whether to use the group's colors or the segment's colors
+ let colors = get(seg_curr, 'colors', base_color)
+
+ " Fallback to normal (current) highlighting if we don't have mode-specific highlighting
+ let mode_colors = get(colors, mode, get(colors, 'n', {}))
+
+ if empty(mode_colors)
+ echoe 'Segment doesn''t have any colors! NS: "'. seg_curr.ns .'" SEG: "'. seg_curr.name .'"'
+
+ continue
+ endif
+
+ " Check if we're in a group (level > 0)
+ if level > 0
+ " If we're in a group we don't have dividers between segments, so we should only pad one side
+ let padding_right = (side == s:LEFT_SIDE ? repeat(' ', s:PADDING) : '')
+ let padding_left = (side == s:RIGHT_SIDE ? repeat(' ', s:PADDING) : '')
+
+ " Check if we lack a bg/fg color for this segment
+ " If we do, use the bg/fg color from base_color
+ let base_color_mode = ! has_key(base_color, mode) ? base_color['n'] : base_color[mode]
+
+ for col in ['ctermbg', 'ctermfg', 'guibg', 'guifg']
+ if empty(mode_colors[col])
+ let mode_colors[col] = base_color_mode[col]
+ endif
+ endfor
+ else
+ "" If we're outside a group we have dividers and must pad both sides
+ let padding_left = repeat(' ', s:PADDING)
+ let padding_right = repeat(' ', s:PADDING)
+ endif
+
+ " Get main hl group for segment
+ let hl_group = s:HlCreate(mode_colors)
+
+ " Prepare segment text
+ let text = '%(%#'. hl_group .'#'. padding_left . text . padding_right . '%)'
+
+ if level == 0
+ " Add divider to single segments
+ let text = s:AddDivider(text, side, mode, colors, seg_prev, seg_curr, seg_next)
+ endif
+
+ call add(ret, text)
+ endif
+ elseif seg_curr.type == 'segment_group'
+ " Recursively parse segment group
+ let func_params = [mode, side, seg_curr.segments, level + 1]
+
+ if has_key(seg_curr, 'colors')
+ " Pass the base colors on to the child segments
+ call add(func_params, seg_curr.colors)
+ endif
+
+ " Get segment group string
+ let text = join(call('s:ParseSegments', func_params), '')
+
+ " Pad on the opposite side of the divider
+ let padding_right = (side == s:RIGHT_SIDE ? repeat(' ', s:PADDING) : '')
+ let padding_left = (side == s:LEFT_SIDE ? repeat(' ', s:PADDING) : '')
+
+ let text = s:AddDivider(padding_left . text . padding_right, side, mode, seg_curr.colors, seg_prev, seg_curr, seg_next)
+
+ call add(ret, text)
+ endif
+ endfor
+
+ return ret
+endfunction " }}}
+function! s:HlCreate(hl) " {{{
+ " Create a short and unique highlighting group name
+ " It uses the hex values of all the color properties and an attribute flag at the end
+ " NONE colors are translated to NN for cterm and NNNNNN for gui colors
+ let hi_group = printf('Pl%s%s%s%s%s'
+ \ , (a:hl['ctermfg'] == 'NONE' ? 'NN' : printf('%02x', a:hl['ctermfg']))
+ \ , (a:hl['guifg'] == 'NONE' ? 'NNNNNN' : printf('%06x', a:hl['guifg'] ))
+ \ , (a:hl['ctermbg'] == 'NONE' ? 'NN' : printf('%02x', a:hl['ctermbg']))
+ \ , (a:hl['guibg'] == 'NONE' ? 'NNNNNN' : printf('%06x', a:hl['guibg'] ))
+ \ , substitute(a:hl['attr'], '\v([a-zA-Z])[a-zA-Z]*,?', '\1', 'g')
+ \ )
+
+ if ! s:HlExists(hi_group)
+ " Create the highlighting group
+ let hi_cmd = printf('hi %s ctermfg=%s ctermbg=%s cterm=%s guifg=%s guibg=%s gui=%s'
+ \ , hi_group
+ \ , (a:hl['ctermfg'] == 'NONE' ? 'NONE' : printf('%d', a:hl['ctermfg']))
+ \ , (a:hl['ctermbg'] == 'NONE' ? 'NONE' : printf('%d', a:hl['ctermbg']))
+ \ , a:hl['attr']
+ \ , (a:hl['guifg'] == 'NONE' ? 'NONE' : printf('#%06x', a:hl['guifg']))
+ \ , (a:hl['guibg'] == 'NONE' ? 'NONE' : printf('#%06x', a:hl['guibg']))
+ \ , a:hl['attr']
+ \ )
+
+ exec hi_cmd
+
+ " Add command to Pl#HL list for caching
+ call add(g:Pl#HL, hi_cmd)
+ endif
+
+ " Return only the highlighting group name
+ return hi_group
+endfunction " }}}
+function! s:HlExists(hl) " {{{
+ if ! hlexists(a:hl)
+ return 0
+ endif
+
+ redir => hlstatus
+ silent exec 'hi' a:hl
+ redir END
+
+ return (hlstatus !~ 'cleared')
+endfunction " }}}
+function! s:AddDivider(text, side, mode, colors, prev, curr, next) " {{{
+ let seg_prev = a:prev
+ let seg_curr = a:curr
+ let seg_next = a:next
+
+ " Set default color/type for the divider
+ let div_colors = get(a:colors, a:mode, a:colors['n'])
+ let div_type = s:SOFT_DIVIDER
+
+ " Define segment to compare
+ let cmp_seg = a:side == s:LEFT_SIDE ? seg_next : seg_prev
+
+ let cmp_all_colors = get(cmp_seg, 'colors', {})
+ let cmp_colors = get(cmp_all_colors, a:mode, get(cmp_all_colors, 'n', {}))
+
+ if ! empty(cmp_colors)
+ " Compare the highlighting groups
+ "
+ " If the background color for cterm is equal, use soft divider with the current segment's highlighting
+ " If not, use hard divider with a new highlighting group
+ "
+ " Note that if the previous/next segment is the split, a hard divider is always used
+ if get(div_colors, 'ctermbg') != get(cmp_colors, 'ctermbg') || get(seg_next, 'name') ==# 'SPLIT' || get(seg_prev, 'name') ==# 'SPLIT'
+ let div_type = s:HARD_DIVIDER
+
+ " Create new highlighting group
+ " Use FG = CURRENT BG, BG = CMP BG
+ let div_colors['ctermfg'] = get(div_colors, 'ctermbg')
+ let div_colors['guifg'] = get(div_colors, 'guibg')
+
+ let div_colors['ctermbg'] = get(cmp_colors, 'ctermbg')
+ let div_colors['guibg'] = get(cmp_colors, 'guibg')
+ endif
+ endif
+
+ " Prepare divider
+ let divider_raw = deepcopy(g:Pl#Parser#Symbols[g:Powerline_symbols].dividers[a:side + div_type])
+ let divider = Pl#Parser#ParseChars(divider_raw)
+
+ " Don't add dividers for segments adjacent to split (unless it's a hard divider)
+ if ((get(seg_next, 'name') ==# 'SPLIT' || get(seg_prev, 'name') ==# 'SPLIT') && div_type != s:HARD_DIVIDER)
+ return ''
+ endif
+
+ if a:side == s:LEFT_SIDE
+ " Left side
+ " Divider to the right
+ return printf('%%(%s%%#%s#%s%%)', a:text, s:HlCreate(div_colors), divider)
+ else
+ " Right side
+ " Divider to the left
+ return printf('%%(%%#%s#%s%s%%)', s:HlCreate(div_colors), divider, a:text)
+ endif
+endfunction " }}}
View
178 autoload/Pl/Segment.vim
@@ -0,0 +1,178 @@
+let s:default_modes = ['n', 'N', 'v', 'i', 'r']
+
+function! s:CheckConditions(params) " {{{
+ " Check conditions for a segment/group
+ " Integer parameters are always conditions
+ for param in a:params
+ if type(param) == type(0) && param == 0
+ " Break here if it's an integer parameter and it's false (0)
+ return 0
+ endif
+ unlet! param
+ endfor
+
+ return 1
+endfunction " }}}
+function! Pl#Segment#Create(name, ...) " {{{
+ " Check condition parameters
+ if ! s:CheckConditions(a:000)
+ return {}
+ endif
+
+ let name = a:name
+ let modes = s:default_modes
+ let segments = []
+
+ for param in a:000
+ " Lookup modes for this segment/group
+ if type(param) == type([]) && param[0] == 'modes'
+ let modes = param[1]
+ elseif type(a:1) == type([]) && a:1[0] == 'segment'
+ call add(segments, param[1])
+ endif
+
+ unlet! param
+ endfor
+
+ if type(a:1) == type([]) && a:1[0] == 'segment'
+ " This is a segment group
+ return ['segment_group', {
+ \ 'type': 'segment_group'
+ \ , 'name': name
+ \ , 'segments': segments
+ \ , 'modes': modes
+ \ }]
+ else
+ " This is a single segment
+ let text = a:1
+
+ " Search/replace symbols
+ for [key, symbol] in items(g:Pl#Parser#Symbols[g:Powerline_symbols].symbols)
+ let text = substitute(
+ \ text,
+ \ '\v\$('. key .')',
+ \ '\=Pl#Parser#ParseChars(g:Pl#Parser#Symbols[g:Powerline_symbols].symbols[submatch(1)])',
+ \ 'g')
+ endfor
+
+ return ['segment', {
+ \ 'type': 'segment'
+ \ , 'name': name
+ \ , 'text': text
+ \ , 'modes': modes
+ \ }]
+ endif
+
+endfunction " }}}
+function! Pl#Segment#Init(...) " {{{
+ " Check condition parameters
+ if ! s:CheckConditions(a:000)
+ return {}
+ endif
+
+ let segments = {}
+ let ns = ''
+
+ for param in a:000
+ if type(param) == type('')
+ " String parameters is the namespace
+ let ns = param
+ elseif type(param) == type([])
+ " The data dict is in param[1]
+ " By default we don't have a namespace for the segment
+ let segment = param[1]
+
+ if ! empty(ns)
+ " Update segment so that it includes the namespace
+ " Add the namespace to the segment dict key
+ let segment.ns = ns
+ let segment.name = join([segment.ns, segment.name], ':')
+ endif
+
+ let key = segment.name
+
+ let segments[key] = segment
+ endif
+
+ unlet! param
+ endfor
+
+ return segments
+endfunction " }}}
+function! Pl#Segment#Modes(modes) " {{{
+ " Handle modes for both segments and groups
+ let modes = split(a:modes, '\zs')
+
+ if modes[0] == '!'
+ " Filter modes (e.g. "!nr" will ignore the segment in normal and replace modes)
+ let modes = filter(deepcopy(s:default_modes), 'v:val !~# "['. join(modes[1:]) .']"')
+ endif
+
+ return ['modes', modes]
+endfunction " }}}
+function! Pl#Segment#Split(...) " {{{
+ return a:0 ? a:1 .':SPLIT' : 'SPLIT'
+endfunction " }}}
+function! Pl#Segment#Truncate() " {{{
+ return 'TRUNCATE'
+endfunction " }}}
+function! Pl#Segment#Get(name) " {{{
+ " Return a segment data dict
+ let args = []
+
+ " Check for printf segments (lists)
+ if type(a:name) == type([])
+ " We're dealing with a segment with printf arguments
+ let seg_orig_name = a:name[0]
+ let args = a:name[1:]
+ else
+ let seg_orig_name = a:name
+ endif
+
+ " Fetch namespace and variants for storing in the segment dict
+ let seg_ns = ''
+ let seg_variants = []
+
+ " Retrieve color scheme variants
+ let seg_name_split = split(seg_orig_name, '\v\.')
+ if len(seg_name_split) > 1
+ let seg_variants = seg_name_split[1:]
+ endif
+
+ " Retrieve segment name and namespace
+ " Use the first piece of the split string, we can't have variants in the final segment name
+ let seg_name_split = split(seg_name_split[0], '\v:')
+ let seg_name = seg_name_split[0]
+
+ if len(seg_name_split) > 1
+ let seg_ns = seg_name_split[0]
+ let seg_name = seg_name_split[-1]
+ endif
+
+ try
+ " If we have a namespace, try to use the namespaced segment first (i.e. search for the segment in the namespaced file first)
+ let return_segment = deepcopy(g:Powerline#Segments#{seg_ns}#segments[seg_ns .':'. seg_name])
+ catch
+ try
+ " We didn't find a namespaced segment, fall back to common segments
+ let return_segment = deepcopy(g:Powerline#Segments#segments[seg_name])
+ catch
+ " Didn't find the segment among the common segments either, just skip it
+ let return_segment = {}
+ endtry
+ endtry
+
+ if len(args) && has_key(return_segment, 'text')
+ " Handle segment printf arguments
+ " printf doesn't accept lists as its second argument, so we have to work around that
+ let return_segment.text = call('printf', [ return_segment.text ] + args)
+ endif
+
+ " Assign namespace, name and variants
+ let return_segment.ns = seg_ns
+ let return_segment.name = seg_name
+ let return_segment.orig_name = seg_orig_name
+ let return_segment.variants = seg_variants
+
+ return return_segment
+endfunction " }}}
View
86 autoload/Pl/Theme.vim
@@ -0,0 +1,86 @@
+function! Pl#Theme#Create(colorscheme, ...) " {{{
+ let buffer_segments = []
+
+ for buffer_segment in a:000
+ " Remove empty segments (e.g. 'Pl#Theme#Function's)
+ if empty(buffer_segment)
+ continue
+ endif
+
+ call add(buffer_segments, buffer_segment)
+ endfor
+
+ let buffer_segments = Pl#Colorscheme#Apply(a:colorscheme, buffer_segments)
+
+ return buffer_segments
+endfunction " }}}
+function! Pl#Theme#Buffer(ns, ...) " {{{
+ let segments = []
+ let ns = ! empty(a:ns) ? a:ns .':' : ''
+
+ " Match namespace parameter by default
+ let matches = Pl#Match#Any(a:ns)
+
+ let theme = a:000
+ let theme = Pl#Mod#UpdateTheme(theme) " Do all actions in Pl#Mod#theme
+
+ " Fetch segment data dicts
+ for item in theme
+ if type(item) == type([])
+ if item[0] == 'match'
+ " Match item, overrides default namespace match
+ let matches = item
+
+ continue
+ endif
+
+ " printf segment, append ns to first item in list
+ let item[0] = ns . item[0]
+ else
+ let item = ns . item
+ endif
+
+ let segment = Pl#Segment#Get(item)
+
+ call add(segments, segment)
+
+ unlet! item
+ endfor
+
+ return {
+ \ 'matches': matches,
+ \ 'segments': segments
+ \ }
+endfunction " }}}
+function! Pl#Theme#InsertSegment(new_segment, where, target_segment) " {{{
+ " It's very important to NOT refer to the theme dict until everything's loaded!
+ "
+ " Because these functions are called from the vimrc, we need to put the
+ " actions in a list which will be parsed later.
+ "
+ " These functions don't accept a name parameter, because they work on the
+ " currently selected theme (will change any selected theme)
+ call add(g:Pl#Mod#theme, {
+ \ 'action': 'insert',
+ \ 'new_segment': a:new_segment,
+ \ 'where': a:where,
+ \ 'target_segment': a:target_segment
+ \ })
+endfunction " }}}
+function! Pl#Theme#RemoveSegment(target_segment) " {{{
+ " It's very important to NOT refer to the theme dict until everything's loaded!
+ "
+ " Because these functions are called from the vimrc, we need to put the
+ " actions in a list which will be parsed later.
+ "
+ " These functions don't accept a name parameter, because they work on the
+ " currently selected theme (will change any selected theme)
+ call add(g:Pl#Mod#theme, {
+ \ 'action': 'remove',
+ \ 'target_segment': a:target_segment
+ \ })
+endfunction " }}}
+function! Pl#Theme#ReplaceSegment(old_segment, new_segment) " {{{
+ call Pl#Theme#InsertSegment(a:new_segment, 'after', a:old_segment)
+ call Pl#Theme#RemoveSegment(a:old_segment)
+endfunction " }}}
View
35 autoload/Powerline/Colorschemes/distinguished.vim
@@ -0,0 +1,35 @@
+let g:Powerline#Colorschemes#distinguished#colorscheme = Pl#Colorscheme#Init([
+ \ Pl#Colorscheme#HiSegment(['SPLIT'], Pl#Hi#Create(Pl#Hi#Cterm( 0, 236) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm( 0, 233) ), 'i': Pl#Hi#Create(Pl#Hi#Cterm( 0, 24) ), } ),
+ \ Pl#Colorscheme#HiSegment(['mode_indicator'], Pl#Hi#Create(Pl#Hi#Cterm( 22, 148), 'bold'), { 'i': Pl#Hi#Create(Pl#Hi#Cterm( 23, 231), 'bold'), 'v': Pl#Hi#Create(Pl#Hi#Cterm( 88, 208), 'bold'), 'r': Pl#Hi#Create(Pl#Hi#Cterm(231, 160), 'bold') } ),
+ \ Pl#Colorscheme#HiSegment(['branch',
+ \ 'scrollpercent',
+ \ 'raw',
+ \ 'filesize'] , Pl#Hi#Create(Pl#Hi#Cterm(250, 240) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(239, 235) ), 'i': Pl#Hi#Create(Pl#Hi#Cterm(117, 31) ), } ),
+ \ Pl#Colorscheme#HiSegment(['fileinfo',
+ \ 'filename'], Pl#Hi#Create(Pl#Hi#Cterm(231, 240), 'bold'), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(245, 235), 'bold'), 'i': Pl#Hi#Create(Pl#Hi#Cterm(231, 31), 'bold'), } ),
+ \ Pl#Colorscheme#HiSegment(['static_str'], Pl#Hi#Create(Pl#Hi#Cterm(231, 240) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(245, 235) ), 'i': Pl#Hi#Create(Pl#Hi#Cterm(231, 31) ), } ),
+ \ Pl#Colorscheme#HiSegment(['fileinfo.flags'], Pl#Hi#Create(Pl#Hi#Cterm(196 ), 'bold'), { 'N': Pl#Hi#Create(Pl#Hi#Cterm( 88 ) ), 'i': Pl#Hi#Create(Pl#Hi#Cterm(196 ), 'bold'), } ),
+ \ Pl#Colorscheme#HiSegment(['current_function',
+ \ 'fileformat',
+ \ 'fileencoding',
+ \ 'pwd'], Pl#Hi#Create(Pl#Hi#Cterm(247, 236) ), { 'i': Pl#Hi#Create(Pl#Hi#Cterm(117, 24) ), } ),
+ \ Pl#Colorscheme#HiSegment(['filetype'], Pl#Hi#Create(Pl#Hi#Cterm(246, 236) ), { 'i': Pl#Hi#Create(Pl#Hi#Cterm( 75, 24) ), } ),
+ \ Pl#Colorscheme#HiSegment(['lineinfo'], Pl#Hi#Create(Pl#Hi#Cterm(236, 252), 'bold'), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(245, 235), 'bold'), 'i': Pl#Hi#Create(Pl#Hi#Cterm( 23, 117), 'bold'), } ),
+ \ Pl#Colorscheme#HiSegment(['lineinfo.line.tot'], Pl#Hi#Create(Pl#Hi#Cterm(244 ) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(241 ) ), 'i': Pl#Hi#Create(Pl#Hi#Cterm( 23 ) ), } ),
+ \
+ \ Pl#Colorscheme#HiSegment(['gundo:static_str.name',
+ \ 'command_t:static_str.name',
+ \ 'lustyexplorer:static_str.name',
+ \ 'minibufexplorer.static_str.name'], Pl#Hi#Create(Pl#Hi#Cterm(231, 124), 'bold'), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(160, 52), 'bold'), } ),
+ \ Pl#Colorscheme#HiSegment(['gundo:static_str.buffer',
+ \ 'command_t:raw.line',
+ \ 'lustyexplorer:static_str.buffer'], Pl#Hi#Create(Pl#Hi#Cterm(231, 88) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm(160, 52) ), } ),
+ \ Pl#Colorscheme#HiSegment(['gundo:SPLIT',
+ \ 'command_t:SPLIT',
+ \ 'lustyexplorer:SPLIT',
+ \ 'minibufexplorer:SPLIT'], Pl#Hi#Create(Pl#Hi#Cterm( 0, 88) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm( 0, 52) ), } ),
+ \
+ \ Pl#Colorscheme#HiSegment(['tagbar:static_str.name'], Pl#Hi#Create(Pl#Hi#Cterm(231, 70), 'bold'), { 'N': Pl#Hi#Create(Pl#Hi#Cterm( 70, 22), 'bold'), } ),
+ \ Pl#Colorscheme#HiSegment(['tagbar:static_str.buffer'], Pl#Hi#Create(Pl#Hi#Cterm(148, 28) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm( 70, 22) ), } ),
+ \ Pl#Colorscheme#HiSegment(['tagbar:SPLIT'], Pl#Hi#Create(Pl#Hi#Cterm( 0, 28) ), { 'N': Pl#Hi#Create(Pl#Hi#Cterm( 0, 22) ), } ),
+\ ])
View
41 autoload/Powerline/Functions.vim
@@ -0,0 +1,41 @@
+function! Powerline#Functions#GetMode() " {{{
+ let mode = mode()
+
+ if mode =~# '\v(v|V|)'
+ " Visual mode
+ if mode ==# 'v'
+ let mode = 'VISUAL'
+ elseif mode ==# 'V'
+ let mode = 'V·LINE'
+ elseif mode ==# ''
+ let mode = 'V·BLOCK'
+ endif
+ elseif mode =~# '\vi'
+ let mode = 'INSERT' " Insert mode
+ elseif mode =~# '\v(R|Rv)'
+ let mode = 'REPLACE' " Replace mode
+ else
+ " Fallback to normal mode
+ let mode = ' N ' " Normal (current)
+ endif
+
+ return mode
+endfunction " }}}
+function! Powerline#Functions#GetFilesize() " {{{
+ let bytes = getfsize(expand("%:p"))
+
+ if bytes <= 0
+ return ''
+ endif
+
+ if bytes < 1024
+ return bytes . 'B'
+ else
+ return (bytes / 1024) . 'kB'
+ endif
+endfunction "}}}
+function! Powerline#Functions#GetPwd() "{{{
+ let pwd = substitute(getcwd(), expand("$HOME"), "~", "g")
+
+ return pwd
+endfunction " }}}
View
3  autoload/Powerline/Functions/cfi.vim
@@ -0,0 +1,3 @@
+function! Powerline#Functions#cfi#GetCurrentFunction() " {{{
+ return cfi#format('%s', '')
+endfunction " }}}
View
12 autoload/Powerline/Functions/ft_man.vim
@@ -0,0 +1,12 @@
+function! Powerline#Functions#ft_man#GetName() " {{{
+ let matches = matchlist(getline(1), '\v^([a-zA-Z_\.\-]+)\((\d+)\)')
+
+ if ! len(matches)
+ return 'n/a'
+ endif
+
+ let file = tolower(matches[1])
+ let num = matches[2]
+
+ return file
+endfunction " }}}
View
7 autoload/Powerline/Functions/fugitive.vim
@@ -0,0 +1,7 @@
+function! Powerline#Functions#fugitive#GetBranch(symbol) " {{{
+ let ret = fugitive#statusline()
+
+ let ret = substitute(ret, 'GIT(\([a-z0-9\-_\./:]\+\))', a:symbol .' \1', 'gi')
+
+ return ret
+endfunction " }}}
View
16 autoload/Powerline/Functions/syntastic.vim
@@ -0,0 +1,16 @@
+function! Powerline#Functions#syntastic#GetErrors(line_symbol) " {{{
+ if ! exists('g:syntastic_stl_format')
+ " Syntastic hasn't been loaded yet
+ return ''
+ endif
+
+ " Temporarily change syntastic output format
+ let old_stl_format = g:syntastic_stl_format
+ let g:syntastic_stl_format = '╱╱╱%E{ ERRORS (%e) '. a:line_symbol .' %fe }%W{ WARNINGS (%w) '. a:line_symbol .' %fw }╱╱╱'
+
+ let ret = SyntasticStatuslineFlag()
+
+ let g:syntastic_stl_format = old_stl_format
+
+ return ret
+endfunction " }}}
View
11 autoload/Powerline/Matches.vim
@@ -0,0 +1,11 @@
+let g:Powerline#Matches#matches = {
+ \ 'command_t' : Pl#Match#Add('bufname("%")', 'GoToFile'),
+ \ 'ft_help' : Pl#Match#Add('&ft' , 'help'),
+ \ 'ft_man' : Pl#Match#Add('&ft' , 'man'),
+ \ 'ft_qf' : Pl#Match#Add('&ft' , 'qf'),
+ \ 'gundo_preview' : Pl#Match#Add('bufname("%")', '__Gundo_Preview__'),
+ \ 'gundo_tree' : Pl#Match#Add('bufname("%")', '__Gundo__'),
+ \ 'lustyexplorer' : Pl#Match#Add('bufname("%")', '\[LustyExplorer-Buffers\]'),
+ \ 'minibufexplorer' : Pl#Match#Add('bufname("%")', '\-MiniBufExplorer\-'),
+ \ 'tagbar' : Pl#Match#Add('bufname("%")', '__Tagbar__')
+\ }
View
25 autoload/Powerline/Segments.vim
@@ -0,0 +1,25 @@
+let g:Powerline#Segments#segments = Pl#Segment#Init(
+ \ Pl#Segment#Create('SPLIT' , '__split__'),
+ \ Pl#Segment#Create('TRUNCATE', '__truncate__'),
+ \
+ \ Pl#Segment#Create('mode_indicator' , '%{Powerline#Functions#GetMode()}', Pl#Segment#Modes('!N')),
+ \ Pl#Segment#Create('fileinfo',
+ \ Pl#Segment#Create('flags.ro' , '%{&readonly ? "$RO" : ""}'),
+ \ Pl#Segment#Create('name' , '%t'),
+ \ Pl#Segment#Create('flags.mod' , '%M'),
+ \ Pl#Segment#Create('flags.type' , '%H%W'),
+ \ ),
+ \ Pl#Segment#Create('filename' , '%t'),
+ \ Pl#Segment#Create('filesize' , '%{Powerline#Functions#GetFilesize()}', Pl#Segment#Modes('!N')),
+ \ Pl#Segment#Create('pwd' , '%{Powerline#Functions#GetPwd()}'),
+ \ Pl#Segment#Create('static_str' , '%%{"%s"}'),
+ \ Pl#Segment#Create('raw' , '%s'),
+ \ Pl#Segment#Create('fileformat' , '%{&fileformat}' , Pl#Segment#Modes('!N')),
+ \ Pl#Segment#Create('fileencoding' , '%{(&fenc == "" ? &enc : &fenc)}' , Pl#Segment#Modes('!N')),
+ \ Pl#Segment#Create('filetype' , '$FT %{strlen(&ft) ? &ft : "n/a"}' , Pl#Segment#Modes('!N')),
+ \ Pl#Segment#Create('scrollpercent' , '%3p%%'),
+ \ Pl#Segment#Create('lineinfo',
+ \ Pl#Segment#Create('line.cur' , '$LINE %3l'),
+ \ Pl#Segment#Create('line.tot' , '$COL %-2c'),
+ \ )
+\ )
View
5 autoload/Powerline/Segments/cfi.vim
@@ -0,0 +1,5 @@
+let g:Powerline#Segments#cfi#segments = Pl#Segment#Init('cfi',
+ \ (exists('g:cfi_disable') && g:cfi_disable == 0),
+ \
+ \ Pl#Segment#Create('current_function', '%{Powerline#Functions#cfi#GetCurrentFunction()}', Pl#Segment#Modes('!N'))
+\ )
View
3  autoload/Powerline/Segments/ft_man.vim
@@ -0,0 +1,3 @@
+let g:Powerline#Segments#ft_man#segments = Pl#Segment#Init('ft_man',
+ \ Pl#Segment#Create('filename', '%{Powerline#Functions#ft_man#GetName()}')
+\ )
View
5 autoload/Powerline/Segments/fugitive.vim
@@ -0,0 +1,5 @@
+let g:Powerline#Segments#fugitive#segments = Pl#Segment#Init('fugitive',
+ \ (exists('g:loaded_fugitive') && g:loaded_fugitive == 1),
+ \
+ \ Pl#Segment#Create('branch', '%{Powerline#Functions#fugitive#GetBranch("$BRANCH")}'),
+\ )
View
5 autoload/Powerline/Segments/syntastic.vim
@@ -0,0 +1,5 @@
+let g:Powerline#Segments#syntastic#segments = Pl#Segment#Init('syntastic',
+ \ (exists('g:loaded_syntastic_plugin') && g:loaded_syntastic_plugin == 1),
+ \
+ \ Pl#Segment#Create('errors', '%{Powerline#Functions#syntastic#GetErrors("$line")}', Pl#Segment#Modes('!N')),
+\ )
View
80 autoload/Powerline/Themes/distinguished.vim
@@ -0,0 +1,80 @@
+let g:Powerline#Themes#distinguished#theme = Pl#Theme#Create(
+ \ 'distinguished',
+ \
+ \ Pl#Theme#Buffer(''
+ \ , 'mode_indicator'
+ \ , 'fugitive:branch'
+ \ , 'fileinfo'
+ \ , Pl#Segment#Truncate()
+ \ , 'cfi:current_function'
+ \ , Pl#Segment#Split()
+ \ , 'fileformat'
+ \ , 'fileencoding'
+ \ , 'filetype'
+ \ , 'scrollpercent'
+ \ , 'lineinfo'
+ \ ),
+ \
+ \ Pl#Theme#Buffer('command_t'
+ \ , ['static_str.name', 'Command-T']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ , ['raw.line', '%10(Match #%l%)']
+ \ ),
+ \
+ \ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_tree')
+ \ , ['static_str.name', 'Gundo']
+ \ , ['static_str.buffer', 'Undo tree']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ ),
+ \
+ \ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_preview')
+ \ , ['static_str.name', 'Gundo']
+ \ , ['static_str.buffer', 'Diff preview']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ ),
+ \
+ \ Pl#Theme#Buffer('ft_help'
+ \ , ['static_str.name', 'Help']
+ \ , 'filename'
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ , 'scrollpercent'
+ \ ),
+ \
+ \ Pl#Theme#Buffer('lustyexplorer'
+ \ , ['static_str.name', 'LustyExplorer']
+ \ , ['static_str.buffer', 'Buffer list']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ ),
+ \
+ \ Pl#Theme#Buffer('ft_man'
+ \ , ['static_str.name', 'Man page']
+ \ , 'filename'
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ , 'scrollpercent'
+ \ ),
+ \
+ \ Pl#Theme#Buffer('minibufexplorer'
+ \ , ['static_str.name', 'MiniBufExplorer']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ ),
+ \
+ \ Pl#Theme#Buffer('ft_qf'
+ \ , ['static_str.name', 'Quickfix']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ ),
+ \
+ \ Pl#Theme#Buffer('tagbar'
+ \ , ['static_str.name', 'Tagbar']
+ \ , ['static_str.buffer', 'Tree']
+ \ , Pl#Segment#Truncate()
+ \ , Pl#Segment#Split()
+ \ )
+\ )
View
273 doc/Powerline.txt
@@ -28,18 +28,6 @@ CONTENTS *Powerline-contents*
6. Customization ...................... |Powerline-customization|
6.1 Basics ......................... |Powerline-cust-basics|
6.2 Functions ...................... |Powerline-cust-functions|
- 6.2.1 Pl#Statusline ............ |Pl#Statusline|
- 6.2.2 Pl#StoreStatusline ....... |Pl#StoreStatusline|
- 6.2.3 Pl#Match ................. |Pl#Match|
- 6.2.4 Pl#Segment ............... |Pl#Segment|
- 6.2.5 Pl#SegmentGroup .......... |Pl#SegmentGroup|
- 6.2.6 Pl#Split ................. |Pl#Split|
- 6.2.7 Pl#FG .................... |Pl#FG|
- 6.2.8 Pl#BG .................... |Pl#BG|
- 6.2.9 Pl#Attr .................. |Pl#Attr|
- 6.2.10 Pl#HiCurrent ............ |Pl#HiCurrent|
- 6.2.11 Pl#HiInsert ............. |Pl#HiInsert|
- 6.2.12 Pl#HiNonCurrent ......... |Pl#HiNonCurrent|
7. License ............................ |Powerline-license|
8. Known issues ....................... |Powerline-known-issues|
9. Contributing ....................... |Powerline-contributing|
@@ -161,273 +149,12 @@ option for the changes to take effect.
==============================================================================
6. Customization *Powerline-customization*
-Please see "powerline/distinguished/00-default.vim" for a complete example of
-a statusline theme.
-
------------------------------------------------------------------------------
6.1 Basics *Powerline-cust-basics*
------------------------------------------------------------------------------
6.2 Functions *Powerline-cust-functions*
-------------------------------------------------------------------------------
-6.2.1 Pl#Statusline({argument}[, ...]) *Pl#Statusline*
-
- ARGUMENT DESCRIPTION ~
- {argument} [Required] The return value of any of the following functions:
-
- - |Pl#Match|
- - |Pl#Segment|
- - |Pl#SegmentGroup|
- - |Pl#Split|
-
-This is the main function which must be called for all statuslines. It accepts
-one or more arguments which are described below.
-
-------------------------------------------------------------------------------
-6.2.2 Pl#StoreStatusline({key}, {argument}[, ...]) *Pl#StoreStatusline*
-
- ARGUMENT DESCRIPTION ~
- {key} [Required] A unique key for referring to this statusline
- {argument} [Required] The return value of any of the following functions:
-
- - |Pl#Segment|
- - |Pl#SegmentGroup|
- - |Pl#Split|
-
-This function works like |Pl#Statusline|, but with one important difference:
-It stores and caches the statusline by a key and does NOT automatically apply
-it to any buffer or window. The statusline can be retrieved by calling
-Pl#GetStoredStatusline({key}).
-
-This function can be used for statuslines for plugins that ignore autocmds and
-have their own callback functions for setting statuslines (e.g. Ctrl-P).
-
-Note: This function doesn't accept |Pl#Match| arguments.
-
-------------------------------------------------------------------------------
-6.2.3 Pl#Match({expr}, {re}) *Pl#Match*
-
- ARGUMENT DESCRIPTION ~
- {expr} [Required] Will be |eval()|'ed, must return a string.
-
- EXAMPLE ~
- >
- 'bufname("%")'
- '&ft'
-<
- {re} [Required] Regular expression which will be |match()|'ed
- against "expr".
-
-Limits the current |Pl#Statusline| to specific buffers or filetypes. An
-example is to provide a statusline for only help files.
-
- EXAMPLE ~
->
- Pl#Match('&ft', 'help')
-
-------------------------------------------------------------------------------
-6.2.4 Pl#Segment({text}[, ...]) *Pl#Segment*
-
- ARGUMENT DESCRIPTION ~
- {text} [Required] The segment text. Uses |statusline| syntax. It's
- possible to include variables from |Powerline_symbols| in each
- segment.
-
- EXAMPLE ~
- >
- '%H%W'
- '%{&fileformat}'
-<
- {boolean} [Optional] If a boolean argument is false, this segment will
- be ignored. Used to disable segments if a user doesn't have
- a required plugin or function.
-
- Example: exists('g:loaded_fugitive') && g:loaded_fugitive == 1
-
- {color} [Optional] Color arguments decide the highlighting of this
- segment in different modes. If a specific highlighting is
- missing (e.g. |Pl#HiNonCurrent|), this segment will be
- disabled for that mode.
-
-Returns a segment. Segments are individual, separated "blocks" in the
-statusline which are wrapped in divider symbols according to
-|Powerline_symbols|.
-
- EXAMPLE ~
->
- " This segment will show the current mode in current windows
-
- \ Pl#Segment(" %{substitute(mode(), '', '^V', 'g')} ",
- \ Pl#HiCurrent( Pl#FG(235), Pl#BG(214), Pl#Attr('bold')),
- \ Pl#HiInsert( Pl#FG( 23), Pl#BG(153), Pl#Attr('bold'))
- \ )
-
- " This segment will show the current branch with a branch symbol in all
- " windows, IF fugitive is loaded.
-
- \ Pl#Segment("%{substitute(fugitive#statusline(),
- 'GIT(\\([a-z0-9\\-_\\./:]\\+\\))', ' $branch \\1 ', 'gi')}",
- \ exists('g:loaded_fugitive') && g:loaded_fugitive == 1,
- \
- \ Pl#HiCurrent( Pl#FG(250), Pl#BG(240)),
- \ Pl#HiInsert( Pl#FG(117), Pl#BG( 31)),
- \ Pl#HiNonCurrent(Pl#FG(239), Pl#BG(234))
- \ )
-
-------------------------------------------------------------------------------
-6.2.5 Pl#SegmentGroup([...]) *Pl#SegmentGroup*
-
- ARGUMENT DESCRIPTION ~
- {color} [Optional] Defines the BG highlighting for this group. Only
- |Pl#BG| colors are used.
-
- {segment} [Optional] Adds a segment to this group.
-
-Returns a segment group. Segment groups are collections of segments with
-a common background color and no dividers between the segments. The segment
-group itself is wrapped in dividers. An example for segment groups is adding
-file flags with separate FG colors or attributes directly before or after the
-filename (with no dividers in between).
-
- EXAMPLE ~
->
- Pl#SegmentGroup(
- \ Pl#HiCurrent(Pl#BG(240)), <-- Gray background for the group
- ...
-
- \ Pl#Segment(' %t ', <-- Filename
- \ Pl#HiCurrent(Pl#FG(231)), <-- White foreground
- ...
- \ ),
-
- \ Pl#Segment('%M ', <-- Modified flag
- \ Pl#HiCurrent(Pl#FG(196)), <-- Red foreground
- ...
- \ )
- \ )
-
-------------------------------------------------------------------------------
-6.2.6 Pl#Split([{color}, {color...}]) *Pl#Split*
-
- ARGUMENT DESCRIPTION ~
- {color} [Optional] Defines the highlighting for the empty space
- between the left and right side.
-
-Splits the statusline. It's recommended that you provide highlighting for all
-modes. Only |Pl#BG| colors are required.
-
- EXAMPLE ~
->
- Pl#Split(
- \ Pl#HiCurrent( Pl#BG(236)),
- \ Pl#HiInsert( Pl#BG( 24)),
- \ Pl#HiNonCurrent(Pl#BG(234))
- \ )
-
-------------------------------------------------------------------------------
-6.2.7 Pl#FG({cterm}[, {gui}]) *Pl#FG*
-
- ARGUMENT DESCRIPTION ~
- {cterm} [Required] Integer color for 256-color terminals (0-255).
-
- {gui} [Optional] Integer color for GUI. Must be a |Number|. Usually
- provided as a hex number, i.e. 0xff0000. If left out the cterm
- color is used in the GUI.
-
-Returns a foreground color set for use in |Pl#HiCurrent|, |Pl#HiInsert| and
-|Pl#HiNonCurrent|.
-
- EXAMPLE ~
->
- Pl#FG(21)
- Pl#FG(247, 0x999999)
-
-------------------------------------------------------------------------------
-6.2.8 Pl#BG({cterm}[, {gui}]) *Pl#BG*
-
- ARGUMENT DESCRIPTION ~
- {cterm} [Required] Integer color for 256-color terminals (0-255).
-
- {gui} [Optional] Integer color for GUI. Must be a |Number|. Usually
- provided as a hex number, i.e. 0xff0000. If left out the cterm
- color is used in the GUI.
-
-Returns a background color set for use in |Pl#HiCurrent|, |Pl#HiInsert| and
-|Pl#HiNonCurrent|.
-
- EXAMPLE ~
->
- Pl#BG(21)
- Pl#BG(247, 0x999999)
-
-------------------------------------------------------------------------------
-6.2.9 Pl#Attr({attr}[, {attr...}]) *Pl#Attr*
-
- ARGUMENT DESCRIPTION ~
- {attr} [Required] A highlighting attribute from |attr-list|.
-
-Returns an attribute set for use in |Pl#HiCurrent|, |Pl#HiInsert| and
-|Pl#HiNonCurrent|. Requires one or more attribute arguments.
-
- EXAMPLE ~
->
- Pl#Attr('bold', 'underline')
-
-------------------------------------------------------------------------------
-6.2.10 Pl#HiCurrent({color}[, {color}[, {attr}]]) *Pl#HiCurrent*
-
- ARGUMENT DESCRIPTION ~
- {color} [Required] One or more |Pl#FG| or |Pl#BG| color sets.
- {attr} [Optional] One |Pl#Attr| attribute set.
-
-Returns a collection of colors and attributes for the currently selected vim
-window/split in |Normal-mode|. For use in |Pl#Segment|s, |Pl#SegmentGroup|s
-and |Pl#Split|s.
-
-Note: If this highlighting isn't provided for a |Pl#Segment|, the segment will
-be hidden in normal mode.
-
- EXAMPLE ~
->
- Pl#HiCurrent(Pl#FG(247), Pl#BG(236), Pl#Attr('bold'))
-
-------------------------------------------------------------------------------
-6.2.11 Pl#HiInsert({color}[, {color}[, {attr}]]) *Pl#HiInsert*
-
- ARGUMENT DESCRIPTION ~
- {color} [Required] One or more |Pl#FG| or |Pl#BG| color sets.
- {attr} [Optional] One |Pl#Attr| attribute set.
-
-Returns a collection of colors and attributes for the currently selected vim
-window/split in |Insert-mode|. For use in |Pl#Segment|s, |Pl#SegmentGroup|s
-and |Pl#Split|s.
-
-Note: If this highlighting isn't provided for a |Pl#Segment|, the segment will
-be hidden in insert mode.
-
- EXAMPLE ~
->
- Pl#HiInsert(Pl#FG(117), Pl#BG(24))
-
-------------------------------------------------------------------------------
-6.2.12 Pl#HiNonCurrent({color}[, {color}[, {attr}]]) *Pl#HiNonCurrent*
-
- ARGUMENT DESCRIPTION ~
- {color} [Required] One or more |Pl#FG| or |Pl#BG| color sets.
- {attr} [Optional] One |Pl#Attr| attribute set.
-
-Returns a collection of colors and attributes for the currently selected vim
-window/split in non-current windows (see |hl-StatusLineNC|). For use in
-|Pl#Segment|s, |Pl#SegmentGroup|s and |Pl#Split|s.
-
-Note: If this highlighting isn't provided for a |Pl#Segment|, the segment will
-be hidden in non-current windows.
-
- EXAMPLE ~
->
- Pl#HiNonCurrent(Pl#FG(239), Pl#BG(234))
-
==============================================================================
7. License *Powerline-license*
View
24 plugin/Powerline.vim
@@ -11,18 +11,18 @@
let g:Powerline_loaded = 1
" }}}
" Set default options {{{
- function! s:InitOptions(options) " {{{
- for [key, value] in items(a:options)
- if ! exists('g:Powerline_' . key)
- exec printf('let g:Powerline_%s = %s', key, string(value))
- endif
- endfor
- endfunction " }}}
- call s:InitOptions({
- \ 'theme' : 'distinguished'
- \ , 'symbols' : 'compatible'
- \ , 'cache_file' : (exists('$TEMP') && ! empty($TEMP) ? $TEMP : '/tmp') . '/Powerline.cache'
- \ })
+ for [key, value] in items({
+ \ 'theme' : 'distinguished'
+ \ , 'colorscheme' : 'distinguished'
+ \ , 'symbols' : 'compatible'
+ \ , 'cache_file' : (exists('$TEMP') && ! empty($TEMP) ? $TEMP : '/tmp') . '/Powerline.cache'
+ \ , 'cache_enabled': 1
+ \ })
+
+ if ! exists('g:Powerline_' . key)
+ exec printf('let g:Powerline_%s = %s', key, string(value))
+ endif
+ endfor
" }}}
" Autocommands {{{
augroup Powerline
View
97 powerline/distinguished.vim
@@ -1,97 +0,0 @@
-function! Stl_GetMode() " {{{
- let ret = mode()
-
- let ret = substitute(ret, '', '^V', 'g')
-
- return ret
-endfunction " }}}
-function! Stl_GetBranch(branch_symbol) " {{{
- let ret = fugitive#statusline()
-
- let ret = substitute(ret, 'GIT(\([a-z0-9\-_\./:]\+\))', ' '. a:branch_symbol .' \1 ', 'gi')
-
- return ret
-endfunction " }}}
-function! Stl_GetSyntaxErrors(line_symbol) " {{{
- if ! exists('g:syntastic_stl_format')
- " Syntastic hasn't been loaded yet
- return ''
- endif
-
- " Temporarily change syntastic output format
- let old_stl_format = g:syntastic_stl_format
- let g:syntastic_stl_format = '╱╱╱%E{ ERRORS (%e) '. a:line_symbol .' %fe }%W{ WARNINGS (%w) '. a:line_symbol .' %fw }╱╱╱ '
-
- let ret = SyntasticStatuslineFlag()
-
- let g:syntastic_stl_format = old_stl_format
-
- return ret
-endfunction " }}}
-function! Stl_GetCurrentFunction() " {{{
- return cfi#format(' %s', '')
-endfunction " }}}
-function! Stl_GetCommandTLine() " {{{
- let line = getline('.')
-
- " Trim whitespace from current line
- let line = substitute(line, '\v^\>\s+|\s+$', '', 'g')
-
- return line
-endfunction " }}}
-function! Stl_GetManPage() " {{{
- let matches = matchlist(getline(1), '\v^([a-zA-Z_\.\-]+)\((\d+)\)')
-
- if ! len(matches)
- return 'n/a'
- endif
-
- let file = tolower(matches[1])
- let num = matches[2]
-
- return file
-endfunction " }}}
-" Handle Ctrl-P statuslines {{{
-if exists('g:loaded_ctrlp') && g:loaded_ctrlp
- let g:ctrlp_status_func = {
- \ 'main': 'CtrlP_Statusline_Main',
- \ 'prog': 'CtrlP_Statusline_Prog'
- \ }
-
- function! CtrlP_Statusline_Main(...) " {{{
- let stl = Pl#GetStoredStatusline('ctrlp_main')['current']
-
- let regex = a:3 ? ' RE ' : ''
- let marked = strpart(a:7, 2, len(a:7) - 3)
-
- let substitutes = {
- \ 'focus' : a:1,
- \ 'byfname': a:2,
- \ 'regex' : regex,
- \ 'prev' : a:4,
- \ 'item' : a:5,
- \ 'next' : a:6,
- \ 'marked' : (marked == '+' ? '' : ' ' . marked . ' ')
- \ }
-
- for [k, v] in items(substitutes)
- let stl = substitute(stl, '\v\%' . toupper(k), v, 'g')
- endfor
-
- return stl
- endfunction " }}}
- function! CtrlP_Statusline_Prog(...) " {{{
- let stl = Pl#GetStoredStatusline('ctrlp_prog')['current']
-
- let substitutes = {
- \ 'len' : a:1
- \ }
-
- for [k, v] in items(substitutes)
- let stl = substitute(stl, '\v\%' . toupper(k), v, 'g')
- endfor
-
- return stl
- endfunction " }}}
-endif
-" }}}
View
93 powerline/distinguished/00-default.vim
@@ -1,93 +0,0 @@
-call Pl#Statusline(
- \ Pl#Segment(" %-2{Stl_GetMode()} ",
- \ Pl#HiCurrent( Pl#FG( 22), Pl#BG(148), Pl#Attr('bold')),
- \ Pl#HiInsert( Pl#FG( 23), Pl#BG(231), Pl#Attr('bold'))
- \ ),
- \
- \ Pl#Segment("%{Stl_GetBranch('$branch')}",
- \ exists('g:loaded_fugitive') && g:loaded_fugitive == 1,
- \
- \ Pl#HiCurrent( Pl#FG(250), Pl#BG(240)),
- \ Pl#HiInsert( Pl#FG(117), Pl#BG( 31)),
- \ Pl#HiNonCurrent(Pl#FG(239), Pl#BG(235))
- \ ),
- \
- \ Pl#SegmentGroup(
- \ Pl#HiCurrent( Pl#BG(240)),
- \ Pl#HiInsert( Pl#BG( 31)),
- \ Pl#HiNonCurrent(Pl#BG(235)),
- \
- \ Pl#Segment("%{&readonly ? ' $ro' : ''}",
- \ Pl#HiCurrent( Pl#FG(196)),
- \ Pl#HiInsert( Pl#FG(196)),
- \ Pl#HiNonCurrent(Pl#FG( 88))
- \ ),
- \ Pl#Segment(" %t ",
- \ Pl#HiCurrent( Pl#FG(231), Pl#Attr('bold')),
- \ Pl#HiInsert( Pl#FG(231), Pl#Attr('bold')),
- \ Pl#HiNonCurrent(Pl#FG(245), Pl#Attr('bold'))
- \ ),
- \ Pl#Segment("%M ",
- \ Pl#HiCurrent( Pl#FG(196), Pl#Attr('bold')),
- \ Pl#HiInsert( Pl#FG(196), Pl#Attr('bold')),
- \ Pl#HiNonCurrent(Pl#FG( 88))
- \ ),
- \ Pl#Segment("%H%W ",
- \ Pl#HiCurrent( Pl#FG(250)),
- \ Pl#HiInsert( Pl#FG(117)),
- \ Pl#HiNonCurrent(Pl#FG(239))
- \ ),
- \ Pl#Segment("%{Stl_GetSyntaxErrors('$line')}",
- \ exists('g:loaded_syntastic_plugin') && g:loaded_syntastic_plugin == 1,
- \
- \ Pl#HiCurrent( Pl#FG(214), Pl#Attr('bold')),
- \ Pl#HiInsert( Pl#FG(214), Pl#Attr('bold')),
- \ )
- \ ),
- \
- \ Pl#Segment("%<%{Stl_GetCurrentFunction()}",
- \ exists('g:cfi_disable') && g:cfi_disable == 0,
- \
- \ Pl#HiCurrent( Pl#FG(247), Pl#BG(236)),
- \ Pl#HiInsert( Pl#FG(117), Pl#BG( 24))
- \ ),
- \
- \ Pl#Split(
- \ Pl#HiCurrent( Pl#BG(236)),