Commits

Andres Vargas  committed 64c60e1

powerline

  • Participants
  • Parent commits edd8e8f

Comments (0)

Files changed (38)

File autoload/Pl.vim

+" Powerline - The ultimate statusline utility
+"
+" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
+" Source repository: https://github.com/Lokaltog/vim-powerline
+
+" Script variables {{{
+	let g:Pl#OLD_STL = ''
+	let g:Pl#THEME = []
+	let g:Pl#THEME_CALLBACKS = []
+	let g:Pl#HL = []
+
+	" Cache revision, this must be incremented whenever the cache format is changed
+	let s:CACHE_REVISION = 7
+" }}}
+" Script initialization {{{
+	function! Pl#LoadCache() " {{{
+		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, cache is invalid
+				unlet! g:Powerline_cache_revision
+
+				return 0
+			endif
+
+			" Create highlighting groups
+			for hi_cmd in g:Pl#HL
+				exec hi_cmd
+			endfor
+
+			" Run theme callbacks
+			for callback in g:Pl#THEME_CALLBACKS
+				" Substitute {{NEWLINE}} with newlines (strings must be
+				" stored without newlines characters to avoid vim errors)
+				exec substitute(callback[0], "{{NEWLINE}}", "\n", 'g')
+				exec substitute(callback[1], "{{NEWLINE}}", "\n", 'g')
+			endfor
+
+			return 1
+		endif
+
+		return 0
+	endfunction " }}}
+	function! Pl#ClearCache() " {{{
+		if filereadable(g:Powerline_cache_file)
+			" Delete the cache file
+			call delete(g:Powerline_cache_file)
+		endif
+
+		echo 'Powerline cache cleared. Please restart vim for the changes to take effect.'
+	endfunction " }}}
+	function! Pl#ReloadColorscheme() " {{{
+		call Pl#ClearCache()
+
+		" The colorscheme and theme files must be manually sourced because
+		" vim won't reload previously autoloaded files
+		"
+		" This is a bit hackish, but it works
+		unlet! g:Powerline#Colorschemes#{g:Powerline_colorscheme}#colorscheme
+		exec "source" split(globpath(&rtp, 'autoload/Powerline/Colorschemes/'. g:Powerline_colorscheme .'.vim', 1), '\n')[0]
+
+		unlet! g:Powerline#Themes#{g:Powerline_theme}#theme
+		exec "source" split(globpath(&rtp, 'autoload/Powerline/Themes/'. g:Powerline_theme .'.vim', 1), '\n')[0]
+
+		let g:Pl#THEME = []
+
+		call Pl#Load()
+	endfunction " }}}
+	function! Pl#Load() " {{{
+		if empty(g:Pl#OLD_STL)
+			" Store old statusline
+			let g:Pl#OLD_STL = &statusline
+		endif
+
+		if ! Pl#LoadCache()
+			try
+				" Autoload the theme dict first
+				let raw_theme = g:Powerline#Themes#{g:Powerline_theme}#theme
+			catch
+				echom 'Invalid Powerline theme! Please check your theme and colorscheme settings.'
+
+				return
+			endtry
+
+			" Create list with parsed statuslines
+			for buffer_statusline in raw_theme
+				unlet! mode_statuslines
+				let mode_statuslines = Pl#Parser#GetStatusline(buffer_statusline.segments)
+
+				if ! empty(buffer_statusline.callback)
+					" The callback function passes its arguments on to
+					" Pl#StatuslineCallback along with the normal/current mode
+					" statusline.
+					let s:cb_func  = "function! PowerlineStatuslineCallback_". buffer_statusline.callback[1] ."(...)\n"
+					let s:cb_func .= "return Pl#StatuslineCallback(". string(mode_statuslines['n']) .", a:000)\n"
+					let s:cb_func .= "endfunction"
+
+					" The callback expression should be used to initialize any
+					" variables that will use the callback function. The
+					" expression requires a %s which will be replaced by the
+					" callback function name.
+					let s:cb_expr  = printf(buffer_statusline.callback[2], 'PowerlineStatuslineCallback_'. buffer_statusline.callback[1])
+
+					exec s:cb_func
+					exec s:cb_expr
+
+					" Newlines must be substituted with another character
+					" because vim doesn't like newlines in strings
+					call add(g:Pl#THEME_CALLBACKS, [substitute(s:cb_func, "\n", "{{NEWLINE}}", 'g'), substitute(s:cb_expr, "\n", "{{NEWLINE}}", 'g')])
+
+					unlet! s:cb_func s:cb_expr
+
+					continue
+				endif
+
+				" Store the statuslines for matching specific buffers
+				call add(g:Pl#THEME, {
+					\ 'matches': buffer_statusline.matches,
+					\ 'mode_statuslines': mode_statuslines
+					\ })
+			endfor
+
+			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:Pl#HL = '. string(g:Pl#HL),
+				\ 'let g:Pl#THEME  = '. string(g:Pl#THEME),
+				\ 'let g:Pl#THEME_CALLBACKS  = '. string(g:Pl#THEME_CALLBACKS),
+			\ ]
+
+			call writefile(cache, g:Powerline_cache_file)
+		endif
+	endfunction " }}}
+" }}}
+" Statusline updater {{{
+	function! Pl#Statusline(statusline, 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 =~# '\v(s|S|)'
+			let mode = 's' " Select mode
+		elseif mode =~# '\vi'
+			let mode = 'i' " Insert mode
+		elseif mode =~# '\v(R|Rv)'
+			let mode = 'r' " Replace mode
+		else
+			" Fallback to normal mode
+			let mode = 'n' " Normal (current)
+		endif
+
+		return g:Pl#THEME[a:statusline].mode_statuslines[mode]
+	endfunction " }}}
+	function! Pl#StatuslineCallback(statusline, args) " {{{
+		" Replace %1, %2, etc. in the statusline with the callback args
+		return substitute(
+			\ a:statusline,
+			\ '\v\%(\d+)',
+			\ '\=a:args[submatch(1)]',
+			\ 'g')
+	endfunction " }}}
+	function! Pl#UpdateStatusline(current) " {{{
+		if empty(g:Pl#THEME)
+			" Load statuslines if they aren't loaded yet
+			call Pl#Load()
+		endif
+
+		for i in range(0, len(g:Pl#THEME) - 1)
+			if Pl#Match#Validate(g:Pl#THEME[i])
+				" Update window-local statusline
+				let &l:statusline = '%!Pl#Statusline('. i .','. a:current .')'
+			endif
+		endfor
+	endfunction " }}}
+" }}}

File autoload/Pl/Colorscheme.vim

+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) " {{{
+	" Set color parameters for all segments in a:buffer_segments
+
+	" TODO This function should be recursive and work on both segments and groups
+	" TODO We could probably handle the NS stuff here...
+
+	try
+		let colorscheme = g:Powerline#Colorschemes#{a:colorscheme}#colorscheme
+	catch
+		echom 'Color scheme "'. a:colorscheme .'" doesn''t exist!'
+
+		return
+	endtry
+
+	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 " }}}

File autoload/Pl/Hi.vim

+" cterm -> gui color dict {{{
+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,
+	\ 34:  0x00af00, 35:  0x00af5f, 36:  0x00af87, 37:  0x00afaf, 38:  0x00afd7, 39:  0x00afff,
+	\ 40:  0x00d700, 41:  0x00d75f, 42:  0x00d787, 43:  0x00d7af, 44:  0x00d7d7, 45:  0x00d7ff,
+	\ 46:  0x00ff00, 47:  0x00ff5f, 48:  0x00ff87, 49:  0x00ffaf, 50:  0x00ffd7, 51:  0x00ffff,
+	\ 52:  0x5f0000, 53:  0x5f005f, 54:  0x5f0087, 55:  0x5f00af, 56:  0x5f00d7, 57:  0x5f00ff,
+	\ 58:  0x5f5f00, 59:  0x5f5f5f, 60:  0x5f5f87, 61:  0x5f5faf, 62:  0x5f5fd7, 63:  0x5f5fff,
+	\ 64:  0x5f8700, 65:  0x5f875f, 66:  0x5f8787, 67:  0x5f87af, 68:  0x5f87d7, 69:  0x5f87ff,
+	\ 70:  0x5faf00, 71:  0x5faf5f, 72:  0x5faf87, 73:  0x5fafaf, 74:  0x5fafd7, 75:  0x5fafff,
+	\ 76:  0x5fd700, 77:  0x5fd75f, 78:  0x5fd787, 79:  0x5fd7af, 80:  0x5fd7d7, 81:  0x5fd7ff,
+	\ 82:  0x5fff00, 83:  0x5fff5f, 84:  0x5fff87, 85:  0x5fffaf, 86:  0x5fffd7, 87:  0x5fffff,
+	\ 88:  0x870000, 89:  0x87005f, 90:  0x870087, 91:  0x8700af, 92:  0x8700d7, 93:  0x8700ff,
+	\ 94:  0x875f00, 95:  0x875f5f, 96:  0x875f87, 97:  0x875faf, 98:  0x875fd7, 99:  0x875fff,
+	\ 100: 0x878700, 101: 0x87875f, 102: 0x878787, 103: 0x8787af, 104: 0x8787d7, 105: 0x8787ff,
+	\ 106: 0x87af00, 107: 0x87af5f, 108: 0x87af87, 109: 0x87afaf, 110: 0x87afd7, 111: 0x87afff,
+	\ 112: 0x87d700, 113: 0x87d75f, 114: 0x87d787, 115: 0x87d7af, 116: 0x87d7d7, 117: 0x87d7ff,
+	\ 118: 0x87ff00, 119: 0x87ff5f, 120: 0x87ff87, 121: 0x87ffaf, 122: 0x87ffd7, 123: 0x87ffff,
+	\ 124: 0xaf0000, 125: 0xaf005f, 126: 0xaf0087, 127: 0xaf00af, 128: 0xaf00d7, 129: 0xaf00ff,
+	\ 130: 0xaf5f00, 131: 0xaf5f5f, 132: 0xaf5f87, 133: 0xaf5faf, 134: 0xaf5fd7, 135: 0xaf5fff,
+	\ 136: 0xaf8700, 137: 0xaf875f, 138: 0xaf8787, 139: 0xaf87af, 140: 0xaf87d7, 141: 0xaf87ff,
+	\ 142: 0xafaf00, 143: 0xafaf5f, 144: 0xafaf87, 145: 0xafafaf, 146: 0xafafd7, 147: 0xafafff,
+	\ 148: 0xafd700, 149: 0xafd75f, 150: 0xafd787, 151: 0xafd7af, 152: 0xafd7d7, 153: 0xafd7ff,
+	\ 154: 0xafff00, 155: 0xafff5f, 156: 0xafff87, 157: 0xafffaf, 158: 0xafffd7, 159: 0xafffff,
+	\ 160: 0xd70000, 161: 0xd7005f, 162: 0xd70087, 163: 0xd700af, 164: 0xd700d7, 165: 0xd700ff,
+	\ 166: 0xd75f00, 167: 0xd75f5f, 168: 0xd75f87, 169: 0xd75faf, 170: 0xd75fd7, 171: 0xd75fff,
+	\ 172: 0xd78700, 173: 0xd7875f, 174: 0xd78787, 175: 0xd787af, 176: 0xd787d7, 177: 0xd787ff,
+	\ 178: 0xd7af00, 179: 0xd7af5f, 180: 0xd7af87, 181: 0xd7afaf, 182: 0xd7afd7, 183: 0xd7afff,
+	\ 184: 0xd7d700, 185: 0xd7d75f, 186: 0xd7d787, 187: 0xd7d7af, 188: 0xd7d7d7, 189: 0xd7d7ff,
+	\ 190: 0xd7ff00, 191: 0xd7ff5f, 192: 0xd7ff87, 193: 0xd7ffaf, 194: 0xd7ffd7, 195: 0xd7ffff,
+	\ 196: 0xff0000, 197: 0xff005f, 198: 0xff0087, 199: 0xff00af, 200: 0xff00d7, 201: 0xff00ff,
+	\ 202: 0xff5f00, 203: 0xff5f5f, 204: 0xff5f87, 205: 0xff5faf, 206: 0xff5fd7, 207: 0xff5fff,
+	\ 208: 0xff8700, 209: 0xff875f, 210: 0xff8787, 211: 0xff87af, 212: 0xff87d7, 213: 0xff87ff,
+	\ 214: 0xffaf00, 215: 0xffaf5f, 216: 0xffaf87, 217: 0xffafaf, 218: 0xffafd7, 219: 0xffafff,
+	\ 220: 0xffd700, 221: 0xffd75f, 222: 0xffd787, 223: 0xffd7af, 224: 0xffd7d7, 225: 0xffd7ff,
+	\ 226: 0xffff00, 227: 0xffff5f, 228: 0xffff87, 229: 0xffffaf, 230: 0xffffd7, 231: 0xffffff,
+	\ 232: 0x080808, 233: 0x121212, 234: 0x1c1c1c, 235: 0x262626, 236: 0x303030, 237: 0x3a3a3a,
+	\ 238: 0x444444, 239: 0x4e4e4e, 240: 0x585858, 241: 0x626262, 242: 0x6c6c6c, 243: 0x767676,
+	\ 244: 0x808080, 245: 0x8a8a8a, 246: 0x949494, 247: 0x9e9e9e, 248: 0xa8a8a8, 249: 0xb2b2b2,
+	\ 250: 0xbcbcbc, 251: 0xc6c6c6, 252: 0xd0d0d0, 253: 0xdadada, 254: 0xe4e4e4, 255: 0xeeeeee
+\ }
+" }}}
+" Allocated color dict {{{
+let s:allocated_colors = {
+	\ 'NONE': 'NONE',
+	\ }
+" }}}
+function! s:Cterm2GUI(cterm) " {{{
+	if toupper(a:cterm) == 'NONE'
+		return 'NONE'
+	endif
+
+	if ! has_key(s:cterm2gui_dict, a:cterm)
+		return 0xff0000
+	endif
+
+	return s:cterm2gui_dict[a:cterm]
+endfunction " }}}
+function! Pl#Hi#Segments(segments, mode_colors) " {{{
+	let mode_translate = {
+		\ 'normal':     'n',
+		\ 'noncurrent': 'N',
+		\ 'insert':     'i',
+		\ 'visual':     'v',
+		\ 'replace':    'r',
+		\ 'select':     's',
+		\ }
+
+	let attributes = ['bold', 'italic', 'underline']
+
+	let segments = a:segments
+	let mode_hi_dict = {}
+
+	" Mode dict
+	for [mode, colors] in items(a:mode_colors)
+		if has_key(mode_translate, mode)
+			let mode = mode_translate[mode]
+		endif
+
+		unlet! fg
+		let fg = s:allocated_colors[colors[0]]
+
+		let hi = {
+			\ 'cterm': [fg['cterm'], ''],
+			\ 'gui'  : [fg['gui'], ''],
+			\ 'attr' : []
+			\ }
+
+		if exists('colors[1]')
+			if type(colors[1]) == type([])
+				" We don't have a BG color, but we have attributes
+				let hi.attr = colors[1]
+			else
+				" The second parameter is the background color
+				unlet! bg
+				let bg = s:allocated_colors[colors[1]]
+
+				let hi.cterm[1] = bg['cterm']
+				let hi.gui[1] = bg['gui']
+			endif
+		endif
+
+		if exists('colors[2]') && type(colors[2]) == type([])
+			" The third parameter is always an attribute list
+			let hi.attr = colors[2]
+		endif
+
+		let mode_hi_dict[mode] = {
+			\ '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'], ','))
+			\ }
+	endfor
+
+	return [segments, mode_hi_dict]
+endfunction " }}}
+function! Pl#Hi#Allocate(colors) " {{{
+	for [key, color] in items(a:colors)
+		if type(color) == type(0)
+			" Only terminal color
+			let cterm = color
+			let gui = s:Cterm2GUI(color)
+		elseif type(color) == type([]) && len(color) == 2
+			" Terminal and GUI colors
+			let cterm = color[0]
+			let gui = color[1]
+		endif
+
+		let s:allocated_colors[key] = {
+			\ 'cterm': cterm,
+			\ 'gui': gui,
+			\ }
+
+		unlet! color
+	endfor
+endfunction " }}}

