自定义脚本git责备从vim

  • 本文关键字:vim 脚本 git 自定义 vim
  • 更新时间 :
  • 英文 :


我想从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

在函数的末尾。

对于下一个问题,您可以使用executeeval

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目录。依据

最新更新