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