Mercurial > dotfiles
view 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 source
" 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 " }}}