blob: 6d5bf4b80617e3c81e98d99696770cad175d2865 [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 Moolenaar071d4272004-06-13 20:20:40 +00006
7if exists("b:did_ftplugin")
8 finish
9endif
10let b:did_ftplugin = 1
11
Bram Moolenaarb6b046b2011-12-30 13:11:27 +010012let s:cpo_save = &cpo
13set cpo&vim
14
Bram Moolenaar071d4272004-06-13 20:20:40 +000015if !exists("no_plugin_maps") && !exists("no_spec_maps")
16 if !hasmapto("<Plug>SpecChangelog")
17 map <buffer> <LocalLeader>c <Plug>SpecChangelog
18 endif
19endif
20
Bram Moolenaar2b8388b2015-02-28 13:11:45 +010021if !hasmapto("call <SID>SpecChangelog(\"\")<CR>")
22 noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
23endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000024
Bram Moolenaarf2571c62015-06-09 19:44:55 +020025if !exists("*s:GetRelVer")
26 function! s:GetRelVer()
27 if has('python')
28python << PYEND
29import sys, datetime, shutil, tempfile
30import vim
31
32try:
33 import rpm
34except ImportError:
35 pass
36else:
37 specfile = vim.current.buffer.name
38 if specfile:
39 spec = rpm.spec(specfile)
40 headers = spec.packages[0].header
41 version = headers['Version']
42 release = ".".join(headers['Release'].split(".")[:-1])
43 vim.command("let ver = " + version)
44 vim.command("let rel = " + release)
45PYEND
46 endif
47 endfunction
48endif
49
Bram Moolenaar071d4272004-06-13 20:20:40 +000050if !exists("*s:SpecChangelog")
51 function s:SpecChangelog(format)
52 if strlen(a:format) == 0
53 if !exists("g:spec_chglog_format")
Bram Moolenaarf2571c62015-06-09 19:44:55 +020054 let email = input("Name <email address>: ")
Bram Moolenaar071d4272004-06-13 20:20:40 +000055 let g:spec_chglog_format = "%a %b %d %Y " . l:email
56 echo "\r"
57 endif
58 let format = g:spec_chglog_format
59 else
60 if !exists("g:spec_chglog_format")
61 let g:spec_chglog_format = a:format
62 endif
63 let format = a:format
64 endif
65 let line = 0
66 let name = ""
67 let ver = ""
68 let rel = ""
69 let nameline = -1
70 let verline = -1
71 let relline = -1
72 let chgline = -1
73 while (line <= line("$"))
74 let linestr = getline(line)
75 if (name == "" && linestr =~? '^Name:')
76 let nameline = line
77 let name = substitute(strpart(linestr,5), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
78 elseif (ver == "" && linestr =~? '^Version:')
79 let verline = line
80 let ver = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
81 elseif (rel == "" && linestr =~? '^Release:')
82 let relline = line
83 let rel = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
84 elseif (linestr =~? '^%changelog')
85 let chgline = line
86 execute line
87 break
88 endif
89 let line = line+1
90 endwhile
91 if (nameline != -1 && verline != -1 && relline != -1)
92 let include_release_info = exists("g:spec_chglog_release_info")
93 let name = s:ParseRpmVars(name, nameline)
94 let ver = s:ParseRpmVars(ver, verline)
95 let rel = s:ParseRpmVars(rel, relline)
96 else
97 let include_release_info = 0
98 endif
Bram Moolenaarf2571c62015-06-09 19:44:55 +020099
100 call s:GetRelVer()
101
Bram Moolenaar071d4272004-06-13 20:20:40 +0000102 if (chgline == -1)
103 let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
104 if (option == 1)
105 call append(line("$"),"")
106 call append(line("$"),"%changelog")
107 execute line("$")
108 let chgline = line(".")
109 elseif (option == 2)
110 call append(line("."),"%changelog")
111 normal j
112 chgline = line(".")
113 endif
114 endif
115 if (chgline != -1)
Bram Moolenaarf2571c62015-06-09 19:44:55 +0200116 let parsed_format = "* ".strftime(format)." - ".ver."-".rel
Bram Moolenaar071d4272004-06-13 20:20:40 +0000117 let release_info = "+ ".name."-".ver."-".rel
118 let wrong_format = 0
119 let wrong_release = 0
120 let insert_line = 0
121 if (getline(chgline+1) != parsed_format)
122 let wrong_format = 1
123 endif
124 if (include_release_info && getline(chgline+2) != release_info)
125 let wrong_release = 1
126 endif
127 if (wrong_format || wrong_release)
128 if (include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release"))
129 let option = confirm("Increase release? ","&Yes\n&No",1)
130 if (option == 1)
131 execute relline
132 normal 
133 let rel = substitute(strpart(getline(relline),8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
134 let release_info = "+ ".name."-".ver."-".rel
135 endif
136 endif
137 let n = 0
138 call append(chgline+n, parsed_format)
139 if include_release_info
140 let n = n + 1
141 call append(chgline+n, release_info)
142 endif
143 let n = n + 1
144 call append(chgline+n,"- ")
145 let n = n + 1
146 call append(chgline+n,"")
147 let insert_line = chgline+n
148 else
149 let line = chgline
150 if !exists("g:spec_chglog_prepend")
151 while !(getline(line+2) =~ '^\( *\|\*.*\)$')
152 let line = line+1
153 endwhile
154 endif
155 call append(line+1,"- ")
156 let insert_line = line+2
157 endif
158 execute insert_line
159 startinsert!
160 endif
161 endfunction
162endif
163
164if !exists("*s:ParseRpmVars")
165 function s:ParseRpmVars(str, strline)
166 let end = -1
167 let ret = ""
168 while (1)
169 let start = match(a:str, "\%{", end+1)
170 if (start == -1)
171 let ret = ret . strpart(a:str, end+1)
172 break
173 endif
174 let ret = ret . strpart(a:str, end+1, start-(end+1))
175 let end = match(a:str, "}", start)
176 if (end == -1)
177 let ret = ret . strpart(a:str, start)
178 break
179 endif
180 let varname = strpart(a:str, start+2, end-(start+2))
181 execute a:strline
182 let definestr = "^[ \t]*%define[ \t]\\+" . varname . "[ \t]\\+\\(.*\\)$"
183 let linenum = search(definestr, "bW")
Bram Moolenaar08589172014-03-08 18:38:28 +0100184 if (linenum == 0)
185 let definestr = substitute(definestr, "%define", "%global", "")
186 let linenum = search(definestr, "bW")
187 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000188 if (linenum != -1)
189 let ret = ret . substitute(getline(linenum), definestr, "\\1", "")
190 else
191 let ret = ret . strpart(str, start, end+1-start)
192 endif
193 endwhile
194 return ret
195 endfunction
196endif
197
198" The following lines, along with the macros/matchit.vim plugin,
199" make it easy to navigate the different sections of a spec file
200" with the % key (thanks to Max Ischenko).
201
202let b:match_ignorecase = 0
203let b:match_words =
204 \ '^Name:^%description:^%clean:^%setup:^%build:^%install:^%files:' .
205 \ '^%package:^%preun:^%postun:^%changelog'
206
Bram Moolenaarb6b046b2011-12-30 13:11:27 +0100207let &cpo = s:cpo_save
208unlet s:cpo_save
209
Bram Moolenaar84f72352012-03-11 15:57:40 +0100210let b:undo_ftplugin = "unlet! b:match_ignorecase b:match_words"