aboutsummaryrefslogtreecommitdiff
path: root/vim/autoload/Pl/Segment.vim
blob: 5ce68b9ac8a7bd3cd46d175ead03e5b3e3341eab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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 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
			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 " }}}