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