comparison vim/bundle/lawrencium/plugin/lawrencium.vim @ 56:0dbb1fd60f71

Debugging features, better auto-complete, and a bug fix in the hg-repo detection code.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 08 Dec 2011 12:30:50 -0800
parents 05fd225bd1a0
children
comparison
equal deleted inserted replaced
55:a7932e0fa961 56:0dbb1fd60f71
1 " lawrencium.vim - A Mercurial wrapper 1 " lawrencium.vim - A Mercurial wrapper
2 " Maintainer: Ludovic Chabant <http://ludovic.chabant.com> 2 " Maintainer: Ludovic Chabant <http://ludovic.chabant.com>
3 " Version: 0.1 3 " Version: 0.1
4 4
5 if exists('g:loaded_lawrencium') || &cp 5 " Globals {{{
6 " finish 6
7 if !exists('g:lawrencium_debug')
8 let g:lawrencium_debug = 0
9 endif
10
11 if (exists('g:loaded_lawrencium') || &cp) && !g:lawrencium_debug
12 finish
7 endif 13 endif
8 let g:loaded_lawrencium = 1 14 let g:loaded_lawrencium = 1
9 15
10 if !exists('g:lawrencium_hg_executable') 16 if !exists('g:lawrencium_hg_executable')
11 let g:lawrencium_hg_executable = 'hg' 17 let g:lawrencium_hg_executable = 'hg'
13 19
14 if !exists('g:lawrencium_trace') 20 if !exists('g:lawrencium_trace')
15 let g:lawrencium_trace = 0 21 let g:lawrencium_trace = 0
16 endif 22 endif
17 23
24 if g:lawrencium_debug
25 echom "Loaded Lawrencium."
26 endif
27
28 " }}}
29
18 " Utility {{{ 30 " Utility {{{
19 31
32 " Strips the ending slash in a path.
20 function! s:stripslash(path) 33 function! s:stripslash(path)
21 return fnamemodify(a:path, ':s?[\/]$??') 34 return fnamemodify(a:path, ':s?[/\\]$??')
22 endfunction 35 endfunction
23 36
37 " Normalizes the slashes in a path.
38 function! s:normalizepath(path)
39 if exists('+shellslash') && &shellslash
40 return substitute(a:path, '\\', '/', '')
41 elseif has('win32')
42 return substitute(a:path, '/', '\\', '')
43 else
44 return a:path
45 endif
46 endfunction
47
48 " Prints a message if debug tracing is enabled.
24 function! s:trace(message) 49 function! s:trace(message)
25 if g:lawrencium_trace 50 if g:lawrencium_trace
26 let l:message = "lawrencium: " . a:message 51 let l:message = "lawrencium: " . a:message
52 echom l:message
27 endif 53 endif
28 endfunction 54 endfunction
29 55
56 " Throw a Lawrencium exception message.
30 function! s:throw(message) 57 function! s:throw(message)
31 let v:errmsg = "lawrencium: " . a:message 58 let v:errmsg = "lawrencium: " . a:message
32 throw v:errmsg 59 throw v:errmsg
33 endfunction 60 endfunction
34 61
62 " Finds the repository root given a path inside that repository.
63 " Throw an error if not repository is found.
35 function! s:find_repo_root(path) 64 function! s:find_repo_root(path)
36 let l:path = s:stripslash(a:path) 65 let l:path = s:stripslash(a:path)
37 while l:path != "" 66 let l:previous_path = ""
67 while l:path != l:previous_path
38 if isdirectory(l:path . '/.hg/store') 68 if isdirectory(l:path . '/.hg/store')
39 return simplify(fnamemodify(l:path, ':p')) 69 return simplify(fnamemodify(l:path, ':p'))
40 endif 70 endif
71 let l:previous_path = l:path
41 let l:path = fnamemodify(l:path, ':h') 72 let l:path = fnamemodify(l:path, ':h')
42 endwhile 73 endwhile
43 call s:throw("No Mercurial repository found above: " . a:path) 74 call s:throw("No Mercurial repository found above: " . a:path)
44 endfunction 75 endfunction
45 76
61 return l:newRepo 92 return l:newRepo
62 endfunction 93 endfunction
63 94
64 " Gets a full path given a repo-relative path 95 " Gets a full path given a repo-relative path
65 function! s:HgRepo.GetFullPath(path) abort 96 function! s:HgRepo.GetFullPath(path) abort
66 let l:path = self.root_dir 97 let l:root_dir = self.root_dir
67 if a:path =~# '^/' 98 if a:path =~# '^[/\\]'
68 let l:path = s:stripslash(self.root_dir) 99 let l:root_dir = s:stripslash(l:root_dir)
69 endif 100 endif
70 return l:path . a:path 101 return l:root_dir . a:path
102 endfunction
103
104 " Gets a list of files matching a root-relative pattern.
105 " If a flag is passed and is TRUE, a slash will be appended to all
106 " directories.
107 function! s:HgRepo.Glob(pattern, ...) abort
108 let l:root_dir = self.root_dir
109 if (a:pattern =~# '^[/\\]')
110 let l:root_dir = s:stripslash(l:root_dir)
111 endif
112 let l:matches = split(glob(l:root_dir . a:pattern), '\n')
113 if a:0 && a:1
114 for l:idx in range(len(l:matches))
115 if !filereadable(l:matches[l:idx])
116 let l:matches[l:idx] = l:matches[l:idx] . '/'
117 endif
118 endfor
119 endif
120 let l:strip_len = len(l:root_dir)
121 call map(l:matches, 'v:val[l:strip_len : -1]')
122 return l:matches
71 endfunction 123 endfunction
72 124
73 " Runs a Mercurial command in the repo 125 " Runs a Mercurial command in the repo
74 function! s:HgRepo.RunCommand(command, ...) abort 126 function! s:HgRepo.RunCommand(command, ...) abort
75 let l:hg_command = g:lawrencium_hg_executable . ' --repository ' . shellescape(self.root_dir) 127 let l:hg_command = g:lawrencium_hg_executable . ' --repository ' . shellescape(s:stripslash(self.root_dir))
76 let l:hg_command = l:hg_command . ' ' . a:command . ' ' . join(a:000, ' ') 128 let l:hg_command = l:hg_command . ' ' . a:command . ' ' . join(a:000, ' ')
77 call s:trace("Running Mercurial command: " . l:hg_command) 129 call s:trace("Running Mercurial command: " . l:hg_command)
78 return system(l:hg_command) 130 return system(l:hg_command)
79 endfunction 131 endfunction
80 132
104 endfunction 156 endfunction
105 157
106 " Sets up the current buffer with Lawrencium commands if it contains a file from a Mercurial repo. 158 " Sets up the current buffer with Lawrencium commands if it contains a file from a Mercurial repo.
107 " If the file is not in a Mercurial repo, just exit silently. 159 " If the file is not in a Mercurial repo, just exit silently.
108 function! s:setup_buffer_commands() abort 160 function! s:setup_buffer_commands() abort
161 call s:trace("Scanning buffer '" . bufname('%') . "' for Lawrencium setup...")
109 let l:do_setup = 1 162 let l:do_setup = 1
110 if exists('b:mercurial_dir') 163 if exists('b:mercurial_dir')
111 if b:mercurial_dir =~# '/^\s*$/' 164 if b:mercurial_dir =~# '/^\s*$/'
112 unlet b:mercurial_dir 165 unlet b:mercurial_dir
113 else 166 else
119 catch /^lawrencium\:/ 172 catch /^lawrencium\:/
120 return 173 return
121 endtry 174 endtry
122 let b:mercurial_dir = l:repo.root_dir 175 let b:mercurial_dir = l:repo.root_dir
123 if exists('b:mercurial_dir') && l:do_setup 176 if exists('b:mercurial_dir') && l:do_setup
124 call s:trace("Setting Mercurial commands for buffer '" . bufname('%') . "' with repo : " . expand(b:mercurial_dir)) 177 call s:trace("Setting Mercurial commands for buffer '" . bufname('%'))
178 call s:trace(" with repo : " . expand(b:mercurial_dir))
125 silent doautocmd User Lawrencium 179 silent doautocmd User Lawrencium
126 endif 180 endif
127 endfunction 181 endfunction
128 182
129 augroup lawrencium_detect 183 augroup lawrencium_detect
141 function! s:AddMainCommand(command) abort 195 function! s:AddMainCommand(command) abort
142 let s:main_commands += [a:command] 196 let s:main_commands += [a:command]
143 endfunction 197 endfunction
144 198
145 function! s:DefineMainCommands() 199 function! s:DefineMainCommands()
146 for command in s:main_commands 200 for l:command in s:main_commands
147 execute 'command! -buffer '.command 201 execute 'command! -buffer ' . l:command
148 endfor 202 endfor
149 endfunction 203 endfunction
150 204
151 augroup lawrencium_main 205 augroup lawrencium_main
152 autocmd! 206 autocmd!
177 " }}} 231 " }}}
178 232
179 " Hgcd, Hglcd {{{ 233 " Hgcd, Hglcd {{{
180 234
181 function! s:ListRepoDirs(ArgLead, CmdLine, CursorPos) abort 235 function! s:ListRepoDirs(ArgLead, CmdLine, CursorPos) abort
182 let l:root_dir = s:hg_repo().root_dir 236 let l:matches = s:hg_repo().Glob(a:ArgLead . '*/')
183 if (a:ArgLead =~# '^/') 237 call map(l:matches, 's:normalizepath(v:val)')
184 let l:root_dir = s:stripslash(l:root_dir)
185 endif
186 let l:matches = split(glob(l:root_dir . a:ArgLead . '*'), '\n')
187 let l:strip_len = len(l:root_dir)
188 call map(l:matches, 'v:val[l:strip_len : -1] . "/"')
189 return l:matches 238 return l:matches
190 endfunction 239 endfunction
191 240
192 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hgcd :cd<bang> `=s:hg_repo().GetFullPath(<q-args>)`") 241 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hgcd :cd<bang> `=s:hg_repo().GetFullPath(<q-args>)`")
193 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hglcd :lcd<bang> `=s:hg_repo().GetFullPath(<q-args>)`") 242 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hglcd :lcd<bang> `=s:hg_repo().GetFullPath(<q-args>)`")
194 243
195 " }}} 244 " }}}
196 245
246 " Hgedit {{{
247
248 function! s:ListRepoFiles(ArgLead, CmdLine, CursorPos) abort
249 let l:matches = s:hg_repo().Glob(a:ArgLead . '*', 1)
250 call map(l:matches, 's:normalizepath(v:val)')
251 return l:matches
252 endfunction
253
254 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoFiles Hgedit :edit<bang> `=s:hg_repo().GetFullPath(<q-args>)`")
255
256 " }}}
257
197 " Autoload Functions {{{ 258 " Autoload Functions {{{
198 259
260 " Prints a summary of the current repo (if any) that's appropriate for
261 " displaying on the status line.
199 function! lawrencium#statusline(...) 262 function! lawrencium#statusline(...)
200 if !exists('b:mercurial_dir') 263 if !exists('b:mercurial_dir')
201 return '' 264 return ''
202 endif 265 endif
203 let l:summary = s:hg_repo().RunCommand('summary') 266 let l:summary = s:hg_repo().RunCommand('summary')
204 let l:parent_rev = matchstr(l:summary, 'parent\: \d+\:[0-9a-f]+') 267 let l:parent_rev = matchstr(l:summary, 'parent\: \d+\:[0-9a-f]+')
205 let l:branch = matchstr(l:summary, 'branch\: [\d\w\-_\.]+') 268 let l:branch = matchstr(l:summary, 'branch\: [\d\w\-_\.]+')
206 return l:branch . ', ' . l:parent_rev 269 return l:branch . ', ' . l:parent_rev
207 endfunction 270 endfunction
208 271
209 " }}} 272 " Rescans the current buffer for setting up Mercurial commands.
210 273 " Passing '1' as the parameter enables debug traces temporarily.
274 function! lawrencium#rescan(...)
275 if exists('b:mercurial_dir')
276 unlet b:mercurial_dir
277 endif
278 if a:0 && a:1
279 let l:trace_backup = g:lawrencium_trace
280 let g:lawrencium_trace = 1
281 endif
282 call s:setup_buffer_commands()
283 if a:0 && a:1
284 let g:lawrencium_trace = l:trace_backup
285 endif
286 endfunction
287
288 " Enables/disables the debug trace.
289 function! lawrencium#debugtrace(...)
290 let g:lawrencium_trace = (a:0 == 0 || (a:0 && a:1))
291 echom "Lawrencium debug trace is now " . (g:lawrencium_trace ? "enabled." : "disabled.")
292 endfunction
293
294 " }}}
295