neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

spec.vim (6345B)


      1 " Plugin to update the %changelog section of RPM spec files
      2 " Filename: spec.vim
      3 " Maintainer: Igor Gnatenko i.gnatenko.brain@gmail.com
      4 " Former Maintainer: Gustavo Niemeyer <niemeyer@conectiva.com> (until March 2014)
      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
      8 "  2024 Oct 07 by Vim Project: add comment support, #15817
      9 
     10 if exists("b:did_ftplugin")
     11 finish
     12 endif
     13 let b:did_ftplugin = 1
     14 
     15 let s:cpo_save = &cpo
     16 set cpo&vim
     17 
     18 setlocal comments=b:#
     19 setlocal commentstring=#\ %s
     20 
     21 let b:undo_ftplugin = "setlocal comments< commentstring<"
     22 
     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 
     29 if !hasmapto("call <SID>SpecChangelog(\"\")<CR>")
     30       noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR>
     31 endif
     32 
     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:
     47        rpm.delMacro("dist")
     48        spec = rpm.spec(specfile)
     49        headers = spec.sourceHeader
     50        version = headers["Version"]
     51        release = headers["Release"]
     52        vim.command("let ver = '" + version + "'")
     53        vim.command("let rel = '" + release + "'")
     54 PYEND
     55 	endif
     56 endfunction
     57 endif
     58 
     59 if !exists("*s:SpecChangelog")
     60 function s:SpecChangelog(format)
     61 	if strlen(a:format) == 0
     62 		if !exists("g:spec_chglog_format")
     63 			let email = input("Name <email address>: ")
     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 = ""
     76 	let epoch = ""
     77 	let ver = ""
     78 	let rel = ""
     79 	let nameline = -1
     80 	let epochline = -1
     81 	let verline = -1
     82 	let relline = -1
     83 	let chgline = -1
     84 	while (line <= line("$"))
     85 		let linestr = getline(line)
     86 		if name == "" && linestr =~? '^Name:'
     87 			let nameline = line
     88 			let name = substitute(strpart(linestr,5), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
     89 		elseif epoch == "" && linestr =~? '^Epoch:'
     90 			let epochline = line
     91 			let epoch = substitute(strpart(linestr,6), '^[     ]*\([^         ]\+\)[          ]*$','\1','')
     92 		elseif ver == "" && linestr =~? '^Version:'
     93 			let verline = line
     94 			let ver = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
     95 		elseif rel == "" && linestr =~? '^Release:'
     96 			let relline = line
     97 			let rel = substitute(strpart(linestr,8), '^[	 ]*\([^ 	]\+\)[		]*$','\1','')
     98 		elseif linestr =~? '^%changelog'
     99 			let chgline = line
    100 			execute line
    101 			break
    102 		endif
    103 		let line = line+1
    104 	endwhile
    105 	if nameline != -1 && verline != -1 && relline != -1
    106 		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 	else
    112 		let include_release_info = 0
    113 	endif
    114 
    115 	call s:GetRelVer()
    116 
    117 	if chgline == -1
    118 		let option = confirm("Can't find %changelog. Create one? ","&End of file\n&Here\n&Cancel",3)
    119 		if option == 1
    120 			call append(line("$"),"")
    121 			call append(line("$"),"%changelog")
    122 			execute line("$")
    123 			let chgline = line(".")
    124 		elseif option == 2
    125 			call append(line("."),"%changelog")
    126 			normal j
    127 			let chgline = line(".")
    128 		endif
    129 	endif
    130 	if chgline != -1
    131 		let tmptime = v:lc_time
    132 		language time C
    133 		if strlen(epoch)
    134 			let ver = epoch.":".ver
    135 		endif
    136 		let parsed_format = "* ".strftime(format)." - ".ver."-".rel
    137 		execute "language time" tmptime
    138 		let release_info = "+ ".name."-".ver."-".rel
    139 		let wrong_format = 0
    140 		let wrong_release = 0
    141 		let insert_line = 0
    142 		if getline(chgline+1) != parsed_format
    143 			let wrong_format = 1
    144 		endif
    145 		if include_release_info && getline(chgline+2) != release_info
    146 			let wrong_release = 1
    147 		endif
    148 		if wrong_format || wrong_release
    149 			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 == 1
    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)
    191 	if start == -1
    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)
    197 	if end == -1
    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
    203 	let definestr = "^[ \t]*%\\(define\\|global\\)[ \t]\\+".varname."[ \t]\\+\\(.*\\)$"
    204 	let linenum = search(definestr, "bW")
    205 	if linenum != 0
    206 		let ret = ret .  substitute(getline(linenum), definestr, "\\2", "")
    207 	endif
    208 endwhile
    209 return ret
    210    endfunction
    211 endif
    212 
    213 " The following lines, along with the 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 =
    219  \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' .
    220  \ '^%package:^%preun:^%postun:^%changelog'
    221 
    222 let &cpo = s:cpo_save
    223 unlet s:cpo_save
    224 
    225 let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_words"