blob: 9040e19ce10f2e0b49fd57d4d63efb7bae1d5ecb [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Plugin to update the %changelog section of RPM spec files
2" Filename: spec.vim
Bram Moolenaar08589172014-03-08 18:38:28 +01003" Maintainer: Igor Gnatenko i.gnatenko.brain@gmail.com
4" Former Maintainer: Gustavo Niemeyer <niemeyer@conectiva.com> (until March 2014)
Bram Moolenaarf2571c62015-06-09 19:44:55 +02005" Last Change: Mon Jun 01 21:15 MSK 2015 Igor Gnatenko
Bram Moolenaar2d8ed022022-05-21 13:08:16 +01006" Update by Zdenek Dohnal, 2022 May 17
Bram Moolenaar071d4272004-06-13 20:20:40 +00007
8if exists("b:did_ftplugin")
9 finish
10endif
11let b:did_ftplugin = 1
12
Bram Moolenaarb6b046b2011-12-30 13:11:27 +010013let s:cpo_save = &cpo
14set cpo&vim
15
Bram Moolenaar071d4272004-06-13 20:20:40 +000016if !exists("no_plugin_maps") && !exists("no_spec_maps")
17 if !hasmapto("<Plug>SpecChangelog")
18 map <buffer> <LocalLeader>c <Plug>SpecChangelog
19 endif
20endif
21
Bram Moolenaar113cb512021-11-07 20:27:04 +000022if !hasmapto("call <SID>SpecChangelog(\"\")<CR>")
23 noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
Bram Moolenaar2b8388b2015-02-28 13:11:45 +010024endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000025
Bram Moolenaarf2571c62015-06-09 19:44:55 +020026if !exists("*s:GetRelVer")
27 function! s:GetRelVer()
28 if has('python')
29python << PYEND
30import sys, datetime, shutil, tempfile
31import vim
32
33try:
34 import rpm
35except ImportError:
36 pass
37else:
38 specfile = vim.current.buffer.name
39 if specfile:
Bram Moolenaar82af8712016-06-04 20:20:29 +020040 rpm.delMacro("dist")
Bram Moolenaarf2571c62015-06-09 19:44:55 +020041 spec = rpm.spec(specfile)
Bram Moolenaar82af8712016-06-04 20:20:29 +020042 headers = spec.sourceHeader
43 version = headers["Version"]
44 release = headers["Release"]
Bram Moolenaar2d8ed022022-05-21 13:08:16 +010045 vim.command("let ver = '" + version + "'")
46 vim.command("let rel = '" + release + "'")
Bram Moolenaarf2571c62015-06-09 19:44:55 +020047PYEND
48 endif
49 endfunction
50endif
51
Bram Moolenaar071d4272004-06-13 20:20:40 +000052if !exists("*s:SpecChangelog")
53 function s:SpecChangelog(format)
54 if strlen(a:format) == 0
55 if !exists("g:spec_chglog_format")
Bram Moolenaarf2571c62015-06-09 19:44:55 +020056 let email = input("Name <email address>: ")
Bram Moolenaar071d4272004-06-13 20:20:40 +000057 let g:spec_chglog_format = "%a %b %d %Y " . l:email
58 echo "\r"
59 endif
60 let format = g:spec_chglog_format
61 else
62 if !exists("g:spec_chglog_format")
63 let g:spec_chglog_format = a:format
64 endif
65 let format = a:format
66 endif
67 let line = 0
68 let name = ""
69 let ver = ""
70 let rel = ""
71 let nameline = -1
72 let verline = -1
73 let relline = -1
74 let chgline = -1
75 while (line <= line("$"))
76 let linestr = getline(line)
Bram Moolenaar4072ba52020-12-23 13:56:35 +010077 if name == "" && linestr =~? '^Name:'
Bram Moolenaar071d4272004-06-13 20:20:40 +000078 let nameline = line
79 let name = substitute(strpart(linestr,5), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
Bram Moolenaar4072ba52020-12-23 13:56:35 +010080 elseif ver == "" && linestr =~? '^Version:'
Bram Moolenaar071d4272004-06-13 20:20:40 +000081 let verline = line
82 let ver = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
Bram Moolenaar4072ba52020-12-23 13:56:35 +010083 elseif rel == "" && linestr =~? '^Release:'
Bram Moolenaar071d4272004-06-13 20:20:40 +000084 let relline = line
85 let rel = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
Bram Moolenaar4072ba52020-12-23 13:56:35 +010086 elseif linestr =~? '^%changelog'
Bram Moolenaar071d4272004-06-13 20:20:40 +000087 let chgline = line
88 execute line
89 break
90 endif
91 let line = line+1
92 endwhile
Bram Moolenaar4072ba52020-12-23 13:56:35 +010093 if nameline != -1 && verline != -1 && relline != -1
Bram Moolenaar071d4272004-06-13 20:20:40 +000094 let include_release_info = exists("g:spec_chglog_release_info")
95 let name = s:ParseRpmVars(name, nameline)
96 let ver = s:ParseRpmVars(ver, verline)
97 let rel = s:ParseRpmVars(rel, relline)
98 else
99 let include_release_info = 0
100 endif
Bram Moolenaarf2571c62015-06-09 19:44:55 +0200101
102 call s:GetRelVer()
103
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100104 if chgline == -1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000105 let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100106 if option == 1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000107 call append(line("$"),"")
108 call append(line("$"),"%changelog")
109 execute line("$")
110 let chgline = line(".")
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100111 elseif option == 2
Bram Moolenaar071d4272004-06-13 20:20:40 +0000112 call append(line("."),"%changelog")
113 normal j
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100114 let chgline = line(".")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000115 endif
116 endif
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100117 if chgline != -1
Bram Moolenaar82af8712016-06-04 20:20:29 +0200118 let tmptime = v:lc_time
119 language time C
Bram Moolenaarf2571c62015-06-09 19:44:55 +0200120 let parsed_format = "* ".strftime(format)." - ".ver."-".rel
Bram Moolenaar82af8712016-06-04 20:20:29 +0200121 execute "language time" tmptime
Bram Moolenaar071d4272004-06-13 20:20:40 +0000122 let release_info = "+ ".name."-".ver."-".rel
123 let wrong_format = 0
124 let wrong_release = 0
125 let insert_line = 0
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100126 if getline(chgline+1) != parsed_format
Bram Moolenaar071d4272004-06-13 20:20:40 +0000127 let wrong_format = 1
128 endif
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100129 if include_release_info && getline(chgline+2) != release_info
Bram Moolenaar071d4272004-06-13 20:20:40 +0000130 let wrong_release = 1
131 endif
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100132 if wrong_format || wrong_release
133 if include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000134 let option = confirm("Increase release? ","&Yes\n&No",1)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100135 if option == 1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000136 execute relline
137 normal 
138 let rel = substitute(strpart(getline(relline),8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
139 let release_info = "+ ".name."-".ver."-".rel
140 endif
141 endif
142 let n = 0
143 call append(chgline+n, parsed_format)
144 if include_release_info
145 let n = n + 1
146 call append(chgline+n, release_info)
147 endif
148 let n = n + 1
149 call append(chgline+n,"- ")
150 let n = n + 1
151 call append(chgline+n,"")
152 let insert_line = chgline+n
153 else
154 let line = chgline
155 if !exists("g:spec_chglog_prepend")
156 while !(getline(line+2) =~ '^\( *\|\*.*\)$')
157 let line = line+1
158 endwhile
159 endif
160 call append(line+1,"- ")
161 let insert_line = line+2
162 endif
163 execute insert_line
164 startinsert!
165 endif
166 endfunction
167endif
168
169if !exists("*s:ParseRpmVars")
170 function s:ParseRpmVars(str, strline)
171 let end = -1
172 let ret = ""
173 while (1)
174 let start = match(a:str, "\%{", end+1)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100175 if start == -1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000176 let ret = ret . strpart(a:str, end+1)
177 break
178 endif
179 let ret = ret . strpart(a:str, end+1, start-(end+1))
180 let end = match(a:str, "}", start)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100181 if end == -1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000182 let ret = ret . strpart(a:str, start)
183 break
184 endif
185 let varname = strpart(a:str, start+2, end-(start+2))
186 execute a:strline
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200187 let definestr = "^[ \t]*%\\(define\\|global\\)[ \t]\\+".varname."[ \t]\\+\\(.*\\)$"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000188 let linenum = search(definestr, "bW")
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100189 if linenum != 0
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200190 let ret = ret . substitute(getline(linenum), definestr, "\\2", "")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000191 endif
192 endwhile
193 return ret
194 endfunction
195endif
196
197" The following lines, along with the macros/matchit.vim plugin,
198" make it easy to navigate the different sections of a spec file
199" with the % key (thanks to Max Ischenko).
200
201let b:match_ignorecase = 0
202let b:match_words =
Bram Moolenaar82af8712016-06-04 20:20:29 +0200203 \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' .
Bram Moolenaar071d4272004-06-13 20:20:40 +0000204 \ '^%package:^%preun:^%postun:^%changelog'
205
Bram Moolenaarb6b046b2011-12-30 13:11:27 +0100206let &cpo = s:cpo_save
207unlet s:cpo_save
208
Bram Moolenaar84f72352012-03-11 15:57:40 +0100209let b:undo_ftplugin = "unlet! b:match_ignorecase b:match_words"