home *** CD-ROM | disk | FTP | other *** search
- " Vim filetype plugin
- " Language: generic Changelog file
- " Maintainer: Nikolai 'pcp' Weibull <da.box@home.se>
- " URL: http://www.pcppopper.org/
- " Latest Revision: 2003-01-14
- " Variables:
- " g:changelog_timeformat -
- " description: the timeformat used in ChangeLog entries.
- " default: "%Y-%m-%d".
- " g:changelog_username -
- " description: the username to use in ChangeLog entries
- " default: try to deduce it from environment variables and system files.
- " Local Mappings:
- " <Leader>o -
- " adds a new changelog entry for the current user for the current date.
- " Global Mappings:
- " <Leader>o -
- " switches to the ChangeLog buffer opened for the current directory, or
- " opens it in a new buffer if it exists in the current directory. Then
- " it does the same as the local <Leader>o described above.
- "
- " Notes:
- " run 'runtime ftplugin/changelog.vim' to enable the global mapping for
- " changelog files.
- " TODO:
- " should we perhaps open the ChangeLog file even if it doesn't exist already?
- " Problem is that you might end up with ChangeLog files all over the place.
-
- " If 'filetype' isn't "changelog", we must have been to add ChangeLog opener
- if &filetype == "changelog"
- " Only do this when not done yet for this buffer
- if exists("b:did_ftplugin")
- finish
- endif
-
- " Don't load another plugin for this buffer
- let b:did_ftplugin = 1
-
- " The format of the date-time field (should have been called dateformat)
- if !exists("g:changelog_timeformat")
- let g:changelog_timeformat = "%Y-%m-%d"
- endif
-
- " Try to figure out a reasonable username of the form:
- " Full Name <user@host>
- if !exists("g:changelog_username")
-
- " Get the users login name
- let login = system('whoami')
- if v:shell_error
- let login = 'unknown'
- else
- let newline = stridx(login, "\n")
- if newline != -1
- let login = strpart(login, 0, newline)
- endif
- endif
-
- " Try to full name from gecos field in /etc/passwd
- if filereadable('/etc/passwd')
- let name = substitute(
- \system('cat /etc/passwd | grep ^`whoami`'),
- \'^\%([^:]*:\)\{4}\([^:]*\):.*$', '\1', '')
- endif
-
- " If there is no such file, or there was some other problem try others
- if !filereadable('/etc/passwd') || v:shell_error
- " Maybe the environment has something of interest
- if exists("$NAME")
- let name = $NAME
- else
- " No? well, use the login name and capitalize first character
- let name = toupper(login[0]) . strpart(login, 1)
- endif
- endif
-
- " Only keep stuff before the first comma
- let comma = stridx(name, ',')
- if comma != -1
- let name = strpart(name, 0, comma)
- endif
-
- " And substitute & in the real name with the login of our user
- let amp = stridx(name, '&')
- if amp != -1
- let name = strpart(name, 0, amp) . toupper(login[0]) .
- \strpart(login, 1) . strpart(name, amp + 1)
- endif
-
- " Get our hostname
- let hostname = system("hostname")
- if v:shell_error
- let hostname = 'unknownhost'
- else
- let newline = stridx(hostname, "\n")
- if newline != -1
- let hostname = strpart(hostname, 0, newline)
- endif
- endif
-
- " And finally set the username
- let g:changelog_username = name.' <'.login.'@'.hostname.'>'
- endif
-
- " Format used for new date-entries
- if !exists("g:changelog_new_date_format")
- let g:changelog_new_date_format = "%d %u\n\n\t* %c\n\n"
- endif
-
- " Format used for new entries to current date-entry
- if !exists("g:changelog_new_entry_format")
- let g:changelog_new_entry_format = "\t* %c"
- endif
-
- if !exists("g:changelog_date_entry_search")
- let g:changelog_date_entry_search = '^\s*%d\_s*%u'
- endif
-
- " Substitutes specific items in new date-entry formats and search strings
- " Can be done with substitute of course, but unclean, and need \@! then
- function! s:substitute_items(str, date, user)
- let str = a:str
- let i = stridx(str, '%')
- while i != -1
- let char = str[i + 1]
- if char == '%'
- let middle = '%'
- elseif char == 'd'
- let middle = a:date
- elseif char == 'u'
- let middle = a:user
- elseif char == 'c'
- let middle = '{cursor}'
- else
- let middle = char
- endif
- let str = strpart(str, 0, i) . middle . strpart(str, i + 2)
- let i = stridx(str, '%')
- endwhile
- return str
- endfunction
-
- function! s:position_cursor()
- if search('{cursor}') > 0
- let pos = line('.')
- let line = getline(pos)
- let cursor = stridx(line, '{cursor}')
- call setline(pos, substitute(line, '{cursor}', '', ''))
- endif
- startinsert!
- endfunction
-
- " Internal function to create a new entry in the ChangeLog
- function! s:new_changelog_entry()
- " Deal with 'paste' option
- let save_paste = &paste
- let &paste = 1
- 1
- " Look for an entry for today by our user
- let date = strftime(g:changelog_timeformat)
- let search = s:substitute_items(g:changelog_date_entry_search, date,
- \g:changelog_username)
- if search(search) > 0
- " Ok, now we look for the end of the date-entry, and add an entry
- let pos = nextnonblank(line('.') + 1)
- let line = getline(pos)
- while line =~ '^\s\+\S\+'
- let pos = pos + 1
- let line = getline(pos)
- endwhile
- let insert = s:substitute_items(g:changelog_new_entry_format,
- \'', '')
- execute "normal! ".(pos - 1)."Go".insert
- execute pos
- else
- " Flag for removing empty lines at end of new ChangeLogs
- let remove_empty = line('$') == 1
-
- " No entry today, so create a date-user header and insert an entry
- let todays_entry = s:substitute_items(g:changelog_new_date_format,
- \date, g:changelog_username)
- " Make sure we have a cursor positioning
- if stridx(todays_entry, '{cursor}') == -1
- let todays_entry = todays_entry.'{cursor}'
- endif
-
- " Now do the work
- execute "normal! i".todays_entry
- if remove_empty
- while getline('$') == ''
- $delete
- endwhile
- endif
-
- 1
- endif
-
- call s:position_cursor()
-
- " And reset 'paste' option
- let &paste = save_paste
- endfunction
-
- if exists(":NewChangelogEntry") != 2
- map <buffer> <silent> <Leader>o <Esc>:call <SID>new_changelog_entry()<CR>
- command! -nargs=0 NewChangelogEntry call s:new_changelog_entry()
- endif
-
- setlocal comments=
- setlocal textwidth=78
- setlocal formatoptions+=t
- else
- " Add the Changelog opening mapping
- nmap <silent> <Leader>o :call <SID>open_changelog()<CR>
-
- function! s:open_changelog()
- if filereadable('ChangeLog')
- if bufloaded('ChangeLog')
- let buf = bufnr('ChangeLog')
- execute "normal! \<C-W>t"
- while winbufnr(winnr()) != buf
- execute "normal! \<C-W>w"
- endwhile
- else
- split ChangeLog
- endif
-
- if exists("g:mapleader")
- execute "normal " . g:mapleader . "o"
- else
- execute "normal \\o"
- endif
- startinsert!
- endif
- endfunction
- endif
-
- " vim: set sw=4 sts=4:
-