xref: /vim-8.2.3635/runtime/ftplugin/spec.vim (revision 113cb513)
1071d4279SBram Moolenaar" Plugin to update the %changelog section of RPM spec files
2071d4279SBram Moolenaar" Filename: spec.vim
30858917eSBram Moolenaar" Maintainer: Igor Gnatenko [email protected]
40858917eSBram Moolenaar" Former Maintainer: Gustavo Niemeyer <[email protected]> (until March 2014)
5f2571c61SBram Moolenaar" Last Change: Mon Jun 01 21:15 MSK 2015 Igor Gnatenko
6071d4279SBram Moolenaar
7071d4279SBram Moolenaarif exists("b:did_ftplugin")
8071d4279SBram Moolenaar	finish
9071d4279SBram Moolenaarendif
10071d4279SBram Moolenaarlet b:did_ftplugin = 1
11071d4279SBram Moolenaar
12b6b046b2SBram Moolenaarlet s:cpo_save = &cpo
13b6b046b2SBram Moolenaarset cpo&vim
14b6b046b2SBram Moolenaar
15071d4279SBram Moolenaarif !exists("no_plugin_maps") && !exists("no_spec_maps")
16071d4279SBram Moolenaar	if !hasmapto("<Plug>SpecChangelog")
17071d4279SBram Moolenaar		map <buffer> <LocalLeader>c <Plug>SpecChangelog
18071d4279SBram Moolenaar	endif
19071d4279SBram Moolenaarendif
20071d4279SBram Moolenaar
21*113cb513SBram Moolenaarif !hasmapto("call <SID>SpecChangelog(\"\")<CR>")
22*113cb513SBram Moolenaar       noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
232b8388bdSBram Moolenaarendif
24071d4279SBram Moolenaar
25f2571c61SBram Moolenaarif !exists("*s:GetRelVer")
26f2571c61SBram Moolenaar	function! s:GetRelVer()
27f2571c61SBram Moolenaar		if has('python')
28f2571c61SBram Moolenaarpython << PYEND
29f2571c61SBram Moolenaarimport sys, datetime, shutil, tempfile
30f2571c61SBram Moolenaarimport vim
31f2571c61SBram Moolenaar
32f2571c61SBram Moolenaartry:
33f2571c61SBram Moolenaar    import rpm
34f2571c61SBram Moolenaarexcept ImportError:
35f2571c61SBram Moolenaar    pass
36f2571c61SBram Moolenaarelse:
37f2571c61SBram Moolenaar    specfile = vim.current.buffer.name
38f2571c61SBram Moolenaar    if specfile:
3982af8710SBram Moolenaar        rpm.delMacro("dist")
40f2571c61SBram Moolenaar        spec = rpm.spec(specfile)
4182af8710SBram Moolenaar        headers = spec.sourceHeader
4282af8710SBram Moolenaar        version = headers["Version"]
4382af8710SBram Moolenaar        release = headers["Release"]
44f2571c61SBram Moolenaar        vim.command("let ver = " + version)
45f2571c61SBram Moolenaar        vim.command("let rel = " + release)
46f2571c61SBram MoolenaarPYEND
47f2571c61SBram Moolenaar		endif
48f2571c61SBram Moolenaar	endfunction
49f2571c61SBram Moolenaarendif
50f2571c61SBram Moolenaar
51071d4279SBram Moolenaarif !exists("*s:SpecChangelog")
52071d4279SBram Moolenaar	function s:SpecChangelog(format)
53071d4279SBram Moolenaar		if strlen(a:format) == 0
54071d4279SBram Moolenaar			if !exists("g:spec_chglog_format")
55f2571c61SBram Moolenaar				let email = input("Name <email address>: ")
56071d4279SBram Moolenaar				let g:spec_chglog_format = "%a %b %d %Y " . l:email
57071d4279SBram Moolenaar				echo "\r"
58071d4279SBram Moolenaar			endif
59071d4279SBram Moolenaar			let format = g:spec_chglog_format
60071d4279SBram Moolenaar		else
61071d4279SBram Moolenaar			if !exists("g:spec_chglog_format")
62071d4279SBram Moolenaar				let g:spec_chglog_format = a:format
63071d4279SBram Moolenaar			endif
64071d4279SBram Moolenaar			let format = a:format
65071d4279SBram Moolenaar		endif
66071d4279SBram Moolenaar		let line = 0
67071d4279SBram Moolenaar		let name = ""
68071d4279SBram Moolenaar		let ver = ""
69071d4279SBram Moolenaar		let rel = ""
70071d4279SBram Moolenaar		let nameline = -1
71071d4279SBram Moolenaar		let verline = -1
72071d4279SBram Moolenaar		let relline = -1
73071d4279SBram Moolenaar		let chgline = -1
74071d4279SBram Moolenaar		while (line <= line("$"))
75071d4279SBram Moolenaar			let linestr = getline(line)
764072ba57SBram Moolenaar			if name == "" && linestr =~? '^Name:'
77071d4279SBram Moolenaar				let nameline = line
78071d4279SBram Moolenaar				let name = substitute(strpart(linestr,5), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
794072ba57SBram Moolenaar			elseif ver == "" && linestr =~? '^Version:'
80071d4279SBram Moolenaar				let verline = line
81071d4279SBram Moolenaar				let ver = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
824072ba57SBram Moolenaar			elseif rel == "" && linestr =~? '^Release:'
83071d4279SBram Moolenaar				let relline = line
84071d4279SBram Moolenaar				let rel = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
854072ba57SBram Moolenaar			elseif linestr =~? '^%changelog'
86071d4279SBram Moolenaar				let chgline = line
87071d4279SBram Moolenaar				execute line
88071d4279SBram Moolenaar				break
89071d4279SBram Moolenaar			endif
90071d4279SBram Moolenaar			let line = line+1
91071d4279SBram Moolenaar		endwhile
924072ba57SBram Moolenaar		if nameline != -1 && verline != -1 && relline != -1
93071d4279SBram Moolenaar			let include_release_info = exists("g:spec_chglog_release_info")
94071d4279SBram Moolenaar			let name = s:ParseRpmVars(name, nameline)
95071d4279SBram Moolenaar			let ver = s:ParseRpmVars(ver, verline)
96071d4279SBram Moolenaar			let rel = s:ParseRpmVars(rel, relline)
97071d4279SBram Moolenaar		else
98071d4279SBram Moolenaar			let include_release_info = 0
99071d4279SBram Moolenaar		endif
100f2571c61SBram Moolenaar
101f2571c61SBram Moolenaar		call s:GetRelVer()
102f2571c61SBram Moolenaar
1034072ba57SBram Moolenaar		if chgline == -1
104071d4279SBram Moolenaar			let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
1054072ba57SBram Moolenaar			if option == 1
106071d4279SBram Moolenaar				call append(line("$"),"")
107071d4279SBram Moolenaar				call append(line("$"),"%changelog")
108071d4279SBram Moolenaar				execute line("$")
109071d4279SBram Moolenaar				let chgline = line(".")
1104072ba57SBram Moolenaar			elseif option == 2
111071d4279SBram Moolenaar				call append(line("."),"%changelog")
112071d4279SBram Moolenaar				normal j
1134072ba57SBram Moolenaar				let chgline = line(".")
114071d4279SBram Moolenaar			endif
115071d4279SBram Moolenaar		endif
1164072ba57SBram Moolenaar		if chgline != -1
11782af8710SBram Moolenaar			let tmptime = v:lc_time
11882af8710SBram Moolenaar			language time C
119f2571c61SBram Moolenaar			let parsed_format = "* ".strftime(format)." - ".ver."-".rel
12082af8710SBram Moolenaar			execute "language time" tmptime
121071d4279SBram Moolenaar			let release_info = "+ ".name."-".ver."-".rel
122071d4279SBram Moolenaar			let wrong_format = 0
123071d4279SBram Moolenaar			let wrong_release = 0
124071d4279SBram Moolenaar			let insert_line = 0
1254072ba57SBram Moolenaar			if getline(chgline+1) != parsed_format
126071d4279SBram Moolenaar				let wrong_format = 1
127071d4279SBram Moolenaar			endif
1284072ba57SBram Moolenaar			if include_release_info && getline(chgline+2) != release_info
129071d4279SBram Moolenaar				let wrong_release = 1
130071d4279SBram Moolenaar			endif
1314072ba57SBram Moolenaar			if wrong_format || wrong_release
1324072ba57SBram Moolenaar				if include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release")
133071d4279SBram Moolenaar					let option = confirm("Increase release? ","&Yes\n&No",1)
1344072ba57SBram Moolenaar					if option == 1
135071d4279SBram Moolenaar						execute relline
136071d4279SBram Moolenaar						normal 
137071d4279SBram Moolenaar						let rel = substitute(strpart(getline(relline),8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
138071d4279SBram Moolenaar						let release_info = "+ ".name."-".ver."-".rel
139071d4279SBram Moolenaar					endif
140071d4279SBram Moolenaar				endif
141071d4279SBram Moolenaar				let n = 0
142071d4279SBram Moolenaar				call append(chgline+n, parsed_format)
143071d4279SBram Moolenaar				if include_release_info
144071d4279SBram Moolenaar					let n = n + 1
145071d4279SBram Moolenaar					call append(chgline+n, release_info)
146071d4279SBram Moolenaar				endif
147071d4279SBram Moolenaar				let n = n + 1
148071d4279SBram Moolenaar				call append(chgline+n,"- ")
149071d4279SBram Moolenaar				let n = n + 1
150071d4279SBram Moolenaar				call append(chgline+n,"")
151071d4279SBram Moolenaar				let insert_line = chgline+n
152071d4279SBram Moolenaar			else
153071d4279SBram Moolenaar				let line = chgline
154071d4279SBram Moolenaar				if !exists("g:spec_chglog_prepend")
155071d4279SBram Moolenaar					while !(getline(line+2) =~ '^\( *\|\*.*\)$')
156071d4279SBram Moolenaar						let line = line+1
157071d4279SBram Moolenaar					endwhile
158071d4279SBram Moolenaar				endif
159071d4279SBram Moolenaar				call append(line+1,"- ")
160071d4279SBram Moolenaar				let insert_line = line+2
161071d4279SBram Moolenaar			endif
162071d4279SBram Moolenaar			execute insert_line
163071d4279SBram Moolenaar			startinsert!
164071d4279SBram Moolenaar		endif
165071d4279SBram Moolenaar	endfunction
166071d4279SBram Moolenaarendif
167071d4279SBram Moolenaar
168071d4279SBram Moolenaarif !exists("*s:ParseRpmVars")
169071d4279SBram Moolenaar    function s:ParseRpmVars(str, strline)
170071d4279SBram Moolenaar	let end = -1
171071d4279SBram Moolenaar	let ret = ""
172071d4279SBram Moolenaar	while (1)
173071d4279SBram Moolenaar		let start = match(a:str, "\%{", end+1)
1744072ba57SBram Moolenaar		if start == -1
175071d4279SBram Moolenaar			let ret = ret . strpart(a:str, end+1)
176071d4279SBram Moolenaar			break
177071d4279SBram Moolenaar		endif
178071d4279SBram Moolenaar		let ret = ret . strpart(a:str, end+1, start-(end+1))
179071d4279SBram Moolenaar		let end = match(a:str, "}", start)
1804072ba57SBram Moolenaar		if end == -1
181071d4279SBram Moolenaar			let ret = ret . strpart(a:str, start)
182071d4279SBram Moolenaar			break
183071d4279SBram Moolenaar		endif
184071d4279SBram Moolenaar		let varname = strpart(a:str, start+2, end-(start+2))
185071d4279SBram Moolenaar		execute a:strline
1861c6737b2SBram Moolenaar		let definestr = "^[ \t]*%\\(define\\|global\\)[ \t]\\+".varname."[ \t]\\+\\(.*\\)$"
187071d4279SBram Moolenaar		let linenum = search(definestr, "bW")
1884072ba57SBram Moolenaar		if linenum != 0
1891c6737b2SBram Moolenaar			let ret = ret .  substitute(getline(linenum), definestr, "\\2", "")
190071d4279SBram Moolenaar		endif
191071d4279SBram Moolenaar	endwhile
192071d4279SBram Moolenaar	return ret
193071d4279SBram Moolenaar    endfunction
194071d4279SBram Moolenaarendif
195071d4279SBram Moolenaar
196071d4279SBram Moolenaar" The following lines, along with the macros/matchit.vim plugin,
197071d4279SBram Moolenaar" make it easy to navigate the different sections of a spec file
198071d4279SBram Moolenaar" with the % key (thanks to Max Ischenko).
199071d4279SBram Moolenaar
200071d4279SBram Moolenaarlet b:match_ignorecase = 0
201071d4279SBram Moolenaarlet b:match_words =
20282af8710SBram Moolenaar  \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' .
203071d4279SBram Moolenaar  \ '^%package:^%preun:^%postun:^%changelog'
204071d4279SBram Moolenaar
205b6b046b2SBram Moolenaarlet &cpo = s:cpo_save
206b6b046b2SBram Moolenaarunlet s:cpo_save
207b6b046b2SBram Moolenaar
20884f7235bSBram Moolenaarlet b:undo_ftplugin = "unlet! b:match_ignorecase b:match_words"
209