Mercurial > dotfiles
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vim/bundle/lawrencium/plugin/lawrencium.vim Wed Dec 07 23:32:39 2011 -0800 @@ -0,0 +1,202 @@ +" lawrencium.vim - A Mercurial wrapper +" Maintainer: Ludovic Chabant <http://ludovic.chabant.com> +" Version: 0.1 + +if exists('g:loaded_lawrencium') || &cp + " finish +endif +let g:loaded_lawrencium = 1 + +if !exists('g:lawrencium_hg_executable') + let g:lawrencium_hg_executable = 'hg' +endif + +if !exists('g:lawrencium_trace') + let g:lawrencium_trace = 0 +endif + +" Utility {{{ + +function! s:stripslash(path) + return fnamemodify(a:path, ':s?[\/]$??') +endfunction + +function! s:trace(message) + if g:lawrencium_trace + let l:message = "lawrencium: " . a:message + endif +endfunction + +function! s:throw(message) + let v:errmsg = "lawrencium: " . a:message + throw v:errmsg +endfunction + +function! s:find_repo_root(path) + let l:path = s:stripslash(a:path) + while l:path != "" + if isdirectory(l:path . '/.hg/store') + return simplify(fnamemodify(l:path, ':p')) + endif + let l:path = fnamemodify(l:path, ':h') + endwhile + call s:throw("No Mercurial repository found above: " . a:path) +endfunction + +" }}} + +" Mercurial Repository {{{ + +" Let's define a Mercurial repo 'class' using prototype-based object-oriented +" programming. +" +" The prototype dictionary. +let s:HgRepo = {} + +" Constructor +function! s:HgRepo.New(path) abort + let l:newRepo = copy(self) + let l:newRepo.root_dir = s:find_repo_root(a:path) + call s:trace("Built new Mercurial repository object at : " . l:newRepo.root_dir) + return l:newRepo +endfunction + +" Sets up the current buffer with local variables +function! s:HgRepo.SetupBuffer() abort + if exists('b:mercurial_dir') && (b:mercurial_dir =~# '/^\s*$/') + unlet b:mercurial_dir + endif + if !exists('b:mercurial_dir') + let b:mercurial_dir = self.root_dir + endif + if exists('b:mercurial_dir') + call s:trace("Setting Mercurial directory to : " . expand(b:mercurial_dir)) + silent doautocmd User Lawrencium + endif +endfunction + +" Gets a full path given a repo-relative path +function! s:HgRepo.GetFullPath(path) abort + let l:path = self.root_dir + if a:path =~# '^/' + let l:path = s:stripslash(self.root_dir) + endif + return l:path . a:path +endfunction + +" Runs a Mercurial command in the repo +function! s:HgRepo.RunCommand(command, ...) abort + let l:hg_command = g:lawrencium_hg_executable . ' --repository ' . shellescape(self.root_dir) + let l:hg_command = l:hg_command . ' ' . a:command . ' ' . join(a:000, ' ') + call s:trace("Running Mercurial command: " . l:hg_command) + return system(l:hg_command) +endfunction + +" Repo cache map +let s:buffer_repos = {} + +" Get a cached repo +function! s:hg_repo(...) abort + " Use the given path, or the mercurial directory of the current buffer. + if a:0 == 0 + if exists('b:mercurial_dir') + let l:path = b:mercurial_dir + else + let l:path = s:find_repo_root(expand('%:p')) + let b:mercurial_dir = l:path + endif + else + let l:path = a:1 + endif + " Find a cache repo instance, or make a new one. + if has_key(s:buffer_repos, l:path) + return get(s:buffer_repos, l:path) + else + let l:repo = s:HgRepo.New(l:path) + let s:buffer_repos[l:path] = l:repo + return l:repo + endif +endfunction + +augroup lawrencium_detect + autocmd! +" autocmd BufNewFile,BufReadPost * call s:DetectMercurialRepository(expand('<amatch>:p')) +" autocmd VimEnter * if expand('<amatch>')==''|call s:DetectMercurialRepository(getcwd())|endif +augroup end + +" }}} + +" Commands {{{ + +let s:main_commands = [] + +function! s:AddMainCommand(command) abort + let s:main_commands += [a:command] +endfunction + +function! s:DefineMainCommands() + for command in s:main_commands + execute 'command! -buffer '.command + endfor +endfunction + +augroup lawrencium_main + autocmd! + autocmd User Lawrencium call s:DefineMainCommands() +augroup end + +" }}} + +" HgExecute {{{ + +function! s:HgExecute(...) abort + let l:repo = s:hg_repo() + echo call(l:repo.RunCommand, a:000, l:repo) +endfunction + +call s:AddMainCommand("-nargs=* Hg :execute s:HgExecute(<f-args>)") + +" }}} + +" HgStatus {{{ + +function! s:HgStatus() abort + echo s:hg_repo().RunCommand('status') +endfunction + +call s:AddMainCommand("HgStatus :execute s:HgStatus()") + +" }}} + +" Hgcd, Hglcd {{{ + +function! s:ListRepoDirs(ArgLead, CmdLine, CursorPos) abort + let l:root_dir = s:hg_repo().root_dir + if (a:ArgLead =~# '^/') + let l:root_dir = s:stripslash(l:root_dir) + endif + let l:matches = split(glob(l:root_dir . a:ArgLead . '*'), '\n') + let l:strip_len = len(l:root_dir) + call map(l:matches, 'v:val[l:strip_len : -1] . "/"') + return l:matches +endfunction + +call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hgcd :cd<bang> `=s:hg_repo().GetFullPath(<q-args>)`") +call s:AddMainCommand("-bang -nargs=? -complete=customlist,s:ListRepoDirs Hglcd :lcd<bang> `=s:hg_repo().GetFullPath(<q-args>)`") + +" }}} + +" Autoload Functions {{{ + +function! lawrencium#statusline(...) + if !exists('b:mercurial_dir') + return '' + endif + let l:summary = s:hg_repo().RunCommand('summary') + let l:parent_rev = matchstr(l:summary, 'parent\: \d+\:[0-9a-f]+') + let l:branch = matchstr(l:summary, 'branch\: [\d\w\-_\.]+') + return l:branch . ', ' . l:parent_rev +endfunction + +" }}} +