cvsdist 1401a3e
" Vim filetype plugin
cvsdist 1401a3e
" Language:	spec file
cvsdist 1401a3e
" Maintainer:	Guillaume Rousse <rousse@ccr.jussieu.fr>
cvsdist 1401a3e
" URL:		http://lis.snv.jussieu.fr/~rousse/linux/spec.vim
ef334d8
" Version:	$Id: spec.vim,v 1.2 2005/02/10 16:45:35 karsten Exp $
cvsdist 1401a3e
cvsdist 1401a3e
if exists("b:did_ftplugin")
cvsdist 1401a3e
	finish
cvsdist 1401a3e
endif
cvsdist 1401a3e
let b:did_ftplugin = 1
cvsdist 1401a3e
cvsdist 1401a3e
" Add mappings, unless user doesn't want
cvsdist 1401a3e
if !exists("no_plugin_maps") && !exists("no_spec_maps")
cvsdist 1401a3e
	if !hasmapto("<Plug>AddChangelogBlock")
cvsdist 1401a3e
		map <buffer> <LocalLeader>ch <Plug>AddChangelogBlock
cvsdist 1401a3e
	endif
cvsdist 1401a3e
	if !hasmapto("<Plug>AddChangelogEntry")
cvsdist 1401a3e
		map <buffer> <LocalLeader>CH <Plug>AddChangelogEntry
cvsdist 1401a3e
	endif
cvsdist 1401a3e
	noremap <buffer> <unique> <script> <Plug>AddChangelogBlock :call <SID>AddChangelogBlock()<CR> 
cvsdist 1401a3e
	noremap <buffer> <unique> <script> <Plug>AddChangelogEntry :call <SID>AddChangelogEntry()<CR>
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
" compilation option
cvsdist 1401a3e
setlocal makeprg=rpm\ -ba\ %
cvsdist 1401a3e
setlocal errorformat=error:\ line\ %l:\ %m
cvsdist 1401a3e
cvsdist 1401a3e
" navigation through sections
cvsdist 1401a3e
let b:match_ignorecase = 0
cvsdist 1401a3e
let b:match_words =
cvsdist 1401a3e
	\ '^Name:^%description:^%clean:^%setup:^%build:^%install:^%files:' .
cvsdist 1401a3e
	\ '^%package:^%preun:^%postun:^%changelog'
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:AddChangelogBlock")
cvsdist 1401a3e
	" Adds a changelog block
cvsdist 1401a3e
	function s:AddChangelogBlock()
cvsdist 1401a3e
		" look for changelog section
cvsdist 1401a3e
		let line = <SID>GetFirstLocation(0, '^%changelog')
cvsdist 1401a3e
		call <SID>InsertChangelogHeader(line)
cvsdist 1401a3e
		call <SID>InsertChangelogEntry(line + 1)
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:AddChangelogEntry")
cvsdist 1401a3e
	" Adds a changelog entry
cvsdist 1401a3e
	function s:AddChangelogEntry()
cvsdist 1401a3e
		" look for changelog section
cvsdist 1401a3e
		let line = <SID>GetFirstLocation(0, '^%changelog')
cvsdist 1401a3e
		" look for last entry
cvsdist 1401a3e
		let line = <SID>GetLastLocation(line + 1, '^- ')
cvsdist 1401a3e
		call <SID>InsertChangelogEntry(line)
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:InsertChangelogHeader")
cvsdist 1401a3e
	" Insert a changelog header just after the given line
cvsdist 1401a3e
	function s:InsertChangelogHeader(line)
cvsdist 1401a3e
		" ensure english locale
cvsdist 1401a3e
		language time C
cvsdist 1401a3e
		" insert blank line first
cvsdist 1401a3e
		call append(a:line, "")
cvsdist 1401a3e
		" insert changelog header
cvsdist 1401a3e
		call append(a:line,
cvsdist 1401a3e
			\ "* " . strftime("%a %b %d %Y") . 
cvsdist 1401a3e
			\ " " . <SID>GetTagValue("Packager") .
cvsdist 1401a3e
			\ " " . <SID>GetTagValue("Version") .
cvsdist 1401a3e
			\ "-" . <SID>GetTagValue("Release")
cvsdist 1401a3e
			\)
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:InsertChangelogEntry")
cvsdist 1401a3e
	" Insert a changelog entry just after the given line
cvsdist 1401a3e
	function s:InsertChangelogEntry(line)
cvsdist 1401a3e
		" insert changelog entry
ef334d8
		call append(a:line, "-")
cvsdist 1401a3e
		" position cursor here
ef334d8
		execute a:line +1
cvsdist 1401a3e
		" enter insert mode
cvsdist 1401a3e
		startinsert!
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:GetTagValue")
cvsdist 1401a3e
	" Return value of a rpm tag
cvsdist 1401a3e
	function s:GetTagValue(tag)
