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