File autoload/Pl/Match.vim

+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(theme) " {{{
+	let match = a:theme.matches[1]
+
+	if match == 'none'
+		return 0
+	elseif match == 'any'
+		let matches = a:theme.matches[2]
+
+		if ! len(matches)
+			" Empty match array matches everything
+			return 1
+		endif
+
+		for [eval, re] in matches
+			if match(eval(eval), '\v'. re) != -1
+				return 1
+			endif
+		endfor
+
+		return 0
+	endif
+endfunction " }}}

File autoload/Pl/Mod.vim

+let s:segment_mods = []
+
+function! Pl#Mod#AddSegmentMod(action, properties) " {{{
+	call add(s:segment_mods, [a:action, a:properties])
+endfunction " }}}
+function! Pl#Mod#ApplySegmentMods(theme) " {{{
+	let theme = deepcopy(a:theme)
+
+	for mod in s:segment_mods
+		let [action, properties] = mod
+
+		" We have to loop through the segments 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(properties.target_segment) && segment == properties.target_segment
+				let target_seg_idx = i
+				break
+			endif
+		endfor
+
+		if action == 'insert_segment'
+			" Insert segment
+			if target_seg_idx != -1
+				call insert(theme, properties.new_segment, (properties.where == 'before' ? target_seg_idx : target_seg_idx + 1))
+			endif
+		elseif action == 'remove_segment'
+			" Remove segment
+			if target_seg_idx != -1
+				call remove(theme, target_seg_idx)
+			endif
+		endif
+	endfor
+
+	return theme
+endfunction " }}}

