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 6if exists("b:did_ftplugin") 7 finish 8endif 9let b:did_ftplugin = 1 10 11if !exists("no_plugin_maps") && !exists("no_spec_maps") 12 if !hasmapto("<Plug>SpecChangelog") 13 map <buffer> <LocalLeader>c <Plug>SpecChangelog 14 endif 15endif 16 17noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR> 18 19if !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 128endif 129 130if !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 158endif 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 164let b:match_ignorecase = 0 165let b:match_words = 166 \ '^Name:^%description:^%clean:^%setup:^%build:^%install:^%files:' . 167 \ '^%package:^%preun:^%postun:^%changelog' 168 169