使用特定的状态行/行号配置 vimdiff 拆分

Posted

技术标签:

【中文标题】使用特定的状态行/行号配置 vimdiff 拆分【英文标题】:Configuring vimdiff splits with specific statusline / line-numbers 【发布时间】:2021-02-08 03:55:14 【问题描述】:

我正在尝试使用以下拆分设置 git mergetool 以生成 vimdiff(以及为每个拆分定制的配置):

从以下缓冲区中拆分 $LOCAL、$BASE、$REMOTE 和 $MERGED(水平) [完成] 显示每个拆分的行号 [Todo] 仅显示这三个拆分中的缓冲区变量的名称:$LOCAL、$BASE、$REMOTE。 [待办事项] $MERGED 拆分状态行应显示来自%t 的文件名[$MERGED 拆分完成]

我在本地 repo 中使用了这个 git 配置:

git config merge.tool vimdiff
git config mergetool.vimdiff.cmd 'vim +"set number" +"set statusline=%t" -d -c "wincmd J" -O $MERGED $BASE $REMOTE $LOCAL'
git config merge.conflictstyle diff3
git config mergetool.prompt false
在上面的配置中,每个拆分都应该显示一个状态行子字符串,但我找不到正确的方法来构建一个正则表达式来将状态行中的文件名减少到三个所需的缓冲区变量名称之一(即“基地”、“远程”或“本地”)。不需要正则表达式,但它似乎是一个很有前途的选择。 行号只显示在一个拆分中,但我希望它们都出现在四个拆分中。

经过多次谷歌搜索和多次实验,我仍然无法强制 vimdiff 显示我想要的状态行/数字...我没有使用状态行插件,例如 vim-powerline。如何配置我的 git 选项以按照我需要的方式生成 vimdiff

我包含了我现有的git mergetool 拆分的屏幕截图。

【问题讨论】:

【参考方案1】:

为每个拆分添加行号

在这个命令中,vim +"set number" ... -O $MERGED $BASE $REMOTE $LOCAL,看起来 vim 会先创建拆分然后执行 set 选项。参考:vim -c option。

有两种方法可以解决这个问题。

    使用--cmd 选项: 如果我们使用vim --cmd "set number" -O $MERGED $BASE $REMOTE $LOCALset number 在创建拆分之前应用。事实上,它甚至在读取 .vimrc 文件之前就已经应用了。 (参考:vim --cmd option)。如果我们在 .vimrc 中有一个像 set nonumber 这样的覆盖配置,可能会引起关注。 手动创建拆分:我们可以手动创建拆分,而不是-O 选项。这样,在应用 -c 选项后,将创建拆分。我们将以相反的顺序发送文件参数,如下所示:
    vim +"set number" +"vs $LOCAL" +"vs $BASE" +"vs $MERGED" +"wincmd J" $REMOTE
    
    但是现在我们需要另一个选项 (diff this) 来在所有拆分中启用diff,因为-d 仅适用于在命令行中直接传递的文件。
    vim +"set number" +"vs $LOCAL" +"vs $BASE" +"vs $MERGED" +"wincmd J" +"windo 
    diffthis" $REMOTE
    

修改状态行

与正则表达式相比,使用静态字符串看起来更可靠。我们可以利用 vim setlocal 选项来实现这一点。所以总命令将是

vim +"set number" +"setlocal statusline=REMOTE" +"vs $LOCAL" +"setlocal statusline=LOCAL" +"vs $BASE" +"setlocal statusline=BASE" +"vs $MERGED" +"wincmd J" +"windo diffthis" $REMOTE

Git 合并工具配置:

git config merge.tool vimdiff
git config mergetool.vimdiff.cmd 'vim +"set number" +"setlocal statusline=REMOTE" +"vs $LOCAL" +"setlocal statusline=LOCAL" +"vs $BASE" +"setlocal statusline=BASE" +"vs $MERGED" +"wincmd J" +"windo diffthis" $REMOTE'
git config merge.conflictstyle diff3
git config mergetool.prompt false

git mergetool 输出:


更新 1

如果可以保留现有的状态行或者简单追加分割的缓冲区号,那么可以使用-Svim选项来大大简化命令。

git config mergetool.vimdiff.cmd 'vim -d -S "~/.git_merge_vimrc" -O $MERGED $BASE $REMOTE $LOCAL

.git_merge_vimrc 内容:

set statusline=%t-Split#%n
wincmd J
windo set number

注意: 如果需要,可以在源文件中使用 vim 脚本来打印复杂的状态行。

【讨论】:

我真的希望有一种更好的方法来配置mergetool.vimdiff.cmd,因为通过删除vim -O 选项,我们现在有很多不同的--cmd 选项,如果我尝试添加,vim 会抛出Too many "+command", "-c command" or "--cmd command" arguments b>任何其他+"set foo"选项。 另外,我稍微调整了你的 vimdiff 命令...我现在决定:vim +"set number" +"setlocal statusline=\$REMOTE-Split_#3" +"vs $LOCAL" +"setlocal statusline=\$LOCAL-Split_#2" +"vs $BASE" +"setlocal statusline=\$BASE-Split_#1" +"vs $MERGED" +"wincmd J" +"setlocal statusline=%t-Split_#4" +"windo diffthis" $REMOTE @MikePennington,请检查更新是否更适合您的用例。状态行可能与您的预期不同。我使用缓冲区号作为后缀,号基于-O 选项中给出的顺序。 my first comment above 中的结果更好...我肯定需要知道什么是 LOCAL、REMOTE 或 BASE 缓冲区。所以,实际上我们可能无法摆脱所有单独的 vim CLI 命令,但我希望我们可以

以上是关于使用特定的状态行/行号配置 vimdiff 拆分的主要内容,如果未能解决你的问题,请参考以下文章

如何找到特定行的行号?

在不知道行号的情况下删除特定行

技巧:Vimdiff 使用

如何从文件中读取特定行(按行号)?

如何在 vimdiff 中的垂直分割和水平分割之间切换?

如何使用 Python 将特定选定行拆分为多行