我想从vim使用git责备的最小方式(我不想使用整个逃犯插件)。我现在的代码是:
这个函数来自vim帮助页面,使我能够在临时缓冲区中打开shell命令。
function! s:ExecuteInShell(command)
let command = join(map(split(a:command), 'expand(v:val)'))
let winnr = bufwinnr('^' . command . '$')
silent! execute winnr < 0 ? 'botright new ' . fnameescape(command) : winnr . 'wincmd w'
setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
echo 'Execute ' . command . '...'
silent! execute 'silent %!'. command
silent! execute 'resize ' . line('$')
silent! redraw
silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
echo 'Shell command ' . command . ' executed.'
endfunction
command! -complete=shellcmd -nargs=+ Shell call s:ExecuteInShell(<q-args>)
结合上面的函数,我想做:
noremap <leader>b :Shell git blame -L line(".") - 5, line(".") + 5 %<cr>
获取当前缓冲区中光标位置周围行的git责备窗口。
现在我有两个问题:
1:我如何使刮痕缓冲区只读打开,这样我就可以使用q关闭它?我想在函数中做这个改变,这样所有的:Shell命令都可以用q结束。
2:如何将line(".") - 5扩展到当前行- 5行号?
要使缓冲区只读且不可修改,可以将
setlocal readonly nomodifiable
在函数的末尾。
对于下一个问题,您可以使用execute
和eval
noremap <leader>b :execute "Shell git blame -L " . eval(line(".")-5)) . ",+10 %"<cr>
我建议阅读这些描述,以及help
的总体:
-
:h execute
-
:h eval
-
:h readonly
-
:h nomodifiable
这里还有wikia上提到的函数的链接
我使用一个简单的hack来获得我的vim git集成:这解决了我的git commit/add, blame和op.
map <F5> :!git add %;git commit -m "commit" %<CR>
map <F3> :!git blame % > %.blame<CR>:vsplit %.blame<CR>
map <F4> :!git log --abbrev-commit % > %.log<CR>:vsplit %.log<CR>
我这里有一些东西,脚本可以复制并添加到.vimrc文件中。
- 命令Blame将在当前文件上运行git Blame,将屏幕分割并将'git Blame -w'的结果放入下缓冲区(缓冲区设置为只读模式),您的光标将位于责备缓冲区(当前行与源文件中相同)
- 当在较低的缓冲区时:GShow将分割较低的屏幕并打开提交'git show -w [hash]',用于当前行在右侧缓冲区(再次以只读模式缓冲)。
"======================================================
" Function runs git blame on file in current buffer and
" puts output into a new window
" move to current line in git output
" (can't edit output)
"======================================================
command! -nargs=* Blame call s:GitBlame()
function! s:GitBlame()
let cmdline = "git blame -w " . bufname("%")
let nline = line(".") + 1
botright new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
execute "$read !" . cmdline
setlocal nomodifiable
execute "normal " . nline . "gg"
execute "set filetype=cpp"
endfunction
"======================================================
" function runs git show on report of git blame;
" the first token of a line is taken as SHA checsum of the
" git commit
"======================================================
command! -nargs=* GShow call s:GitShowFromBlame()
function! s:GitShowFromBlame()
let curline = getline( "." )
let tokens = split(curline)
let cmdline = "git show -w " . tokens[0]
"botright new
"topleft new
"vsplit new
"vnew new
vertical new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
execute "$read !" . cmdline
setlocal nomodifiable
execute "normal 1gg"
execute "set filetype=cpp"
endfunction
我的看法
fun! GbSyncLines(is_ow2bw)
let l:ow = getbufvar(+expand('<abuf>'), 'origWindow')
let l:bw = getbufvar(+expand('<abuf>'), 'blameWindow')
let l:origLine=line('.', win_getid(l:ow))
let l:blameLine=line('.', win_getid(l:bw))
if a:is_ow2bw == 1
eval win_execute(win_getid(l:bw), "windo call cursor(" . l:origLine . ", 0)")
else
eval win_execute(win_getid(l:ow), "windo call cursor(" . l:blameLine . ", 0)")
endif
endfun
fun! GbMake(view, origWindow)
let l:origWindow=a:origWindow
let l:file_dir=expand('#'.winbufnr(a:origWindow).':h')
let l:file_name=expand('#'.winbufnr(a:origWindow).':t')
let l:origLine=line('.', win_getid(a:origWindow))
sil exe a:view
setl buftype=nofile bufhidden=wipe
exe "lcd ".l:file_dir
exe "0r ! git blame " . l:file_name
setl nomodifiable
setl nonumber norelativenumber
if v:shell_error != 0
exe l:origWindow . "wincmd w"
return
end
eval searchpos('(')
eval searchpairpos('(', '', ')')
norm! gE
exe "vertical resize " . col('.')
let l:blameWindow = winnr()
let b:blameWindow = winnr()
let b:origWindow = a:origWindow
let l:origLine=line('.', win_getid(b:origWindow))
eval cursor(l:origLine , 1)
nnoremap <buffer> <C-]> :call GcommitShow(expand("<cword>"), line(".")) <CR>
au BufWipeout <buffer> call win_execute(win_getid(getbufvar(+expand('<abuf>'), 'origWindow')), "windo setl scrollbind&")
au WinEnter <buffer> :call GbSyncLines(1)
au WinLeave <buffer> :call GbSyncLines(0)
setl scrollbind
exe a:origWindow . "wincmd w"
setl scrollbind
exe "syncbind"
if a:view == "enew"
exe l:blameWindow . "wincmd w"
end
endfun
fun! GcommitShowClose()
let l:w=getbufvar(expand('<abuf>'), 'origWindow')
let l:l=getbufvar(expand('<abuf>'), 'origLine')
let l:v=getbufvar(expand('<abuf>'), 'origView')
eval GbMake("enew", l:w)
eval winrestview(l:v)
eval cursor(l:l, 1)
endfun
fun! GcommitShow(commit, linenr)
let l:origWindow=b:origWindow
let l:viewsave=winsaveview()
sil exe "enew | setlocal buftype=nofile | setlocal bufhidden=wipe | 0r ! git show " . a:commit
setl nomodifiable
setl nonumber norelativenumber
if v:shell_error != 0
eval GbMake('enew', l:origWindow)
return
end
let b:origWindow=l:origWindow
let b:origLine=a:linenr
let b:origView=l:viewsave
nnoremap <buffer> <C-O> :call GcommitShowClose()<CR>
eval cursor(1, 1)
endfun
fun! Gb()
eval GbMake('vnew', winnr())
endfun
command! Gb call Gb()
而在责备窗口,CTRL+]快捷键将显示git show为提交光标是在。然后CTRL+O将返回到git责备。注意lcd上的启动命令将工作,即使你不在git目录。依据