Mercurial > dotfiles
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 |