xref: /vim-8.2.3635/runtime/ftplugin/spec.vim (revision 2b8388bd)
1" Plugin to update the %changelog section of RPM spec files
2" Filename: spec.vim
3" Maintainer: Igor Gnatenko [email protected]
4" Former Maintainer: Gustavo Niemeyer <[email protected]> (until March 2014)
5" Last Change: Fri Feb 20 16:01 MSK 2014 Igor Gnatenko
6
7if exists("b:did_ftplugin")
8	finish
9endif
10let b:did_ftplugin = 1
11
12let s:cpo_save = &cpo
13set cpo&vim
14
15if !exists("no_plugin_maps") && !exists("no_spec_maps")
16	if !hasmapto("<Plug>SpecChangelog")
17		map <buffer> <LocalLeader>c <Plug>SpecChangelog
18	endif
19endif
20
21if !hasmapto("call <SID>SpecChangelog(\"\")<CR>")
22       noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
23endif
24
25if !exists("*s:SpecChangelog")
26	function s:SpecChangelog(format)
27		if strlen(a:format) == 0
28			if !exists("g:spec_chglog_format")
29				let email = input("Email address: ")
30				let g:spec_chglog_format = "%a %b %d %Y " . l:email
31				echo "\r"
32			endif
33			let format = g:spec_chglog_format
34		else
35			if !exists("g:spec_chglog_format")
36				let g:spec_chglog_format = a:format
37			endif
38			let format = a:format
39		endif
40		let line = 0
41		let name = ""
42		let ver = ""
43		let rel = ""
44		let nameline = -1
45		let verline = -1
46		let relline = -1
47		let chgline = -1
48		while (line <= line("$"))
49			let linestr = getline(line)
50			if (name == "" && linestr =~? '^Name:')
51				let nameline = line
52				let name = substitute(strpart(linestr,5), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
53			elseif (ver == "" && linestr =~? '^Version:')
54				let verline = line
55				let ver = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
56			elseif (rel == "" && linestr =~? '^Release:')
57				let relline = line
58				let rel = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
59			elseif (linestr =~? '^%changelog')
60				let chgline = line
61				execute line
62				break
63			endif
64			let line = line+1
65		endwhile
66		if (nameline != -1 && verline != -1 && relline != -1)
67			let include_release_info = exists("g:spec_chglog_release_info")
68			let name = s:ParseRpmVars(name, nameline)
69			let ver = s:ParseRpmVars(ver, verline)
70			let rel = s:ParseRpmVars(rel, relline)
71		else
72			let include_release_info = 0
73		endif
74		if (chgline == -1)
75			let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
76			if (option == 1)
77				call append(line("$"),"")
78				call append(line("$"),"%changelog")
79				execute line("$")
80				let chgline = line(".")
81			elseif (option == 2)
82				call append(line("."),"%changelog")
83				normal j
84				chgline = line(".")
85			endif
86		endif
87		if (chgline != -1)
88			let parsed_format = "* ".strftime(format)
89			let release_info = "+ ".name."-".ver."-".rel
90			let wrong_format = 0
91			let wrong_release = 0
92			let insert_line = 0
93			if (getline(chgline+1) != parsed_format)
94				let wrong_format = 1
95			endif
96			if (include_release_info && getline(chgline+2) != release_info)
97				let wrong_release = 1
98			endif
99			if (wrong_format || wrong_release)
100				if (include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release"))
101					let option = confirm("Increase release? ","&Yes\n&No",1)
102					if (option == 1)
103						execute relline
104						normal 
105						let rel = substitute(strpart(getline(relline),8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
106						let release_info = "+ ".name."-".ver."-".rel
107					endif
108				endif
109				let n = 0
110				call append(chgline+n, parsed_format)
111				if include_release_info
112					let n = n + 1
113					call append(chgline+n, release_info)
114				endif
115				let n = n + 1
116				call append(chgline+n,"- ")
117				let n = n + 1
118				call append(chgline+n,"")
119				let insert_line = chgline+n
120			else
121				let line = chgline
122				if !exists("g:spec_chglog_prepend")
123					while !(getline(line+2) =~ '^\( *\|\*.*\)$')
124						let line = line+1
125					endwhile
126				endif
127				call append(line+1,"- ")
128				let insert_line = line+2
129			endif
130			execute insert_line
131			startinsert!
132		endif
133	endfunction
134endif
135
136if !exists("*s:ParseRpmVars")
137    function s:ParseRpmVars(str, strline)
138	let end = -1
139	let ret = ""
140	while (1)
141		let start = match(a:str, "\%{", end+1)
142		if (start == -1)
143			let ret = ret . strpart(a:str, end+1)
144			break
145		endif
146		let ret = ret . strpart(a:str, end+1, start-(end+1))
147		let end = match(a:str, "}", start)
148		if (end == -1)
149			let ret = ret . strpart(a:str, start)
150			break
151		endif
152		let varname = strpart(a:str, start+2, end-(start+2))
153		execute a:strline
154		let definestr = "^[ \t]*%define[ \t]\\+" . varname . "[ \t]\\+\\(.*\\)$"
155		let linenum = search(definestr, "bW")
156		if (linenum == 0)
157			let definestr = substitute(definestr, "%define", "%global", "")
158			let linenum = search(definestr, "bW")
159		endif
160		if (linenum != -1)
161			let ret = ret .  substitute(getline(linenum), definestr, "\\1", "")
162		else
163			let ret = ret . strpart(str, start, end+1-start)
164		endif
165	endwhile
166	return ret
167    endfunction
168endif
169
170" The following lines, along with the macros/matchit.vim plugin,
171" make it easy to navigate the different sections of a spec file
172" with the % key (thanks to Max Ischenko).
173
174let b:match_ignorecase = 0
175let b:match_words =
176  \ '^Name:^%description:^%clean:^%setup:^%build:^%install:^%files:' .
177  \ '^%package:^%preun:^%postun:^%changelog'
178
179let &cpo = s:cpo_save
180unlet s:cpo_save
181
182let b:undo_ftplugin = "unlet! b:match_ignorecase b:match_words"
183