File autoload/Pl/Parser.vim

+let g:Pl#Parser#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]
+		\ }
+	\ }
+\ }
+
+" Handle symbol overrides
+for [s:key, s:value] in items(g:Powerline_symbols_override)
+	let g:Pl#Parser#Symbols[g:Powerline_symbols].symbols[s:key] = s:value
+
+	unlet! s:key s:value
+endfor
+
+" Handle divider overrides
+if len(g:Powerline_dividers_override) == 4
+	let g:Pl#Parser#Symbols[g:Powerline_symbols].dividers = g:Powerline_dividers_override
+endif
+
+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': ''
+		\ , 's': ''
+		\ }
+
+	" 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
+
+		" If we're currently at i = 0 we have to start on 0 or else we will start on the last segment (list[-1])
+		let range_start = (i == 0 ? i : i - 1)
+		for j in range(range_start, 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
+
+		" If we're currently at i = len(segments) - 1 we have to start on i or else we will get an error because the index doesn't exist
+		let range_start = (i == len(segments) - 1 ? i : i + 1)
+		for j in range(range_start, 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)
+					echom '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, but only pad
+					" if the segment doesn't have Pl#Segment#NoPadding() set
+					let padding_right = (seg_curr.padding && side == s:LEFT_SIDE  ? repeat(' ', s:PADDING) : '')
+					let padding_left  = (seg_curr.padding && 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)
+		let ctermbg = a:hl['ctermbg'] == 'NONE' ? 'NONE' : printf('%d', a:hl['ctermbg'])
+		if (has('win32') || has('win64')) && !has('gui_running') && ctermbg != 'NONE' && ctermbg > 128
+			let ctermbg -= 128
+		endif
+		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'])
+			\ , 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
+			if div_colors['attr'] =~ 'reverse' && cmp_colors['attr'] =~ 'reverse'
+				" Use FG = CURRENT FG, BG = CMP FG
+				let div_colors['ctermbg'] = get(cmp_colors, 'ctermfg')
+				let div_colors['guibg']   = get(cmp_colors, 'guifg')
+
+				let div_colors['attr']    = div_colors['attr'] =~ 'bold' ? 'bold' : 'NONE'
+			elseif div_colors['attr'] =~ 'reverse'
+				" Use FG = CURRENT FG, BG = CMP BG
+				let div_colors['ctermbg'] = get(cmp_colors, 'ctermbg')
+				let div_colors['guibg']   = get(cmp_colors, 'guibg')
+
+				let div_colors['attr']    = div_colors['attr'] =~ 'bold' ? 'bold' : 'NONE'
+			elseif cmp_colors['attr'] =~ 'reverse'
+				" Use FG = CMP FG, BG = CURRENT BG : reversed
+				let div_colors['ctermfg'] = get(cmp_colors, 'ctermfg')
+				let div_colors['guifg']   = get(cmp_colors, 'guifg')
+
+				let div_colors['attr']    = 'reverse'
+
+			else
+				" 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')
+
+				let div_colors['attr']    = 'NONE'
+			endif
+		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 " }}}

File autoload/Pl/Segment.vim

+let s:default_modes = ['n', 'N', 'v', 'i', 'r', 's']
+
+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 padding = 1
+	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(param) == type([]) && param[0] == 'nopadding'
+			let padding = 0
+		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
+			\ , 'padding': padding
+			\ }]
+	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')
+
+			unlet! key symbol
+		endfor
+
+		return ['segment', {
+			\   'type': 'segment'
+			\ , 'name': name
+			\ , 'text': text
+			\ , 'modes': modes
+			\ , 'padding': padding
+			\ }]
+	endif
+
+endfunction " }}}
+function! Pl#Segment#Init(params) " {{{
+	" Check condition parameters
+	if ! s:CheckConditions(a:params)
+		return {}
+	endif
+
+	let segments = {}
+	let ns = ''
+
+	for param in a:params
+		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#NoPadding() " {{{
+	return ['nopadding']
+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
+			return {}
+		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 " }}}

