簡體   English   中英

來自 vim 的 git blame 自定義腳本

[英]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

在你的函數結束時。

對於下一個問題,您可以使用executeeval

noremap <leader>b :execute "Shell git blame -L " . eval(line(".")-5)) . ",+10 %"<cr>

我建議閱讀這些描述,並help一般help


這里也是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' 的結果放入較低的緩沖區(緩沖區被置於只讀模式),您的光標將位於blame緩沖區(當前源文件中的行)
  • 而在下部緩沖區中: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: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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM