如何暂停VIM历史记录?


8

编辑文件时,通常通常连续执行很多UNDO,例如20次。在VIM中,通常通过按u20次来执行此操作,这会使VIM在历史记录堆栈中的20个位置“向上”移动。如果您随后确定change,则最后20条历史命令将全部丢失,并由代替change。我想change不失去这20个职位。因此,我想我想告诉VIM在我之前停止记录历史,然后在change以后恢复历史记录(不想change在历史记录中)。

编辑 试图变得更加清晰:我有一个函数FF,在写入缓冲区时会更新文件的最后几行。因此,如果我执行20 undos + write,最后一个write将打开一个新的撤消分支。我尝试undojoin在里面添加内容FF(尝试遵循下面的jlmg的建议),但是序列write-undo-write给出了一个错误:undo之后不允许使用undojoint。我可以sed ....在离开后改为执行一些操作vim,但是由于我是通过使用此方法,SSH所以我更喜欢仅使用vim的解决方案(在卸载缓冲区后执行命令不会写入文件)。

编辑2尝试在VIM中执行此操作:打开一个空白文件,然后执行以下操作:

i1<ESC>:wa2<ESC>:wa3<ESC>:wa4<ESC>uu:w

如果现在执行a <CTRL>R,则VIM将写回3,再进一步<CTRL>R输入4即使:w每次都执行一次,也会发生这种情况<CTRL>R。但是,如果每次:w执行a 时,您都通过执行功能BufWritePre<CTRL>R则不会写3回。这就是我想要做的,这就是为什么我写了“暂停历史记录”的原因,但是也许我要问的是不可能的,除了处理全部内容undotree()


1
这个问题本网站的主题,但是由于它与VIM的潜在功能有关,因此您是否考虑过尝试vim.stackexchange.com?我的意思是,我知道UNIX,也知道vi,但是对我来说vi,undo命令撤消一次,然后在u再次按下时撤消撤消(“ redo”)。那是真实的 vi。因此,我和该站点的其他用户可能不知道您问题的答案。
西拉达(Celada)

2
@Celada我相信它是vi.stackexchange.comVi和Vim
佐藤桂

@SatoKatsura你是绝对正确的!
西拉达(Celada)

1
@Celada:我不知道vim.se,我会尝试的。无论如何,佐藤似乎知道如何提供帮助。
路易斯·弗洛里特

您给出的“所有最后20条历史命令都丢失了”的问题已通过撤消分支的存在而得到解决,因此令人困惑的是,您随后希望通过避免其创建来解决问题。您说您可以使用获得所需的结果sed,但是sed不能撤消操作,那怎么办?如果您能够“暂停历史记录”,那么以后执行撤消操作时,vim会期望什么样的行为?我能看到的唯一行为是将这些更改(以及撤消)分组在一个撤消块中,因此我可以回答。但是,如果不是,那是什么?
JoL

Answers:


12

您不需要暂停Vim历史记录。实际数据形成一棵树,您可以使用undotree()函数检索它。当然,有许多插件可以将它们转变为更加用户友好的功能,例如gundomundoundotree。如果您还启用撤消持久性(请参阅参考资料:h undo-persistence),则可以轻松浏览文件的整个更改历史记录。


有趣的是,我不知道撤消实际上是一棵树。就我而言,我只想返回一次,即回到上一个撤消分支。你知道怎么做吗?似乎undotree()应该有所帮助?
路易斯·弗洛里特

事实上,在这种特殊情况下能够激励我的问题,我想是change不会出现在所有,任何地方,也不在history,也不在undo树上。这就是为什么我的问题是“暂停历史”。
路易斯·弗洛里特

@ LuisA.Florit:快速简便的方法是使用:earlier,它接受一个时间单位,并在必要时会越过撤消分支(例如,:earlier 1h使缓冲区看起来像一个小时前一样)。如果您不能使用时间单位(因为更改之间的距离太近了?),那么您将不得不一次g-使撤销树走几步。
凯文

0

如果我正确理解您的要求,那么change在撤消操作之后应该撤消该操作,然后执行20次撤消操作。

当vim执行一个功能或命令时,它所做的所有动作都将被撤消。我不确定这些动作是否可能包含撤消。也许这部分文档可以帮助您:

3. Undo blocks                      *undo-blocks*

One undo command normally undoes a typed command, no matter how many changes
that command makes.  This sequence of undo-able changes forms an undo block.
Thus if the typed key(s) call a function, all the commands in the function are
undone together.

If you want to write a function or script that doesn't create a new undoable
change but joins in with the previous change use this command:

                        *:undoj* *:undojoin* *E790*
:undoj[oin]     Join further changes with the previous undo block.
            Warning: Use with care, it may prevent the user from
            properly undoing changes.  Don't use this after undo
            or redo.
            {not in Vi}

This is most useful when you need to prompt the user halfway through a change.
For example in a function that calls |getchar()|.  Do make sure that there was
a related change before this that you must join with.

This doesn't work by itself, because the next key press will start a new
change again.  But you can do something like this: >

    :undojoin | delete

After this an "u" command will undo the delete command and the previous
change.

To do the opposite, break a change into two undo blocks, in Insert mode use
CTRL-G u.  This is useful if you want an insert command to be undoable in
parts.  E.g., for each sentence.  |i_CTRL-G_u|
Setting the value of 'undolevels' also breaks undo.  Even when the new value
is equal to the old value.

las,我尝试使用:undo 2 | undojoin | normal ohi,但收到错误消息E790: undojoin is not allowed after undo

但是,如果操作是通过以下函数完成的:

function F()
  undo 2
  normal ohi
endfunction

然后使用调用它:call F()undo在一个撤消块中执行和其他操作。请注意,由于您正在使用撤消,因此要创建一个新的撤消分支。完成后,您可以使用normal模式命令g-来撤消F();使用u就像:undo 3开始时一样。


不知道这是否行得通...我想要的是,在执行某些操作之后undo,您在函数中F()所做的所有操作都不会打开新的撤消分支。就我而言,F()每次写入文件时都会执行该命令,如果undo先写入然后再写入文件,则会F()打开一个新的撤消分支。我undojoin在开始时尝试了使用F(),但是序列write-undo-write给出了错误:undojoint not allowed after undo
路易斯·弗洛里特

更新了我的问题,试图使其更加清晰。
路易斯·弗洛里特

我在答案中写的@ LuisA.Florit :undojoin不适用于您想要的内容,并提到了相同的错误,我不建议:undojoin在的开头使用F()F()意味着要做:undojoin无法做的事情,那就是将撤消和其他命令合并到一个撤消块中。
JoL

@ LuisA.Florit您说您想避免创建撤消分支,但是我找不到您想要这样做的原因。我认为您的问题的关键是能够一次撤消命令和多次撤消。回顾一下,我想知道您是否要避免失去所做的更改。如果是这样的话,还原树的存在正是您想要的。您可以使用g-g+
JoL

是的,似乎需要的是撤消树。
路易斯·弗洛里特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.