blob: b229dbe84c21d4d04cd8091cabb7b0fdf0987df8 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim filetype plugin file
Bram Moolenaar42eeac32005-06-29 22:40:58 +00002" Language: generic Changelog file
3" Maintainer: Nikolai Weibull <nikolai+work.vim@bitwi.se>
4" Latest Revision: 2005-06-29
Bram Moolenaar071d4272004-06-13 20:20:40 +00005" Variables:
6" g:changelog_timeformat -
Bram Moolenaar42eeac32005-06-29 22:40:58 +00007" description: the timeformat used in ChangeLog entries.
8" default: "%Y-%m-%d".
Bram Moolenaar071d4272004-06-13 20:20:40 +00009" g:changelog_username -
Bram Moolenaar42eeac32005-06-29 22:40:58 +000010" description: the username to use in ChangeLog entries
11" default: try to deduce it from environment variables and system files.
Bram Moolenaar071d4272004-06-13 20:20:40 +000012" Local Mappings:
13" <Leader>o -
Bram Moolenaar42eeac32005-06-29 22:40:58 +000014" adds a new changelog entry for the current user for the current date.
Bram Moolenaar071d4272004-06-13 20:20:40 +000015" Global Mappings:
16" <Leader>o -
Bram Moolenaar42eeac32005-06-29 22:40:58 +000017" switches to the ChangeLog buffer opened for the current directory, or
18" opens it in a new buffer if it exists in the current directory. Then
19" it does the same as the local <Leader>o described above.
Bram Moolenaar071d4272004-06-13 20:20:40 +000020" Notes:
21" run 'runtime ftplugin/changelog.vim' to enable the global mapping for
22" changelog files.
23" TODO:
24" should we perhaps open the ChangeLog file even if it doesn't exist already?
25" Problem is that you might end up with ChangeLog files all over the place.
26
27" If 'filetype' isn't "changelog", we must have been to add ChangeLog opener
28if &filetype == "changelog"
Bram Moolenaar071d4272004-06-13 20:20:40 +000029 if exists("b:did_ftplugin")
30 finish
31 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000032 let b:did_ftplugin = 1
33
Bram Moolenaar42eeac32005-06-29 22:40:58 +000034 let s:cpo_save = &cpo
35 set cpo&vim
Bram Moolenaar071d4272004-06-13 20:20:40 +000036
37 " The format of the date-time field (should have been called dateformat)
38 if !exists("g:changelog_timeformat")
39 let g:changelog_timeformat = "%Y-%m-%d"
40 endif
41
42 " Try to figure out a reasonable username of the form:
43 " Full Name <user@host>
44 if !exists("g:changelog_username")
45 if exists("$EMAIL_ADDRESS")
46 let g:changelog_username = $EMAIL_ADDRESS
47 elseif exists("$EMAIL")
48 let g:changelog_username = $EMAIL
49 else
50 " Get the users login name
51 let login = system('whoami')
52 if v:shell_error
Bram Moolenaar42eeac32005-06-29 22:40:58 +000053 let login = 'unknown'
Bram Moolenaar071d4272004-06-13 20:20:40 +000054 else
Bram Moolenaar42eeac32005-06-29 22:40:58 +000055 let newline = stridx(login, "\n")
56 if newline != -1
57 let login = strpart(login, 0, newline)
58 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000059 endif
60
61 " Try to full name from gecos field in /etc/passwd
62 if filereadable('/etc/passwd')
Bram Moolenaar42eeac32005-06-29 22:40:58 +000063 let name = substitute(
64 \system('cat /etc/passwd | grep ^`whoami`'),
65 \'^\%([^:]*:\)\{4}\([^:]*\):.*$', '\1', '')
Bram Moolenaar071d4272004-06-13 20:20:40 +000066 endif
67
68 " If there is no such file, or there was some other problem try
69 " others
70 if !filereadable('/etc/passwd') || v:shell_error
Bram Moolenaar42eeac32005-06-29 22:40:58 +000071 " Maybe the environment has something of interest
72 if exists("$NAME")
73 let name = $NAME
74 else
75 " No? well, use the login name and capitalize first
76 " character
77 let name = toupper(login[0]) . strpart(login, 1)
78 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000079 endif
80
81 " Only keep stuff before the first comma
82 let comma = stridx(name, ',')
83 if comma != -1
Bram Moolenaar42eeac32005-06-29 22:40:58 +000084 let name = strpart(name, 0, comma)
Bram Moolenaar071d4272004-06-13 20:20:40 +000085 endif
86
87 " And substitute & in the real name with the login of our user
88 let amp = stridx(name, '&')
89 if amp != -1
Bram Moolenaar42eeac32005-06-29 22:40:58 +000090 let name = strpart(name, 0, amp) . toupper(login[0]) .
91 \strpart(login, 1) . strpart(name, amp + 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +000092 endif
93
94 " Get our hostname
95 let hostname = system("hostname")
96 if v:shell_error
Bram Moolenaar42eeac32005-06-29 22:40:58 +000097 let hostname = 'unknownhost'
Bram Moolenaar071d4272004-06-13 20:20:40 +000098 else
Bram Moolenaar42eeac32005-06-29 22:40:58 +000099 let newline = stridx(hostname, "\n")
100 if newline != -1
101 let hostname = strpart(hostname, 0, newline)
102 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000103 endif
104
105 " And finally set the username
106 let g:changelog_username = name.' <'.login.'@'.hostname.'>'
107 endif
108 endif
109
110 " Format used for new date-entries
111 if !exists("g:changelog_new_date_format")
112 let g:changelog_new_date_format = "%d %u\n\n\t* %c\n\n"
113 endif
114
115 " Format used for new entries to current date-entry
116 if !exists("g:changelog_new_entry_format")
117 let g:changelog_new_entry_format = "\t* %c"
118 endif
119
120 if !exists("g:changelog_date_entry_search")
121 let g:changelog_date_entry_search = '^\s*%d\_s*%u'
122 endif
123
124 " Substitutes specific items in new date-entry formats and search strings
125 " Can be done with substitute of course, but unclean, and need \@! then
126 function! s:substitute_items(str, date, user)
127 let str = a:str
128 let i = stridx(str, '%')
129 while i != -1
130 let char = str[i + 1]
131 if char == '%'
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000132 let middle = '%'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000133 elseif char == 'd'
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000134 let middle = a:date
Bram Moolenaar071d4272004-06-13 20:20:40 +0000135 elseif char == 'u'
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000136 let middle = a:user
Bram Moolenaar071d4272004-06-13 20:20:40 +0000137 elseif char == 'c'
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000138 let middle = '{cursor}'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000139 else
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000140 let middle = char
Bram Moolenaar071d4272004-06-13 20:20:40 +0000141 endif
142 let str = strpart(str, 0, i) . middle . strpart(str, i + 2)
143 let i = stridx(str, '%')
144 endwhile
145 return str
146 endfunction
147
148 function! s:position_cursor()
149 if search('{cursor}') > 0
150 let pos = line('.')
151 let line = getline(pos)
152 let cursor = stridx(line, '{cursor}')
153 call setline(pos, substitute(line, '{cursor}', '', ''))
154 endif
155 startinsert!
156 endfunction
157
158 " Internal function to create a new entry in the ChangeLog
159 function! s:new_changelog_entry()
160 " Deal with 'paste' option
161 let save_paste = &paste
162 let &paste = 1
163 1
164 " Look for an entry for today by our user
165 let date = strftime(g:changelog_timeformat)
166 let search = s:substitute_items(g:changelog_date_entry_search, date,
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000167 \g:changelog_username)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000168 if search(search) > 0
169 " Ok, now we look for the end of the date-entry, and add an entry
170 let pos = nextnonblank(line('.') + 1)
171 let line = getline(pos)
172 while line =~ '^\s\+\S\+'
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000173 let pos = pos + 1
174 let line = getline(pos)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000175 endwhile
176 let insert = s:substitute_items(g:changelog_new_entry_format,
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000177 \'', '')
Bram Moolenaar071d4272004-06-13 20:20:40 +0000178 execute "normal! ".(pos - 1)."Go".insert
179 execute pos
180 else
181 " Flag for removing empty lines at end of new ChangeLogs
182 let remove_empty = line('$') == 1
183
184 " No entry today, so create a date-user header and insert an entry
185 let todays_entry = s:substitute_items(g:changelog_new_date_format,
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000186 \date, g:changelog_username)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000187 " Make sure we have a cursor positioning
188 if stridx(todays_entry, '{cursor}') == -1
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000189 let todays_entry = todays_entry.'{cursor}'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000190 endif
191
192 " Now do the work
193 execute "normal! i".todays_entry
194 if remove_empty
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000195 while getline('$') == ''
196 $delete
197 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +0000198 endif
199
200 1
201 endif
202
203 call s:position_cursor()
204
205 " And reset 'paste' option
206 let &paste = save_paste
207 endfunction
208
209 if exists(":NewChangelogEntry") != 2
210 map <buffer> <silent> <Leader>o <Esc>:call <SID>new_changelog_entry()<CR>
211 command! -nargs=0 NewChangelogEntry call s:new_changelog_entry()
212 endif
213
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000214 let b:undo_ftplugin = "setl com< tw< fo< et< ai<"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000215
216 if &textwidth == 0
217 setlocal textwidth=78
218 endif
219 setlocal comments=
220 setlocal formatoptions+=t
221 setlocal noexpandtab
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000222 setlocal autoindent
Bram Moolenaar071d4272004-06-13 20:20:40 +0000223
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000224 let &cpo = s:cpo_save
225 unlet s:cpo_save
Bram Moolenaar071d4272004-06-13 20:20:40 +0000226else
227 " Add the Changelog opening mapping
228 nmap <silent> <Leader>o :call <SID>open_changelog()<CR>
229
230 function! s:open_changelog()
231 if filereadable('ChangeLog')
232 if bufloaded('ChangeLog')
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000233 let buf = bufnr('ChangeLog')
234 execute "normal! \<C-W>t"
235 while winbufnr(winnr()) != buf
236 execute "normal! \<C-W>w"
237 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238 else
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000239 split ChangeLog
Bram Moolenaar071d4272004-06-13 20:20:40 +0000240 endif
241
242 if exists("g:mapleader")
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000243 execute "normal " . g:mapleader . "o"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000244 else
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000245 execute "normal \\o"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000246 endif
247 startinsert!
248 endif
249 endfunction
250endif