Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 1 | " Plugin to update the %changelog section of RPM spec files |
| 2 | " Filename: spec.vim |
Bram Moolenaar | 0858917 | 2014-03-08 18:38:28 +0100 | [diff] [blame] | 3 | " Maintainer: Igor Gnatenko i.gnatenko.brain@gmail.com |
| 4 | " Former Maintainer: Gustavo Niemeyer <niemeyer@conectiva.com> (until March 2014) |
fundawang | e401576 | 2024-09-10 21:43:05 +0200 | [diff] [blame] | 5 | " Last Change: 2015 Jun 01 |
| 6 | " Update by Zdenek Dohnal, 2022 May 17 |
| 7 | " 2024 Sep 10 by Vim Project: add epoch support for spec changelog, #15537 |
Andreas Schneider | 4f51f3a | 2024-10-07 21:02:10 +0200 | [diff] [blame] | 8 | " 2024 Oct 07 by Vim Project: add comment support, #15817 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 9 | |
| 10 | if exists("b:did_ftplugin") |
| 11 | finish |
| 12 | endif |
| 13 | let b:did_ftplugin = 1 |
| 14 | |
Bram Moolenaar | b6b046b | 2011-12-30 13:11:27 +0100 | [diff] [blame] | 15 | let s:cpo_save = &cpo |
| 16 | set cpo&vim |
| 17 | |
Andreas Schneider | 4f51f3a | 2024-10-07 21:02:10 +0200 | [diff] [blame] | 18 | setlocal comments=b:# |
| 19 | setlocal commentstring=#\ %s |
| 20 | |
| 21 | let b:undo_ftplugin = "setlocal comments< commentstring<" |
| 22 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 23 | if !exists("no_plugin_maps") && !exists("no_spec_maps") |
| 24 | if !hasmapto("<Plug>SpecChangelog") |
| 25 | map <buffer> <LocalLeader>c <Plug>SpecChangelog |
| 26 | endif |
| 27 | endif |
| 28 | |
Bram Moolenaar | 113cb51 | 2021-11-07 20:27:04 +0000 | [diff] [blame] | 29 | if !hasmapto("call <SID>SpecChangelog(\"\")<CR>") |
| 30 | noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR> |
Bram Moolenaar | 2b8388b | 2015-02-28 13:11:45 +0100 | [diff] [blame] | 31 | endif |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 32 | |
Bram Moolenaar | f2571c6 | 2015-06-09 19:44:55 +0200 | [diff] [blame] | 33 | if !exists("*s:GetRelVer") |
| 34 | function! s:GetRelVer() |
| 35 | if has('python') |
| 36 | python << PYEND |
| 37 | import sys, datetime, shutil, tempfile |
| 38 | import vim |
| 39 | |
| 40 | try: |
| 41 | import rpm |
| 42 | except ImportError: |
| 43 | pass |
| 44 | else: |
| 45 | specfile = vim.current.buffer.name |
| 46 | if specfile: |
Bram Moolenaar | 82af871 | 2016-06-04 20:20:29 +0200 | [diff] [blame] | 47 | rpm.delMacro("dist") |
Bram Moolenaar | f2571c6 | 2015-06-09 19:44:55 +0200 | [diff] [blame] | 48 | spec = rpm.spec(specfile) |
Bram Moolenaar | 82af871 | 2016-06-04 20:20:29 +0200 | [diff] [blame] | 49 | headers = spec.sourceHeader |
| 50 | version = headers["Version"] |
| 51 | release = headers["Release"] |
Bram Moolenaar | 2d8ed02 | 2022-05-21 13:08:16 +0100 | [diff] [blame] | 52 | vim.command("let ver = '" + version + "'") |
| 53 | vim.command("let rel = '" + release + "'") |
Bram Moolenaar | f2571c6 | 2015-06-09 19:44:55 +0200 | [diff] [blame] | 54 | PYEND |
| 55 | endif |
| 56 | endfunction |
| 57 | endif |
| 58 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 59 | if !exists("*s:SpecChangelog") |
| 60 | function s:SpecChangelog(format) |
| 61 | if strlen(a:format) == 0 |
| 62 | if !exists("g:spec_chglog_format") |
Bram Moolenaar | f2571c6 | 2015-06-09 19:44:55 +0200 | [diff] [blame] | 63 | let email = input("Name <email address>: ") |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 64 | let g:spec_chglog_format = "%a %b %d %Y " . l:email |
| 65 | echo "\r" |
| 66 | endif |
| 67 | let format = g:spec_chglog_format |
| 68 | else |
| 69 | if !exists("g:spec_chglog_format") |
| 70 | let g:spec_chglog_format = a:format |
| 71 | endif |
| 72 | let format = a:format |
| 73 | endif |
| 74 | let line = 0 |
| 75 | let name = "" |
fundawang | e401576 | 2024-09-10 21:43:05 +0200 | [diff] [blame] | 76 | let epoch = "" |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 77 | let ver = "" |
| 78 | let rel = "" |
| 79 | let nameline = -1 |
fundawang | e401576 | 2024-09-10 21:43:05 +0200 | [diff] [blame] | 80 | let epochline = -1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 81 | let verline = -1 |
| 82 | let relline = -1 |
| 83 | let chgline = -1 |
| 84 | while (line <= line("$")) |
| 85 | let linestr = getline(line) |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 86 | if name == "" && linestr =~? '^Name:' |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 87 | let nameline = line |
| 88 | let name = substitute(strpart(linestr,5), '^[ ]*\([^ ]\+\)[ ]*$','\1','') |
fundawang | e401576 | 2024-09-10 21:43:05 +0200 | [diff] [blame] | 89 | elseif epoch == "" && linestr =~? '^Epoch:' |
| 90 | let epochline = line |
| 91 | let epoch = substitute(strpart(linestr,6), '^[ ]*\([^ ]\+\)[ ]*$','\1','') |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 92 | elseif ver == "" && linestr =~? '^Version:' |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 93 | let verline = line |
| 94 | let ver = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','') |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 95 | elseif rel == "" && linestr =~? '^Release:' |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 96 | let relline = line |
| 97 | let rel = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','') |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 98 | elseif linestr =~? '^%changelog' |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 99 | let chgline = line |
| 100 | execute line |
| 101 | break |
| 102 | endif |
| 103 | let line = line+1 |
| 104 | endwhile |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 105 | if nameline != -1 && verline != -1 && relline != -1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 106 | let include_release_info = exists("g:spec_chglog_release_info") |
| 107 | let name = s:ParseRpmVars(name, nameline) |
fundawang | e401576 | 2024-09-10 21:43:05 +0200 | [diff] [blame] | 108 | let epoch = s:ParseRpmVars(epoch, epochline) |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 109 | let ver = s:ParseRpmVars(ver, verline) |
| 110 | let rel = s:ParseRpmVars(rel, relline) |
| 111 | else |
| 112 | let include_release_info = 0 |
| 113 | endif |
Bram Moolenaar | f2571c6 | 2015-06-09 19:44:55 +0200 | [diff] [blame] | 114 | |
| 115 | call s:GetRelVer() |
| 116 | |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 117 | if chgline == -1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 118 | let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3) |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 119 | if option == 1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 120 | call append(line("$"),"") |
| 121 | call append(line("$"),"%changelog") |
| 122 | execute line("$") |
| 123 | let chgline = line(".") |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 124 | elseif option == 2 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 125 | call append(line("."),"%changelog") |
| 126 | normal j |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 127 | let chgline = line(".") |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 128 | endif |
| 129 | endif |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 130 | if chgline != -1 |
Bram Moolenaar | 82af871 | 2016-06-04 20:20:29 +0200 | [diff] [blame] | 131 | let tmptime = v:lc_time |
| 132 | language time C |
fundawang | e401576 | 2024-09-10 21:43:05 +0200 | [diff] [blame] | 133 | if strlen(epoch) |
| 134 | let ver = epoch.":".ver |
| 135 | endif |
Bram Moolenaar | f2571c6 | 2015-06-09 19:44:55 +0200 | [diff] [blame] | 136 | let parsed_format = "* ".strftime(format)." - ".ver."-".rel |
Bram Moolenaar | 82af871 | 2016-06-04 20:20:29 +0200 | [diff] [blame] | 137 | execute "language time" tmptime |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 138 | let release_info = "+ ".name."-".ver."-".rel |
| 139 | let wrong_format = 0 |
| 140 | let wrong_release = 0 |
| 141 | let insert_line = 0 |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 142 | if getline(chgline+1) != parsed_format |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 143 | let wrong_format = 1 |
| 144 | endif |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 145 | if include_release_info && getline(chgline+2) != release_info |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 146 | let wrong_release = 1 |
| 147 | endif |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 148 | if wrong_format || wrong_release |
| 149 | if include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release") |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 150 | let option = confirm("Increase release? ","&Yes\n&No",1) |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 151 | if option == 1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 152 | execute relline |
| 153 | normal |
| 154 | let rel = substitute(strpart(getline(relline),8), '^[ ]*\([^ ]\+\)[ ]*$','\1','') |
| 155 | let release_info = "+ ".name."-".ver."-".rel |
| 156 | endif |
| 157 | endif |
| 158 | let n = 0 |
| 159 | call append(chgline+n, parsed_format) |
| 160 | if include_release_info |
| 161 | let n = n + 1 |
| 162 | call append(chgline+n, release_info) |
| 163 | endif |
| 164 | let n = n + 1 |
| 165 | call append(chgline+n,"- ") |
| 166 | let n = n + 1 |
| 167 | call append(chgline+n,"") |
| 168 | let insert_line = chgline+n |
| 169 | else |
| 170 | let line = chgline |
| 171 | if !exists("g:spec_chglog_prepend") |
| 172 | while !(getline(line+2) =~ '^\( *\|\*.*\)$') |
| 173 | let line = line+1 |
| 174 | endwhile |
| 175 | endif |
| 176 | call append(line+1,"- ") |
| 177 | let insert_line = line+2 |
| 178 | endif |
| 179 | execute insert_line |
| 180 | startinsert! |
| 181 | endif |
| 182 | endfunction |
| 183 | endif |
| 184 | |
| 185 | if !exists("*s:ParseRpmVars") |
| 186 | function s:ParseRpmVars(str, strline) |
| 187 | let end = -1 |
| 188 | let ret = "" |
| 189 | while (1) |
| 190 | let start = match(a:str, "\%{", end+1) |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 191 | if start == -1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 192 | let ret = ret . strpart(a:str, end+1) |
| 193 | break |
| 194 | endif |
| 195 | let ret = ret . strpart(a:str, end+1, start-(end+1)) |
| 196 | let end = match(a:str, "}", start) |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 197 | if end == -1 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 198 | let ret = ret . strpart(a:str, start) |
| 199 | break |
| 200 | endif |
| 201 | let varname = strpart(a:str, start+2, end-(start+2)) |
| 202 | execute a:strline |
Bram Moolenaar | 1c6737b | 2020-09-07 22:18:52 +0200 | [diff] [blame] | 203 | let definestr = "^[ \t]*%\\(define\\|global\\)[ \t]\\+".varname."[ \t]\\+\\(.*\\)$" |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 204 | let linenum = search(definestr, "bW") |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 205 | if linenum != 0 |
Bram Moolenaar | 1c6737b | 2020-09-07 22:18:52 +0200 | [diff] [blame] | 206 | let ret = ret . substitute(getline(linenum), definestr, "\\2", "") |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 207 | endif |
| 208 | endwhile |
| 209 | return ret |
| 210 | endfunction |
| 211 | endif |
| 212 | |
| 213 | " The following lines, along with the macros/matchit.vim plugin, |
| 214 | " make it easy to navigate the different sections of a spec file |
| 215 | " with the % key (thanks to Max Ischenko). |
| 216 | |
| 217 | let b:match_ignorecase = 0 |
| 218 | let b:match_words = |
Bram Moolenaar | 82af871 | 2016-06-04 20:20:29 +0200 | [diff] [blame] | 219 | \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' . |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 220 | \ '^%package:^%preun:^%postun:^%changelog' |
| 221 | |
Bram Moolenaar | b6b046b | 2011-12-30 13:11:27 +0100 | [diff] [blame] | 222 | let &cpo = s:cpo_save |
| 223 | unlet s:cpo_save |
| 224 | |
Andreas Schneider | 4f51f3a | 2024-10-07 21:02:10 +0200 | [diff] [blame] | 225 | let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_words" |