File autoload/Pl/Theme.vim

+function! Pl#Theme#Create(...) " {{{
+	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(g:Powerline_colorscheme, buffer_segments)
+
+	return buffer_segments
+endfunction " }}}
+function! Pl#Theme#Callback(name, expr) " {{{
+	return ['callback', a:name, a:expr]
+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 callback = []
+
+	let args = a:000
+	let args = Pl#Mod#ApplySegmentMods(args)
+
+	" Fetch segment data dicts
+	for item in args
+		if type(item) == type([])
+			if item[0] == 'match'
+				" Match item, overrides default namespace match
+				let matches = item
+
+				unlet! item
+				continue
+			elseif item[0] == 'callback'
+				" Store the item as a callback expression
+				let matches = ['match', 'none']
+				let callback = [a:ns, item[1], item[2]]
+
+				unlet! 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)
+
+		if ! empty(segment)
+			" Skip empty (possible disabled) segments
+			call add(segments, segment)
+		endif
+
+		unlet! item
+	endfor
+
+	return {
+		\   'matches': matches
+		\ , 'callback': callback
+		\ , '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 Pl#Mod#AddSegmentMod('insert_segment', {
+		\ '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 Pl#Mod#AddSegmentMod('remove_segment', {
+		\ '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 " }}}

File autoload/Powerline/Colorschemes/default.vim

+call Pl#Hi#Allocate({
+	\ 'black'          : 16,
+	\ 'white'          : 231,
+	\
+	\ 'darkestgreen'   : 22,
+	\ 'darkgreen'      : 28,
+	\ 'mediumgreen'    : 70,
+	\ 'brightgreen'    : 148,
+	\
+	\ 'darkestcyan'    : 23,
+	\ 'mediumcyan'     : 117,
+	\
+	\ 'darkestblue'    : 24,
+	\ 'darkblue'       : 31,
+	\
+	\ 'darkestred'     : 52,
+	\ 'darkred'        : 88,
+	\ 'mediumred'      : 124,
+	\ 'brightred'      : 160,
+	\ 'brightestred'   : 196,
+	\
+	\ 'darkestpurple'  : 55,
+	\ 'mediumpurple'   : 98,
+	\ 'brightpurple'   : 189,
+	\
+	\ 'brightorange'   : 208,
+	\ 'brightestorange': 214,
+	\
+	\ 'gray0'          : 233,
+	\ 'gray1'          : 235,
+	\ 'gray2'          : 236,
+	\ 'gray3'          : 239,
+	\ 'gray4'          : 240,
+	\ 'gray5'          : 241,
+	\ 'gray6'          : 244,
+	\ 'gray7'          : 245,
+	\ 'gray8'          : 247,
+	\ 'gray9'          : 250,
+	\ 'gray10'         : 252,
+	\ })
+
+let g:Powerline#Colorschemes#default#colorscheme = Pl#Colorscheme#Init([
+	\ Pl#Hi#Segments(['SPLIT'], {
+		\ 'n': ['white', 'gray2'],
+		\ 'N': ['white', 'gray0'],
+		\ 'i': ['white', 'darkestblue'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['mode_indicator'], {
+		\ 'n': ['darkestgreen', 'brightgreen', ['bold']],
+		\ 'i': ['darkestcyan', 'white', ['bold']],
+		\ 'v': ['darkred', 'brightorange', ['bold']],
+		\ 'r': ['white', 'brightred', ['bold']],
+		\ 's': ['white', 'gray5', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['branch', 'scrollpercent', 'raw', 'filesize'], {
+		\ 'n': ['gray9', 'gray4'],
+		\ 'N': ['gray4', 'gray1'],
+		\ 'i': ['mediumcyan', 'darkblue'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo', 'filename'], {
+		\ 'n': ['white', 'gray4', ['bold']],
+		\ 'N': ['gray7', 'gray0', ['bold']],
+		\ 'i': ['white', 'darkblue', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
+		\ 'n': ['gray10'],
+		\ 'N': ['gray5'],
+		\ 'i': ['mediumcyan'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['static_str'], {
+		\ 'n': ['white', 'gray4'],
+		\ 'N': ['gray7', 'gray1'],
+		\ 'i': ['white', 'darkblue'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
+		\ 'n': ['brightestred', ['bold']],
+		\ 'N': ['darkred'],
+		\ 'i': ['brightestred', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
+		\ 'n': ['gray8', 'gray2'],
+		\ 'i': ['mediumcyan', 'darkestblue'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo'], {
+		\ 'n': ['gray2', 'gray10', ['bold']],
+		\ 'N': ['gray7', 'gray1', ['bold']],
+		\ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['errors'], {
+		\ 'n': ['brightestorange', 'gray2', ['bold']],
+		\ 'i': ['brightestorange', 'darkestblue', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
+		\ 'n': ['gray6'],
+		\ 'N': ['gray5'],
+		\ 'i': ['darkestcyan'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
+		\ 'n': ['white', 'brightred', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
+		\ 'n': ['white', 'mediumred', ['bold']],
+		\ 'N': ['brightred', 'darkestred', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
+		\ 'n': ['white', 'darkred'],
+		\ 'N': ['brightred', 'darkestred'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
+		\ 'n': ['white', 'darkred'],
+		\ 'N': ['white', 'darkestred'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
+		\ 'n': ['white', 'mediumgreen', ['bold']],
+		\ 'N': ['mediumgreen', 'darkestgreen', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
+		\ 'n': ['brightgreen', 'darkgreen'],
+		\ 'N': ['mediumgreen', 'darkestgreen'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
+		\ 'n': ['white', 'darkgreen'],
+		\ 'N': ['white', 'darkestgreen'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
+		\ 'n': ['brightpurple', 'darkestpurple'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
+		\ 'n': ['white', 'mediumpurple'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:item'], {
+		\ 'n': ['darkestpurple', 'white', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
+		\ 'n': ['brightestred', 'darkestpurple', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:count'], {
+		\ 'n': ['darkestpurple', 'white'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
+		\ 'n': ['white', 'darkestpurple'],
+		\ }),
+	\ ])

File autoload/Powerline/Colorschemes/solarized.vim

+
+" Solarized color scheme for Powerline
+" N = no focus
+" 16 hex colors as defined on http://ethanschoonover.com/solarized
+call Pl#Hi#Allocate({
+  \ 'base03'  : [8,   0x002b36],
+  \ 'base02'  : [0,   0x073642],
+  \ 'base01'  : [10,  0x586e75],
+  \ 'base00'  : [11,  0x657b83],
+  \ 'base0'   : [12,  0x839496],
+  \ 'base1'   : [14,  0x93a1a1],
+  \ 'base2'   : [7,   0xeee8d5],
+  \ 'base3'   : [15,  0xfdf6e3],
+  \ 'yellow'  : [3,   0xb58900],
+  \ 'orange'  : [9,   0xcb4b16],
+  \ 'red'     : [1,   0xdc322f],
+  \ 'magenta' : [5,   0xd33682],
+  \ 'violet'  : [13,  0x6c71c4],
+  \ 'blue'    : [4,   0x268bd2],
+  \ 'cyan'    : [6,   0x2aa198],
+  \ 'green'   : [2,   0x859900],
+	\ })
+
+let g:Powerline#Colorschemes#solarized#colorscheme = Pl#Colorscheme#Init([
+	\ Pl#Hi#Segments(['SPLIT'], {
+		\ 'n': ['base3',  'base2'],
+		\ 'N': ['base3',  'base2'],
+		\ 'i': ['base3',  'base2'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['mode_indicator'], {
+		\ 'n': ['base2',  'blue',     ['bold']],
+		\ 'i': ['base3',  'orange',   ['bold']],
+		\ 'v': ['base3',  'magenta',  ['bold']],
+		\ 'r': ['base3',  'violet',   ['bold']],
+		\ 's': ['base3',  'yellow',   ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['branch'], {
+		\ 'n': ['base2',   'base02'],
+		\ 'N': ['base02',  'base1'],
+		\ 'i': ['base2',   'base00'],
+		\ }),
+	\
+  \ Pl#Hi#Segments(['scrollpercent', 'raw', 'filesize'], {
+		\ 'n': ['base2',   'base0'],
+		\ 'N': ['base00',  'base2'],
+		\ 'i': ['base2',   'base1'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo', 'filename'], {
+		\ 'n': ['base2',   'base01',   ['bold']],
+		\ 'N': ['base01',  'base2' ],
+		\ 'i': ['base3',   'base1',    ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
+		\ 'n': ['base1'],
+		\ 'N': ['base1'],
+		\ 'i': ['base01'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['static_str'], {
+		\ 'n': ['base3',   'green'],
+		\ 'N': ['base02',  'base01'],
+		\ 'i': ['base3',   'blue'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
+		\ 'n': ['base3'],
+		\ 'N': ['base00'],
+		\ 'i': ['base3'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['currenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
+		\ 'n': ['base00', 'base2'],
+		\ 'i': ['base0', 'base2'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo'], {
+		\ 'n': ['base2',   'base01',  ['bold']],
+		\ 'N': ['base02',  'base0'],
+		\ 'i': ['base2',   'base00',  ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['errors'], {
+		\ 'n': ['red',  'base2',  ['bold']],
+		\ 'i': ['red',  'base2',  ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
+		\ 'n': ['base3'],
+		\ 'N': ['base02'],
+		\ 'i': ['base3'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
+		\ 'n': ['base3', 'red', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
+		\ 'n': ['base3',   'red',     ['bold']],
+		\ 'N': ['base02',  'base01',  ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
+		\ 'n': ['base3',  'base00'],
+		\ 'N': ['base0',  'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
+		\ 'n': ['base3',  'base02'],
+		\ 'N': ['base0',  'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
+		\ 'n': ['base2',   'green',   ['bold']],
+		\ 'N': ['base02',  'base1'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
+		\ 'n': ['base3',   'base01'],
+		\ 'N': ['base02',  'base01'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
+		\ 'n': ['base2',  'base2'],
+		\ 'N': ['base2',  'base2'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
+		\ 'n': ['base03', 'base01'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
+		\ 'n': ['base3', 'base00'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:item'], {
+		\ 'n': ['base3', 'violet', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
+		\ 'n': ['base1', 'base01', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:count'], {
+		\ 'n': ['base3', 'violet'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
+		\ 'n': ['base3', 'base03'],
+		\ }),
+	\ ])

File autoload/Powerline/Colorschemes/solarized16.vim

+" Authors:
+"   @stephenmckinney
+"
+" This colorscheme is based on Solarized-dark colors, setting the specific
+" values for the Solarized palette, using the terminal's 16 ansi
+" color values. It combines Solarized with Powerline native colors.
+call Pl#Hi#Allocate({
+	\ 'black'          : 16,
+	\ 'white'          : 231,
+	\
+	\ 'darkestgreen'   : 22,
+	\ 'darkgreen'      : 28,
+	\ 'mediumgreen'    : 70,
+	\ 'brightgreen'    : 148,
+	\
+	\ 'darkestcyan'    : 23,
+	\ 'mediumcyan'     : 117,
+	\
+	\ 'darkestblue'    : 24,
+	\ 'darkblue'       : 31,
+	\
+	\ 'darkestred'     : 52,
+	\ 'darkred'        : 88,
+	\ 'mediumred'      : 124,
+	\ 'brightred'      : 160,
+	\ 'brightestred'   : 196,
+	\
+	\ 'darkestpurple'  : 55,
+	\ 'mediumpurple'   : 98,
+	\ 'brightpurple'   : 189,
+	\
+	\ 'brightorange'   : 208,
+	\ 'brightestorange': 214,
+	\
+	\ 'gray0'          : 233,
+	\ 'gray1'          : 235,
+	\ 'gray2'          : 236,
+	\ 'gray3'          : 239,
+	\ 'gray4'          : 240,
+	\ 'gray5'          : 241,
+	\ 'gray6'          : 244,
+	\ 'gray7'          : 245,
+	\ 'gray8'          : 247,
+	\ 'gray9'          : 250,
+	\ 'gray10'         : 252,
+	\
+	\ 'base03'         : [8, 0x002b36],
+	\ 'base02'         : [0, 0x073642],
+	\ 'base01'         : [10, 0x586e75],
+	\ 'base00'         : [11, 0x657b83],
+	\ 'base0'          : [12, 0x839496],
+	\ 'base1'          : [14, 0x93a1a1],
+	\ 'base2'          : [7, 0xeee8d5],
+	\ 'base3'          : [15, 0xfdf6e3],
+	\ 'yellow'         : [3, 0xb58900],
+	\ 'orange'         : [9, 0xcb4b16],
+	\ 'red'            : [1, 0xdc322f],
+	\ 'magenta'        : [5, 0xd33682],
+	\ 'violet'         : [13, 0x6c71c4],
+	\ 'blue'           : [4, 0x268bd2],
+	\ 'cyan'           : [6, 0x2aa198],
+	\ 'green'          : [2, 0x859900],
+	\ })
+
+let g:Powerline#Colorschemes#solarized16#colorscheme= Pl#Colorscheme#Init([
+	\ Pl#Hi#Segments(['SPLIT'], {
+		\ 'n': ['white', 'base02'],
+		\ 'N': ['white', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['mode_indicator'], {
+		\ 'n': ['darkestgreen', 'brightgreen', ['bold']],
+		\ 'i': ['darkestcyan', 'white', ['bold']],
+		\ 'v': ['red', 'brightorange', ['bold']],
+		\ 'r': ['white', 'violet', ['bold']],
+		\ 's': ['white', 'gray5', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['branch', 'raw', 'filesize'], {
+		\ 'n': ['base03', 'blue'],
+		\ 'N': ['base00', 'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo', 'filename', 'filepath'], {
+		\ 'n': ['base3', 'darkestblue', ['bold']],
+		\ 'N': ['base0', 'base02', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
+		\ 'n': ['base2'],
+		\ 'N': ['base00'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['static_str'], {
+		\ 'n': ['base3', 'violet'],
+		\ 'N': ['base1', 'base02'],
+		\ 'i': ['white', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
+		\ 'n': ['base03', ['bold']],
+		\ 'N': ['gray5'],
+		\ 'i': ['base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
+		\ 'n': ['base1', 'base02'],
+		\ 'N': ['base00', 'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['scrollpercent'], {
+		\ 'n': ['base1', 'base02', ['bold']],
+		\ 'N': ['base00', 'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo'], {
+		\ 'n': ['gray2', 'gray10', ['bold']],
+		\ 'N': ['gray7', 'gray1', ['bold']],
+		\ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['errors'], {
+		\ 'n': ['orange', 'base02', ['bold']],
+		\ 'N': ['gray5', 'base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
+		\ 'n': ['gray6'],
+		\ 'N': ['gray5'],
+		\ 'i': ['darkestcyan'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
+		\ 'n': ['base3', 'red', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
+		\ 'n': ['base3', 'darkblue', ['bold']],
+		\ 'N': ['base1', 'base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
+		\ 'n': ['white', 'base02'],
+		\ 'N': ['gray5', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
+		\ 'n': ['white', 'base02'],
+		\ 'N': ['white', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
+		\ 'n': ['base3', 'darkestblue', ['bold']],
+		\ 'N': ['base01', 'base02', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
+		\ 'n': ['base3', 'blue'],
+		\ 'N': ['gray5', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
+		\ 'n': ['gray3', 'base02'],
+		\ 'N': ['gray3', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
+		\ 'n': ['green', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next'], {
+		\ 'n': ['green', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:item', 'ctrlp:pwd'], {
+		\ 'n': ['base2', 'darkestblue', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
+		\ 'n': ['green', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:count'], {
+		\ 'n': ['base0', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
+		\ 'n': ['white', 'base02'],
+		\ }),
+  \
+  \ Pl#Hi#Segments(['status'], {
+		\ 'n': ['green', 'base02'],
+		\ 'N': ['gray5', 'base02'],
+    \ }),
+\ ])

File autoload/Powerline/Colorschemes/solarized256.vim

+" Authors:
+"   @skwp
+"
+" This colorscheme is based on Solarized-dark colors, combined
+" with Powerline native colors
+call Pl#Hi#Allocate({
+	\ 'black'          : 16,
+	\ 'white'          : 231,
+	\
+	\ 'darkestgreen'   : 22,
+	\ 'darkgreen'      : 28,
+	\ 'mediumgreen'    : 70,
+	\ 'brightgreen'    : 148,
+	\
+	\ 'darkestcyan'    : 23,
+	\ 'mediumcyan'     : 117,
+	\
+	\ 'darkestblue'    : 24,
+	\ 'darkblue'       : 31,
+	\
+	\ 'darkestred'     : 52,
+	\ 'darkred'        : 88,
+	\ 'mediumred'      : 124,
+	\ 'brightred'      : 160,
+	\ 'brightestred'   : 196,
+	\
+	\ 'darkestpurple'  : 55,
+	\ 'mediumpurple'   : 98,
+	\ 'brightpurple'   : 189,
+	\
+	\ 'brightorange'   : 208,
+	\ 'brightestorange': 214,
+	\
+	\ 'gray0'          : 233,
+	\ 'gray1'          : 235,
+	\ 'gray2'          : 236,
+	\ 'gray3'          : 239,
+	\ 'gray4'          : 240,
+	\ 'gray5'          : 241,
+	\ 'gray6'          : 244,
+	\ 'gray7'          : 245,
+	\ 'gray8'          : 247,
+	\ 'gray9'          : 250,
+	\ 'gray10'         : 252,
+	\
+	\ 'base03'         : [234, 0x002b36],
+	\ 'base02'         : [235, 0x073642],
+	\ 'base01'         : [240, 0x586e75],
+	\ 'base00'         : [241, 0x657b83],
+	\ 'base0'          : [244, 0x839496],
+	\ 'base1'          : [245, 0x93a1a1],
+	\ 'base2'          : [254, 0xeee8d5],
+	\ 'base3'          : [230, 0xfdf6e3],
+	\ 'yellow'         : [136, 0xb58900],
+	\ 'orange'         : [166, 0xcb4b16],
+	\ 'red'            : [160, 0xdc322f],
+	\ 'magenta'        : [125, 0xd33682],
+	\ 'violet'         : [61, 0x6c71c4],
+	\ 'blue'           : [33, 0x268bd2],
+	\ 'cyan'           : [37, 0x2aa198],
+	\ 'green'          : [64, 0x859900],
+	\ })
+
+let g:Powerline#Colorschemes#solarized256#colorscheme = Pl#Colorscheme#Init([
+	\ Pl#Hi#Segments(['SPLIT'], {
+		\ 'n': ['white', 'base02'],
+		\ 'N': ['white', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['mode_indicator'], {
+		\ 'n': ['darkestgreen', 'brightgreen', ['bold']],
+		\ 'i': ['darkestcyan', 'white', ['bold']],
+		\ 'v': ['red', 'brightorange', ['bold']],
+		\ 'r': ['white', 'violet', ['bold']],
+		\ 's': ['white', 'gray5', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['branch', 'raw', 'filesize'], {
+		\ 'n': ['base03', 'blue'],
+		\ 'N': ['gray5', 'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['scrollpercent'], {
+		\ 'n': ['gray7', 'gray2'],
+		\ 'N': ['base2', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo', 'filename', 'filepath'], {
+		\ 'n': ['base2', 'darkestblue', ['bold']],
+		\ 'N': ['base1', 'base02', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
+		\ 'n': ['gray10'],
+		\ 'N': ['gray5'],
+		\ 'i': ['mediumcyan'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['static_str'], {
+		\ 'n': ['base3', 'violet'],
+		\ 'N': ['base1', 'base02'],
+		\ 'i': ['white', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
+		\ 'n': ['base03', ['bold']],
+		\ 'N': ['gray5'],
+		\ 'i': ['base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
+		\ 'n': ['gray5', 'gray2'],
+		\ 'i': ['mediumcyan', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo'], {
+		\ 'n': ['gray2', 'gray10', ['bold']],
+		\ 'N': ['gray7', 'gray1', ['bold']],
+		\ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['errors'], {
+		\ 'n': ['orange', 'base02', ['bold']],
+		\ 'N': ['gray5', 'base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
+		\ 'n': ['gray6'],
+		\ 'N': ['gray5'],
+		\ 'i': ['darkestcyan'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
+		\ 'n': ['base3', 'red', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
+		\ 'n': ['base3', 'darkblue', ['bold']],
+		\ 'N': ['base1', 'base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
+		\ 'n': ['white', 'base02'],
+		\ 'N': ['gray5', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
+		\ 'n': ['white', 'base02'],
+		\ 'N': ['white', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
+		\ 'n': ['gray10', 'darkestblue', ['bold']],
+		\ 'N': ['gray3', 'base02', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
+		\ 'n': ['base3', 'blue'],
+		\ 'N': ['gray5', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
+		\ 'n': ['gray3', 'base02'],
+		\ 'N': ['gray3', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
+		\ 'n': ['green', 'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
+		\ 'n': ['green', 'base02'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:item'], {
+		\ 'n': ['base2', 'darkestblue', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
+		\ 'n': ['brightgreen', 'base03', ['bold']],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:count'], {
+		\ 'n': ['base0', 'base03'],
+		\ }),
+	\
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
+		\ 'n': ['white', 'base03'],
+		\ }),
+  \
+  \ Pl#Hi#Segments(['status'], {
+		\ 'n': ['green', 'base02'],
+		\ 'N': ['gray5', 'base02'],
+    \ }),
+\ ])

File autoload/Powerline/Functions.vim

+" Recalculate the trailing whitespace warning when idle, and after saving
+autocmd CursorHold,BufWritePost,InsertLeave * unlet! b:statusline_trailing_space_warning
+
+function! Powerline#Functions#GetFilepath() " {{{
+	" Recalculate the filepath when cwd changes.
+	let cwd = getcwd()
+	if exists("b:Powerline_cwd") && cwd != b:Powerline_cwd
+		unlet! b:Powerline_filepath
+	endif
+	let b:Powerline_cwd = cwd
+
+	if exists('b:Powerline_filepath')
+		return b:Powerline_filepath
+	endif
+
+	let dirsep = has('win32') && ! &shellslash ? '\' : '/'
+	let filepath = expand('%:p')
+
+	if empty(filepath)
+		return ''
+	endif
+
+	let ret = ''
+
+	if g:Powerline_stl_path_style == 'short'
+		" Display a short path where the first directory is displayed with its
+		" full name, and the subsequent directories are shortened to their
+		" first letter, i.e. "/home/user/foo/foo/bar/baz.vim" becomes
+		" "~/foo/f/b/baz.vim"
+		"
+		" This displays the shortest possible path, relative to ~ or the
+		" current directory.
+		let mod = (exists('+acd') && &acd) ? ':~:h' : ':~:.:h'
+		let fpath = split(fnamemodify(filepath, mod), dirsep)
+		let fpath_shortparts = map(fpath[1:], 'v:val[0]')
+		let ret = join(extend([fpath[0]], fpath_shortparts), dirsep) . dirsep
+	elseif g:Powerline_stl_path_style == 'relative'
+		" Display a relative path, similar to the %f statusline item
+		let ret = fnamemodify(filepath, ':~:.:h') . dirsep
+	elseif g:Powerline_stl_path_style == 'full'
+		" Display the full path, similar to the %F statusline item
+		let ret = fnamemodify(filepath, ':h') . dirsep
+	endif
+
+	if ret == ('.' . dirsep)
+		let ret = ''
+	endif
+
+	let b:Powerline_filepath = ret
+	return ret
+endfunction " }}}
+function! Powerline#Functions#GetShortPath(threshold) " {{{
+	let fullpath = split(expand('%:~'), '[/\\]')
+
+	if len(fullpath) > a:threshold