[英]Custom script for git blame from vim
我想要從 vim 中使用 git blame 的最小方式(我不想使用整個 Fugative 插件)。 我現在所擁有的是:
這個函數來自 vim 幫助頁面,它使我能夠在臨時緩沖區中打開 shellcomands。
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 blame 窗口。
現在我有兩個問題:
1:如何將打開的暫存緩沖區設為只讀,以便僅使用 q 關閉它? 我想在函數中進行此更改,以便可以使用 q 關閉所有 :Shell 命令。
2:我怎樣才能得到 line(".") - 5 擴展到當前行 - 5 行號?
要使緩沖區只讀且不可修改,您可以將
setlocal readonly nomodifiable
在你的函數結束時。
對於下一個問題,您可以使用execute
和eval
noremap <leader>b :execute "Shell git blame -L " . eval(line(".")-5)) . ",+10 %"<cr>
我建議閱讀這些描述,並help
一般help
:
我使用一個簡單的 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 文件中。
"======================================================
" 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:fname=expand('#'.winbufnr(a:origWindow).':p:.')
let l:fname_dir=expand("%:h")
let l:origLine=line('.', win_getid(a:origWindow))
sil exe a:view . " | setl buftype=nofile bufhidden=wipe | 0r ! git blame " . l:fname
setl nomodifiable
setl nonumber norelativenumber
if v:shell_error != 0
exe l:origWindow . "wincmd w"
return
end
exe "lcd ".l:fname_dir
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 目錄中,命令也能工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.