codekingpro/portable-devtools
115k
1" Plugin to update the %changelog section of RPM spec files2" Filename: spec.vim3" Maintainer: Igor Gnatenko i.gnatenko.brain@gmail.com4" Former Maintainer: Gustavo Niemeyer <niemeyer@conectiva.com> (until March 2014)5" Last Change: 2015 Jun 016" Update by Zdenek Dohnal, 2022 May 177" 2024 Sep 10 by Vim Project: add epoch support for spec changelog, #155378" 2024 Oct 07 by Vim Project: add comment support, #158179 10if exists("b:did_ftplugin")11 finish12endif13let b:did_ftplugin = 114 15let s:cpo_save = &cpo16set cpo&vim17 18setlocal comments=b:#19setlocal commentstring=#\ %s20 21let b:undo_ftplugin = "setlocal comments< commentstring<"22 23if !exists("no_plugin_maps") && !exists("no_spec_maps")24 if !hasmapto("<Plug>SpecChangelog")25 map <buffer> <LocalLeader>c <Plug>SpecChangelog26 endif27endif28 29if !hasmapto("call <SID>SpecChangelog(\"\")<CR>")30 noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>31endif32 33if !exists("*s:GetRelVer")34 function! s:GetRelVer()35 if has('python')36python << PYEND37import sys, datetime, shutil, tempfile38import vim39 40try:41 import rpm42except ImportError:43 pass44else:45 specfile = vim.current.buffer.name46 if specfile:47 rpm.delMacro("dist")48 spec = rpm.spec(specfile)49 headers = spec.sourceHeader50 version = headers["Version"]51 release = headers["Release"]52 vim.command("let ver = '" + version + "'")53 vim.command("let rel = '" + release + "'")54PYEND55 endif56 endfunction57endif58 59if !exists("*s:SpecChangelog")60 function s:SpecChangelog(format)61 if strlen(a:format) == 062 if !exists("g:spec_chglog_format")63 let email = input("Name <email address>: ")64 let g:spec_chglog_format = "%a %b %d %Y " . l:email65 echo "\r"66 endif67 let format = g:spec_chglog_format68 else69 if !exists("g:spec_chglog_format")70 let g:spec_chglog_format = a:format71 endif72 let format = a:format73 endif74 let line = 075 let name = ""76 let epoch = ""77 let ver = ""78 let rel = ""79 let nameline = -180 let epochline = -181 let verline = -182 let relline = -183 let chgline = -184 while (line <= line("$"))85 let linestr = getline(line)86 if name == "" && linestr =~? '^Name:'87 let nameline = line88 let name = substitute(strpart(linestr,5), '^[ ]*\([^ ]\+\)[ ]*$','\1','')89 elseif epoch == "" && linestr =~? '^Epoch:'90 let epochline = line91 let epoch = substitute(strpart(linestr,6), '^[ ]*\([^ ]\+\)[ ]*$','\1','')92 elseif ver == "" && linestr =~? '^Version:'93 let verline = line94 let ver = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')95 elseif rel == "" && linestr =~? '^Release:'96 let relline = line97 let rel = substitute(strpart(linestr,8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')98 elseif linestr =~? '^%changelog'99 let chgline = line100 execute line101 break102 endif103 let line = line+1104 endwhile105 if nameline != -1 && verline != -1 && relline != -1106 let include_release_info = exists("g:spec_chglog_release_info")107 let name = s:ParseRpmVars(name, nameline)108 let epoch = s:ParseRpmVars(epoch, epochline)109 let ver = s:ParseRpmVars(ver, verline)110 let rel = s:ParseRpmVars(rel, relline)111 else112 let include_release_info = 0113 endif114 115 call s:GetRelVer()116 117 if chgline == -1118 let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)119 if option == 1120 call append(line("$"),"")121 call append(line("$"),"%changelog")122 execute line("$")123 let chgline = line(".")124 elseif option == 2125 call append(line("."),"%changelog")126 normal j127 let chgline = line(".")128 endif129 endif130 if chgline != -1131 let tmptime = v:lc_time132 language time C133 if strlen(epoch)134 let ver = epoch.":".ver135 endif136 let parsed_format = "* ".strftime(format)." - ".ver."-".rel137 execute "language time" tmptime138 let release_info = "+ ".name."-".ver."-".rel139 let wrong_format = 0140 let wrong_release = 0141 let insert_line = 0142 if getline(chgline+1) != parsed_format143 let wrong_format = 1144 endif145 if include_release_info && getline(chgline+2) != release_info146 let wrong_release = 1147 endif148 if wrong_format || wrong_release149 if include_release_info && !wrong_release && !exists("g:spec_chglog_never_increase_release")150 let option = confirm("Increase release? ","&Yes\n&No",1)151 if option == 1152 execute relline153 normal 154 let rel = substitute(strpart(getline(relline),8), '^[ ]*\([^ ]\+\)[ ]*$','\1','')155 let release_info = "+ ".name."-".ver."-".rel156 endif157 endif158 let n = 0159 call append(chgline+n, parsed_format)160 if include_release_info161 let n = n + 1162 call append(chgline+n, release_info)163 endif164 let n = n + 1165 call append(chgline+n,"- ")166 let n = n + 1167 call append(chgline+n,"")168 let insert_line = chgline+n169 else170 let line = chgline171 if !exists("g:spec_chglog_prepend")172 while !(getline(line+2) =~ '^\( *\|\*.*\)$')173 let line = line+1174 endwhile175 endif176 call append(line+1,"- ")177 let insert_line = line+2178 endif179 execute insert_line180 startinsert!181 endif182 endfunction183endif184 185if !exists("*s:ParseRpmVars")186 function s:ParseRpmVars(str, strline)187 let end = -1188 let ret = ""189 while (1)190 let start = match(a:str, "\%{", end+1)191 if start == -1192 let ret = ret . strpart(a:str, end+1)193 break194 endif195 let ret = ret . strpart(a:str, end+1, start-(end+1))196 let end = match(a:str, "}", start)197 if end == -1198 let ret = ret . strpart(a:str, start)199 break200 endif201 let varname = strpart(a:str, start+2, end-(start+2))202 execute a:strline203 let definestr = "^[ \t]*%\\(define\\|global\\)[ \t]\\+".varname."[ \t]\\+\\(.*\\)$"204 let linenum = search(definestr, "bW")205 if linenum != 0206 let ret = ret . substitute(getline(linenum), definestr, "\\2", "")207 endif208 endwhile209 return ret210 endfunction211endif212 213" The following lines, along with the macros/matchit.vim plugin,214" make it easy to navigate the different sections of a spec file215" with the % key (thanks to Max Ischenko).216 217let b:match_ignorecase = 0218let b:match_words =219 \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' .220 \ '^%package:^%preun:^%postun:^%changelog'221 222let &cpo = s:cpo_save223unlet s:cpo_save224 225let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_words"226 