Mercurial > dotfiles
comparison vim/bundle/lawrencium/plugin/lawrencium.vim @ 51:a6bc310e7015
First version of lawrencium plugin.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 07 Dec 2011 23:32:39 -0800 |
parents | |
children | 05fd225bd1a0 |
comparison
equal
deleted
inserted
replaced
50:30c36bc04926 | 51:a6bc310e7015 |
---|---|
1 " lawrencium.vim - A Mercurial wrapper | |
2 " Maintainer: Ludovic Chabant <http://ludovic.chabant.com> | |
3 " Version: 0.1 | |
4 | |
5 if exists('g:loaded_lawrencium') || &cp | |
6 " finish | |
7 endif | |
8 let g:loaded_lawrencium = 1 | |
9 | |
10 if !exists('g:lawrencium_hg_executable') | |
11 let g:lawrencium_hg_executable = 'hg' | |
12 endif | |
13 | |
14 if !exists('g:lawrencium_trace') | |
15 let g:lawrencium_trace = 0 | |
16 endif | |
17 | |
18 " Utility {{{ | |
19 | |
20 function! s:stripslash(path) | |
21 return fnamemodify(a:path, ':s?[\/]$??') | |
22 endfunction | |
23 | |
24 function! s:trace(message) | |
25 if g:lawrencium_trace | |
26 let l:message = "lawrencium: " . a:message | |
27 endif | |
28 endfunction | |
29 | |
30 function! s:throw(message) | |
31 let v:errmsg = "lawrencium: " . a:message | |
32 throw v:errmsg | |
33 endfunction | |
34 | |
35 function! s:find_repo_root(path) | |
36 let l:path = s:stripslash(a:path) | |
37 while l:path != "" | |
38 if isdirectory(l:path . '/.hg/store') | |
39 return simplify(fnamemodify(l:path, ':p')) | |
40 endif | |
41 let l:path = fnamemodify(l:path, ':h') | |
42 endwhile | |
43 call s:throw("No Mercurial repository found above: " . a:path) | |
44 endfunction | |
45 | |
46 " }}} | |
47 | |
48 " Mercurial Repository {{{ | |
49 | |
50 " Let's define a Mercurial repo 'class' using prototype-based object-oriented | |
51 " programming. | |
52 " | |
53 " The prototype dictionary. | |
54 let s:HgRepo = {} | |
55 | |
56 " Constructor | |
57 function! s:HgRepo.New(path) abort | |
58 let l:newRepo = copy(self) | |
59 let l:newRepo.root_dir = s:find_repo_root(a:path) | |
60 call s:trace("Built new Mercurial repository object at : " . l:newRepo.root_dir) | |
61 return l:newRepo | |
62 endfunction | |
63 | |
64 " Sets up the current buffer with local variables | |
65 function! s:HgRepo.SetupBuffer() abort | |
66 if exists('b:mercurial_dir') && (b:mercurial_dir =~# '/^\s*$/') | |
67 unlet b:mercurial_dir | |
68 endif | |
69 if !exists('b:mercurial_dir') | |
70 let b:mercurial_dir = self.root_dir | |
71 endif | |
72 if exists('b:mercurial_dir') | |
73 call s:trace("Setting Mercurial directory to : " . expand(b:mercurial_dir)) | |
74 silent doautocmd User Lawrencium | |
75 endif | |
76 endfunction | |
77 | |
78 " Gets a full path given a repo-relative path | |
79 function! s:HgRepo.GetFullPath(path) abort | |
80 let l:path = self.root_dir | |
81 if a:path =~# '^/' | |
82 let l:path = s:stripslash(self.root_dir) | |
83 endif | |
84 return l:path . a:path | |
85 endfunction | |
86 | |
87 " Runs a Mercurial command in the repo | |
88 function! s:HgRepo.RunCommand(command, ...) abort | |
89 let l:hg_command = g:lawrencium_hg_executable . ' --repository ' . shellescape(self.root_dir) | |
90 let l:hg_command = l:hg_command . ' ' . a:command . ' ' . join(a:000, ' ') | |
91 call s:trace("Running Mercurial command: " . l:hg_command) | |
92 return system(l:hg_command) | |
93 endfunction | |
94 | |
95 " Repo cache map | |
96 let s:buffer_repos = {} | |
97 | |
98 " Get a cached repo | |
99 function! s:hg_repo(...) abort | |
100 " Use the given path, or the mercurial directory of the current buffer. | |
101 if a:0 == 0 | |
102 if exists('b:mercurial_dir') | |
103 let l:path = b:mercurial_dir | |
104 else | |
105 let l:path = s:find_repo_root(expand('%:p')) | |
106 let b:mercurial_dir = l:path | |
107 endif | |
108 else | |
109 let l:path = a:1 | |
110 endif | |
111 " Find a cache repo instance, or make a new one. | |
112 if has_key(s:buffer_repos, l:path) | |
113 return get(s:buffer_repos, l:path) | |
114 else | |
115 let l:repo = s:HgRepo.New(l:path) | |
116 let s:buffer_repos[l:path] = l:repo | |
117 return l:repo | |
118 endif | |
119 endfunction | |
120 | |
121 augroup lawrencium_detect | |
122 autocmd! | |
123 " autocmd BufNewFile,BufReadPost * call s:DetectMercurialRepository(expand('<amatch>:p')) | |
124 " autocmd VimEnter * if expand('<amatch>')==''|call s:DetectMercurialRepository(getcwd())|endif | |
125 augroup end | |
126 | |
127 " }}} | |
128 | |
129 " Commands {{{ | |
130 | |
131 let s:main_commands = [] | |
132 | |
133 function! s:AddMainCommand(command) abort | |
134 let s:main_commands += [a:command] | |
135 endfunction | |
136 | |
137 function! s:DefineMainCommands() | |
138 for command in s:main_commands | |
139 execute 'command! -buffer '.command | |
140 endfor | |
141 endfunction | |
142 | |
143 augroup lawrencium_main | |
144 autocmd! | |
145 autocmd User Lawrencium call s:DefineMainCommands() | |
146 augroup end | |
147 | |
148 " }}} | |
149 | |
150 " HgExecute {{{ | |
151 | |
152 function! s:HgExecute(...) abort | |
153 let l:repo = s:hg_repo() | |
154 echo call(l:repo.RunCommand, a:000, l:repo) | |
155 endfunction | |
156 | |
157 call s:AddMainCommand("-nargs=* Hg :execute s:HgExecute(<f-args>)") | |
158 | |
159 " }}} | |
160 | |
161 " HgStatus {{{ | |
162 | |
163 function! s:HgStatus() abort | |
164 echo s:hg_repo().RunCommand('status') | |
165 endfunction | |
166 | |
167 call s:AddMainCommand("HgStatus :execute s:HgStatus()") | |
168 | |
169 " }}} | |
170 | |
171 " Hgcd, Hglcd {{{ | |
172 | |
173 function! s:ListRepoDirs(ArgLead, CmdLine, CursorPos) abort | |
174 let l:root_dir = s:hg_repo().root_dir | |
175 if (a:ArgLead =~# '^/') | |
176 let l:root_dir = s:stripslash(l:root_dir) | |
177 endif | |
178 let l:matches = split(glob(l:root_dir . a:ArgLead . '*'), '\n') | |
179 let l:strip_len = len(l:root_dir) | |
180 call map(l:matches, 'v:val[l:strip_len : -1] . "/"') | |
181 return l:matches | |
182 endfunction | |
183 | |
184 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hgcd :cd<bang> `=s:hg_repo().GetFullPath(<q-args>)`") | |
185 call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hglcd :lcd<bang> `=s:hg_repo().GetFullPath(<q-args>)`") | |
186 | |
187 " }}} | |
188 | |
189 " Autoload Functions {{{ | |
190 | |
191 function! lawrencium#statusline(...) | |
192 if !exists('b:mercurial_dir') | |
193 return '' | |
194 endif | |
195 let l:summary = s:hg_repo().RunCommand('summary') | |
196 let l:parent_rev = matchstr(l:summary, 'parent\: \d+\:[0-9a-f]+') | |
197 let l:branch = matchstr(l:summary, 'branch\: [\d\w\-_\.]+') | |
198 return l:branch . ', ' . l:parent_rev | |
199 endfunction | |
200 | |
201 " }}} | |
202 |