Vim - 在Mercurial中显示提交差异

4
在我的.hgrc文件中,我可以提供一个编辑器或命令来在提交时启动编辑器选项。
我想编写一个方法或别名来启动$ hg ci,它不仅会在Vim中打开消息,还会分割窗口并打印出$ hg diff
我知道可以使用+{command}选项向vim传递参数。因此,启动$ vim "+vsplit"会分割窗口,但是任何其他选项都会进入第一个打开的窗口。因此,我认为需要一个特定的函数,但我没有编写自己的Vim脚本的经验。
脚本应该:
  • 使用空缓冲区打开新的垂直分割(可能使用vnew
  • 在空缓冲区中启动:.!hg diff
  • 将空缓冲区文件类型设置为diff :set ft=diff
我已经编写了这样的函数:
function! HgCiDiff()
    vnew
    :.!hg diff
    set ft=diff
endfunction

.hgrc文件中,我添加了选项:editor = vim "+HgCiDiff()"。它有点起作用,但我希望分割窗口在右侧(现在是左侧打开),并且Mercurial消息应该成为焦点窗口。此外,:wq可以设置为临时快捷键:wq<CR>:q!(假设Mercurial消息是焦点)。如何使其更加实用且不那么笨重?更新:我找到了vim分割指南,因此将vnew更改为rightbelow vnew将在右侧打开差异。

你可能想要做类似于 silent! setlocal ft=diff previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile 这样的操作,而不仅仅是 set ft=diff(来自 ~/.vim/ftplugin/svn.vim)。此外,最好在编辑与 /tmp/hg-editor-*.txt 匹配的文件时运行它,即将其设置为自动命令。 - Marius Gedminas
啊,我不知道你可以这样嵌套设置参数。很棒。 - JackLeo
相关问题 https://dev59.com/mk3Sa4cB1Zd3GeqPuFG0 - anatoly techtonik
4个回答

5

所以我扩展了自己的代码:

function! HgCiDiff()
    "In .hgrc editor option I call vim "+HgCiDiff()"
    "It opens new split with diff inside
    rightbelow  vnew
    :.!hg diff
    set ft=diff
    saveas! /tmp/hgdiff.txt
    execute "normal \<c-w>w"
endfunction

然而,它错过了将:wq映射为:wqa,但使用:wqa并不难。

我的vimrc的源代码在这里:http://hg.jackleo.info/vim-configs/src/08df5cb9d143/vimrc
我的hgrc的源代码在这里:http://hg.jackleo.info/home-configs/src/22f5fb47a7d2/.hgrc

更新:根据Randy Morris的建议,我更新了我的代码,现在它正如我所期望的那样工作。谢谢!还添加了一些额外的功能。

function! HgCiDiff()
    "In .hgrc editor option I call vim "+HgCiDiff()"
    "It opens new split with diff inside
    rightbelow  vnew
    setlocal buftype=nofile
    :.!hg diff
    setlocal ft=diff
    wincmd p
    setlocal spell spelllang=en_us
    cnoremap wq wqa
    cnoremap q qa
    start
endfunction

1
几点注释: 1)最后一行可以改为“wincmd w”或更正确的是“wincmd p”,两者都可以。 2)对于文件类型,您可能希望使用“setlocal”而不仅仅是“set”。 3)除非您明确想将差异保存到/tmp/hgdiff.txt,否则您可以使用“setlocal buftype=nofile”。 - Randy Morris
1
而且4)您可以添加“cnoremap wq wqa”来实现最后一个目标。(无法编辑先前的评论) - Randy Morris

3

编辑

嗯,我想这可能不是你在第二次阅读时想要的。我理解你想要一个多文件(统一)差异。我真的会使用一个 hg-aware UI 工具和一个单独的 vim 编辑器来进行提交消息。对此我感到抱歉。

我将保留“原始”回复,以防你还不知道 VCSCommand + Hg + Vim:

我的选择武器是用

vcscommand.vim:CVS/SVN/SVK/git/hg/bzr 集成插件

你会

:VCSVimDiff

使用Leadercv命令可以将文件与仓库版本进行区分对比,也可以使用diffsplit命令实现此功能。

:VCSVimDiff <revid>

对比特定版本。


谢谢,不,我还不知道VCSCommand,它是一个很棒的工具,但你说得对。这不是我要找的 :) - JackLeo

1

我的解决方案由三个vim文件组成。它不需要hg配置更改,仅在您提交文件时显示差异,如果您使用了hg commit file1 file2

~/.vim/ftdetect/hg.vim

au BufRead,BufNewFile /tmp/hg-editor-*.txt set filetype=hg

~/.vim/syntax/hg.vim

" Vim syntax file
" Language: hg commit file
" Maintainer:   Marius Gedminas <marius@gedmin.as>
" Filenames:    /tmp/hg-editor-*.txt
" Last Change:  2012 July 8

" Based on gitcommit.vim by Tim Pope

if exists("b:current_syntax")
  finish
endif

syn case match
syn sync minlines=50

if has("spell")
  syn spell toplevel
endif

syn match   hgComment   "^HG: .*"

hi def link hgComment       Comment

let b:current_syntax = "hg"

~/.vim/ftplugin/hg.vim

" Show diff while editing a Mercurial commit message
" Inspired by https://dev59.com/fVzUa4cB1Zd3GeqP7uYh
" and Michael Scherer' svn.vim

function! HgCiDiff()
    let i = 0
    let list_of_files = ''

    while i <= line('$') && getline(i) != 'HG: --'
        let i = i + 1
    endwhile
    while i <= line('$')
        let line = getline(i)
        if line =~ '^HG: \(added\|changed\)'
            let file = substitute(line, '^HG: \(added\|changed\) ', '', '')
            let file = "'".substitute(file, "'", "'\''", '')."'"
            let list_of_files = list_of_files . ' '.file
        endif
        let i = i + 1
    endwhile

    if list_of_files == ""
        return
    endif

    pclose
    new
    setlocal ft=diff previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile
    silent exec ':0r!hg diff ' . list_of_files
    setlocal nomodifiable
    goto 1
    redraw!
    " nooo idea why I have to do this
    syn enable
endfunction

call HgCiDiff()

第一个版本存在一个可怕的错误,它假设hg会忽略'HG:'注释块后面的所有内容,并将差异直接包含在同一缓冲区中(就像git commit -v一样)。这使得hg在提交消息中包含了整个差异。糟糕。 - Marius Gedminas
通过一些补充内容,我可以看到我会使用这个 :) 其中之一是拼写检查设置 setlocal spell spelllang=en_us 同时,我也更新了自己的代码片段,并进行了一些修复。 - JackLeo

1

这是基于Marius Gedminas和JackLeo版本的我的变化:

function! HgCiDiff()
    " find files that were changed (not interested in added or deleted)
    let changed_files = []
    let pattern = '\vHG: changed \zs(.+)\ze'
    while search("HG: changed", "W") > 0
        let line_text = getline(line("."))
        call add(changed_files, matchstr(line_text, pattern))
    endwhile
    let diff_cmd = "hg diff " . join(changed_files, " ")
    " Reset cursor to beginning of the buffer
    call cursor(1, 1)
    rightbelow vnew
    setlocal buftype=nofile
    let diff_output = system(diff_cmd)
    call append(0, split(diff_output, "\n"))
    " Reset cursor to beginning of the buffer
    call cursor(1, 1)
    setlocal ft=diff
    wincmd p
    setlocal spell spelllang=en_us
    cnoremap wq wqa
    cnoremap q qa!
    startinsert
endfunction

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接