cvsdist 1401a3e
		let pattern = '^' . a:tag . ':\s*'
cvsdist 1401a3e
		let line = <SID>GetFirstLine(0, pattern)
cvsdist 1401a3e
		let value = substitute(line, pattern, "", "")
cvsdist 1401a3e
cvsdist 1401a3e
		" resolve macros
cvsdist 1401a3e
		while (value =~ '%{\?\w\{3,}}\?')
cvsdist 1401a3e
			let macro = matchstr(value, '%{\?\w\{3,}}\?')
cvsdist 1401a3e
			let macro_name = substitute(macro, '%{\?\(\w\{3,}\)}\?', '\1', "")
cvsdist 1401a3e
			let macro_value = <SID>GetMacroValue(macro_name)
cvsdist 1401a3e
			let value = substitute(value, '%{\?' . macro_name . '}\?', macro_value, "")
cvsdist 1401a3e
		endwhile
cvsdist 1401a3e
		
cvsdist 1401a3e
		" try to read externaly defined values
cvsdist 1401a3e
		if (value == "")
cvsdist 1401a3e
			let value = <SID>GetExternalMacroValue(a:tag)
cvsdist 1401a3e
		endif
cvsdist 1401a3e
cvsdist 1401a3e
		return value
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:GetMacroValue")
cvsdist 1401a3e
	" Return value of a rpm macro
cvsdist 1401a3e
	function s:GetMacroValue(macro)
cvsdist 1401a3e
		let pattern = '^%define\s*' . a:macro . '\s*'
cvsdist 1401a3e
		let line = <SID>GetFirstLine(0, pattern)
cvsdist 1401a3e
		return substitute(line, pattern, "", "")
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:GetExternalMacroValue")
cvsdist 1401a3e
	" Return value of an external rpm macro defined in $HOME/.rpmmacros
cvsdist 1401a3e
	function s:GetExternalMacroValue(macro)
cvsdist 1401a3e
		if filereadable($HOME . "/.rpmmacros")
cvsdist 1401a3e
			let pattern = '^%' . tolower(a:macro) . '\s*'
cvsdist 1401a3e
			let line = system("grep '" . pattern . "' $HOME/.rpmmacros")
cvsdist 1401a3e
			" get rid of this !#&* trailing <NL>
cvsdist 1401a3e
			let line = strpart(line, 0, strlen(line) - 1)
cvsdist 1401a3e
			return substitute(line, pattern, "", "")
cvsdist 1401a3e
		endif
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:GetFirstLocation")
cvsdist 1401a3e
	" Return location of first line matching the given pattern after the given line
cvsdist 1401a3e
	" Return -1 if not found at the end of the file
cvsdist 1401a3e
	function s:GetFirstLocation(from, pattern)
cvsdist 1401a3e
		let linenb = a:from
cvsdist 1401a3e
		while (linenb <= line("$"))
cvsdist 1401a3e
			let linenb = linenb + 1
cvsdist 1401a3e
			let linestr = getline(linenb)
cvsdist 1401a3e
			if (linestr =~ a:pattern)
cvsdist 1401a3e
				return linenb
cvsdist 1401a3e
			endif
cvsdist 1401a3e
		endwhile
cvsdist 1401a3e
		return -1
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:GetLastLocation")
cvsdist 1401a3e
	" Return location of last line matching the given pattern after the given line
cvsdist 1401a3e
	" Return -1 if still found at the end of the file
cvsdist 1401a3e
	function s:GetLastLocation(from, pattern)
cvsdist 1401a3e
		let linenb = a:from
cvsdist 1401a3e
		while (linenb <= line("$"))
cvsdist 1401a3e
			let linenb = linenb + 1
cvsdist 1401a3e
			let linestr = getline(linenb)
cvsdist 1401a3e
			if (linestr !~ a:pattern)
cvsdist 1401a3e
				return linenb - 1
cvsdist 1401a3e
			endif
cvsdist 1401a3e
		endwhile
cvsdist 1401a3e
		return -1
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif
cvsdist 1401a3e
cvsdist 1401a3e
if !exists("*s:GetFirstLine")
cvsdist 1401a3e
	" Return first line matching the given pattern after the given line
cvsdist 1401a3e
	" Return "" if not found at the end of the file
cvsdist 1401a3e
	function s:GetFirstLine(from, pattern)
cvsdist 1401a3e
		let linenb = a:from
cvsdist 1401a3e
		while (linenb <= line("$"))
cvsdist 1401a3e
			let linenb = linenb + 1
cvsdist 1401a3e
			let linestr = getline(linenb)
cvsdist 1401a3e
			if (linestr =~ a:pattern)
cvsdist 1401a3e
				return linestr
cvsdist 1401a3e
			endif
cvsdist 1401a3e
		endwhile
cvsdist 1401a3e
		return ""
cvsdist 1401a3e
	endfunction
cvsdist 1401a3e
endif