blob: 47d58ccb90d38d748f9ac47b9568717525c5282d [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim filetype plugin file
2" Language: generic Changelog file
3" Maintainer: Nikolai Weibull <source@pcppopper.org>
4" URL: http://www.pcppopper.org/vim/ftplugin/pcp/changelog/
5" Latest Revision: 2004-04-25
6" arch-tag: b00e2974-c559-4477-b7b2-3ef3f4061bdb
7" Variables:
8" g:changelog_timeformat -
9" description: the timeformat used in ChangeLog entries.
10" default: "%Y-%m-%d".
11" g:changelog_username -
12" description: the username to use in ChangeLog entries
13" default: try to deduce it from environment variables and system files.
14" Local Mappings:
15" <Leader>o -
16" adds a new changelog entry for the current user for the current date.
17" Global Mappings:
18" <Leader>o -
19" switches to the ChangeLog buffer opened for the current directory, or
20" opens it in a new buffer if it exists in the current directory. Then
21" it does the same as the local <Leader>o described above.
22" Notes:
23" run 'runtime ftplugin/changelog.vim' to enable the global mapping for
24" changelog files.
25" TODO:
26" should we perhaps open the ChangeLog file even if it doesn't exist already?
27" Problem is that you might end up with ChangeLog files all over the place.
28
29" If 'filetype' isn't "changelog", we must have been to add ChangeLog opener
30if &filetype == "changelog"
31 " Only do this when not done yet for this buffer
32 if exists("b:did_ftplugin")
33 finish
34 endif
35
36 " Don't load another plugin for this buffer
37 let b:did_ftplugin = 1
38
39 let cpo_save = &cpo
40 set cpo-=C
41
42 " The format of the date-time field (should have been called dateformat)
43 if !exists("g:changelog_timeformat")
44 let g:changelog_timeformat = "%Y-%m-%d"
45 endif
46
47 " Try to figure out a reasonable username of the form:
48 " Full Name <user@host>
49 if !exists("g:changelog_username")
50 if exists("$EMAIL_ADDRESS")
51 let g:changelog_username = $EMAIL_ADDRESS
52 elseif exists("$EMAIL")
53 let g:changelog_username = $EMAIL
54 else
55 " Get the users login name
56 let login = system('whoami')
57 if v:shell_error
58 let login = 'unknown'
59 else
60 let newline = stridx(login, "\n")
61 if newline != -1
62 let login = strpart(login, 0, newline)
63 endif
64 endif
65
66 " Try to full name from gecos field in /etc/passwd
67 if filereadable('/etc/passwd')
68 let name = substitute(
69 \system('cat /etc/passwd | grep ^`whoami`'),
70 \'^\%([^:]*:\)\{4}\([^:]*\):.*$', '\1', '')
71 endif
72
73 " If there is no such file, or there was some other problem try
74 " others
75 if !filereadable('/etc/passwd') || v:shell_error
76 " Maybe the environment has something of interest
77 if exists("$NAME")
78 let name = $NAME
79 else
80 " No? well, use the login name and capitalize first
81 " character
82 let name = toupper(login[0]) . strpart(login, 1)
83 endif
84 endif
85
86 " Only keep stuff before the first comma
87 let comma = stridx(name, ',')
88 if comma != -1
89 let name = strpart(name, 0, comma)
90 endif
91
92 " And substitute & in the real name with the login of our user
93 let amp = stridx(name, '&')
94 if amp != -1
95 let name = strpart(name, 0, amp) . toupper(login[0]) .
96 \strpart(login, 1) . strpart(name, amp + 1)
97 endif
98
99 " Get our hostname
100 let hostname = system("hostname")
101 if v:shell_error
102 let hostname = 'unknownhost'
103 else
104 let newline = stridx(hostname, "\n")
105 if newline != -1
106 let hostname = strpart(hostname, 0, newline)
107 endif
108 endif
109
110 " And finally set the username
111 let g:changelog_username = name.' <'.login.'@'.hostname.'>'
112 endif
113 endif
114
115 " Format used for new date-entries
116 if !exists("g:changelog_new_date_format")
117 let g:changelog_new_date_format = "%d %u\n\n\t* %c\n\n"
118 endif
119
120 " Format used for new entries to current date-entry
121 if !exists("g:changelog_new_entry_format")
122 let g:changelog_new_entry_format = "\t* %c"
123 endif
124
125 if !exists("g:changelog_date_entry_search")
126 let g:changelog_date_entry_search = '^\s*%d\_s*%u'
127 endif
128
129 " Substitutes specific items in new date-entry formats and search strings
130 " Can be done with substitute of course, but unclean, and need \@! then
131 function! s:substitute_items(str, date, user)
132 let str = a:str
133 let i = stridx(str, '%')
134 while i != -1
135 let char = str[i + 1]
136 if char == '%'
137 let middle = '%'
138 elseif char == 'd'
139 let middle = a:date
140 elseif char == 'u'
141 let middle = a:user
142 elseif char == 'c'
143 let middle = '{cursor}'
144 else
145 let middle = char
146 endif
147 let str = strpart(str, 0, i) . middle . strpart(str, i + 2)
148 let i = stridx(str, '%')
149 endwhile
150 return str
151 endfunction
152
153 function! s:position_cursor()
154 if search('{cursor}') > 0
155 let pos = line('.')
156 let line = getline(pos)
157 let cursor = stridx(line, '{cursor}')
158 call setline(pos, substitute(line, '{cursor}', '', ''))
159 endif
160 startinsert!
161 endfunction
162
163 " Internal function to create a new entry in the ChangeLog
164 function! s:new_changelog_entry()
165 " Deal with 'paste' option
166 let save_paste = &paste
167 let &paste = 1
168 1
169 " Look for an entry for today by our user
170 let date = strftime(g:changelog_timeformat)
171 let search = s:substitute_items(g:changelog_date_entry_search, date,
172 \g:changelog_username)
173 if search(search) > 0
174 " Ok, now we look for the end of the date-entry, and add an entry
175 let pos = nextnonblank(line('.') + 1)
176 let line = getline(pos)
177 while line =~ '^\s\+\S\+'
178 let pos = pos + 1
179 let line = getline(pos)
180 endwhile
181 let insert = s:substitute_items(g:changelog_new_entry_format,
182 \'', '')
183 execute "normal! ".(pos - 1)."Go".insert
184 execute pos
185 else
186 " Flag for removing empty lines at end of new ChangeLogs
187 let remove_empty = line('$') == 1
188
189 " No entry today, so create a date-user header and insert an entry
190 let todays_entry = s:substitute_items(g:changelog_new_date_format,
191 \date, g:changelog_username)
192 " Make sure we have a cursor positioning
193 if stridx(todays_entry, '{cursor}') == -1
194 let todays_entry = todays_entry.'{cursor}'
195 endif
196
197 " Now do the work
198 execute "normal! i".todays_entry
199 if remove_empty
200 while getline('$') == ''
201 $delete
202 endwhile
203 endif
204
205 1
206 endif
207
208 call s:position_cursor()
209
210 " And reset 'paste' option
211 let &paste = save_paste
212 endfunction
213
214 if exists(":NewChangelogEntry") != 2
215 map <buffer> <silent> <Leader>o <Esc>:call <SID>new_changelog_entry()<CR>
216 command! -nargs=0 NewChangelogEntry call s:new_changelog_entry()
217 endif
218
219 let b:undo_ftplugin = "setl com< tw< fo< et< ai<"
220
221 if &textwidth == 0
222 setlocal textwidth=78
223 endif
224 setlocal comments=
225 setlocal formatoptions+=t
226 setlocal noexpandtab
227 setlocal autoindent
228
229 let &cpo = cpo_save
230else
231 " Add the Changelog opening mapping
232 nmap <silent> <Leader>o :call <SID>open_changelog()<CR>
233
234 function! s:open_changelog()
235 if filereadable('ChangeLog')
236 if bufloaded('ChangeLog')
237 let buf = bufnr('ChangeLog')
238 execute "normal! \<C-W>t"
239 while winbufnr(winnr()) != buf
240 execute "normal! \<C-W>w"
241 endwhile
242 else
243 split ChangeLog
244 endif
245
246 if exists("g:mapleader")
247 execute "normal " . g:mapleader . "o"
248 else
249 execute "normal \\o"
250 endif
251 startinsert!
252 endif
253 endfunction
254endif
255
256" vim: set sts=2 sw=2: