blob: 75eebec56a705a9c6e53daa54f83d55fa0aa3aa2 [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 Moolenaar6e649222021-10-04 21:32:54 +010021if !hasmapto("call SpecChangelog(\"\")<CR>")
22 noremap <buffer> <unique> <script> <Plug>SpecChangelog :call SpecChangelog("")<CR>
Bram Moolenaar2b8388b2015-02-28 13:11:45 +010023endif
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:
Bram Moolenaar82af8712016-06-04 20:20:29 +020039 rpm.delMacro("dist")
Bram Moolenaarf2571c62015-06-09 19:44:55 +020040 spec = rpm.spec(specfile)
Bram Moolenaar82af8712016-06-04 20:20:29 +020041 headers = spec.sourceHeader
42 version = headers["Version"]
43 release = headers["Release"]
Bram Moolenaarf2571c62015-06-09 19:44:55 +020044 vim.command("let ver = " + version)
45 vim.command("let rel = " + release)
46PYEND
47 endif
48 endfunction
49endif
50
Bram Moolenaar071d4272004-06-13 20:20:40 +000051if !exists("*s:SpecChangelog")
52 function s:SpecChangelog(format)
53 if strlen(a:format) == 0
54 if !exists("g:spec_chglog_format")
Bram Moolenaarf2571c62015-06-09 19:44:55 +020055 let email = input("Name <email address>: ")
Bram Moolenaar071d4272004-06-13 20:20:40 +000056 let g:spec_chglog_format = "%a %b %d %Y " . l:email
57 echo "\r"
58 endif
59 let format = g:spec_chglog_format
60 else
61 if !exists("g:spec_chglog_format")
62 let g:spec_chglog_format = a:format
63 endif
64 let format = a:format
65 endif
66 let line = 0
67 let name = ""
68 let ver = ""
69 let rel = ""
70 let nameline = -1
71 let verline = -1
72 let relline = -1
73 let chgline = -1
74 while (line <= line("$"))
75 let linestr = getline(line)
Bram Moolenaar4072ba52020-12-23 13:56:35 +010076 if name == "" && linestr =~? '^Name:'
Bram Moolenaar071d4272004-06-13 20:20:40 +000077 let nameline = line
78 let name = substitute(strpart(linestr,5), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
Bram Moolenaar4072ba52020-12-23 13:56:35 +010079 elseif ver == "" && linestr =~? '^Version:'
Bram Moolenaar071d4272004-06-13 20:20:40 +000080 let verline = line
81 let ver = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
Bram Moolenaar4072ba52020-12-23 13:56:35 +010082 elseif rel == "" && linestr =~? '^Release:'
Bram Moolenaar071d4272004-06-13 20:20:40 +000083 let relline = line
84 let rel = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
Bram Moolenaar4072ba52020-12-23 13:56:35 +010085 elseif linestr =~? '^%changelog'
Bram Moolenaar071d4272004-06-13 20:20:40 +000086 let chgline = line
87 execute line
88 break
89 endif
90 let line = line+1
91 endwhile
Bram Moolenaar4072ba52020-12-23 13:56:35 +010092 if nameline != -1 && verline != -1 && relline != -1
Bram Moolenaar071d4272004-06-13 20:20:40 +000093 let include_release_info = exists("g:spec_chglog_release_info")
94 let name = s:ParseRpmVars(name, nameline)
95 let ver = s:ParseRpmVars(ver, verline)
96 let rel = s:ParseRpmVars(rel, relline)
97 else
98 let include_release_info = 0
99 endif
Bram Moolenaarf2571c62015-06-09 19:44:55 +0200100
101 call s:GetRelVer()
102
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100103 if chgline == -1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000104 let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100105 if option == 1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000106 call append(line("$"),"")
107 call append(line("$"),"%changelog")
108 execute line("$")
109 let chgline = line(".")
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100110 elseif option == 2
Bram Moolenaar071d4272004-06-13 20:20:40 +0000111 call append(line("."),"%changelog")
112 normal j
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100113 let chgline = line(".")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000114 endif
115 endif
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100116 if chgline != -1
Bram Moolenaar82af8712016-06-04 20:20:29 +0200117 let tmptime = v:lc_time
118 language time C
Bram Moolenaarf2571c62015-06-09 19:44:55 +0200119 let parsed_format = "* ".strftime(format)." - ".ver."-".rel
Bram Moolenaar82af8712016-06-04 20:20:29 +0200120 execute "language time" tmptime
Bram Moolenaar071d4272004-06-13 20:20:40 +0000121 let release_info = "+ ".name."-".ver."-".rel
122 let wrong_format = 0
123 let wrong_release = 0
124 let insert_line = 0
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100125 if getline(chgline+1) != parsed_format
Bram Moolenaar071d4272004-06-13 20:20:40 +0000126 let wrong_format = 1
127 endif
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100128 if include_release_info && getline(chgline+2) != release_info
Bram Moolenaar071d4272004-06-13 20:20:40 +0000129 let wrong_release = 1
130 endif
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100131 if wrong_format || wrong_release
132 if include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000133 let option = confirm("Increase release? ","&Yes\n&No",1)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100134 if option == 1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000135 execute relline
136 normal 
137 let rel = substitute(strpart(getline(relline),8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')
138 let release_info = "+ ".name."-".ver."-".rel
139 endif
140 endif
141 let n = 0
142 call append(chgline+n, parsed_format)
143 if include_release_info
144 let n = n + 1
145 call append(chgline+n, release_info)
146 endif
147 let n = n + 1
148 call append(chgline+n,"- ")
149 let n = n + 1
150 call append(chgline+n,"")
151 let insert_line = chgline+n
152 else
153 let line = chgline
154 if !exists("g:spec_chglog_prepend")
155 while !(getline(line+2) =~ '^\( *\|\*.*\)$')
156 let line = line+1
157 endwhile
158 endif
159 call append(line+1,"- ")
160 let insert_line = line+2
161 endif
162 execute insert_line
163 startinsert!
164 endif
165 endfunction
166endif
167
168if !exists("*s:ParseRpmVars")
169 function s:ParseRpmVars(str, strline)
170 let end = -1
171 let ret = ""
172 while (1)
173 let start = match(a:str, "\%{", end+1)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100174 if start == -1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000175 let ret = ret . strpart(a:str, end+1)
176 break
177 endif
178 let ret = ret . strpart(a:str, end+1, start-(end+1))
179 let end = match(a:str, "}", start)
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100180 if end == -1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000181 let ret = ret . strpart(a:str, start)
182 break
183 endif
184 let varname = strpart(a:str, start+2, end-(start+2))
185 execute a:strline
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200186 let definestr = "^[ \t]*%\\(define\\|global\\)[ \t]\\+".varname."[ \t]\\+\\(.*\\)$"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000187 let linenum = search(definestr, "bW")
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100188 if linenum != 0
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200189 let ret = ret . substitute(getline(linenum), definestr, "\\2", "")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000190 endif
191 endwhile
192 return ret
193 endfunction
194endif
195
196" The following lines, along with the macros/matchit.vim plugin,
197" make it easy to navigate the different sections of a spec file
198" with the % key (thanks to Max Ischenko).
199
200let b:match_ignorecase = 0
201let b:match_words =
Bram Moolenaar82af8712016-06-04 20:20:29 +0200202 \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' .
Bram Moolenaar071d4272004-06-13 20:20:40 +0000203 \ '^%package:^%preun:^%postun:^%changelog'
204
Bram Moolenaarb6b046b2011-12-30 13:11:27 +0100205let &cpo = s:cpo_save
206unlet s:cpo_save
207
Bram Moolenaar84f72352012-03-11 15:57:40 +0100208let b:undo_ftplugin = "unlet! b:match_ignorecase b:match_words"