VIM履歴を一時停止する方法は?


8

ファイルを編集するときは、通常20回など、何度もUNDOを続けて実行します。VIMでは通常u、20回押すことで実行され、履歴スタックの20の位置でVIMが「上」になります。その後、特定のを作成すると、change最後の20個の履歴コマンドはすべて失われ、に置き換えられchangeます。changeその20ポジションを失うことなく作りたいと思います。ですから、私はVIMに履歴の記録を停止してchangeから履歴を再開するように伝えたいと思います(履歴には入れたくないchange)。

EDIT より明確にしようとしている:FFバッファーが書き込まれたときにファイルの最後の行を更新する関数があります。そのため、を実行する20 undos + writeと、最後にwrite新しいundoブランチが開きます。undojoin内部に追加しようとしましたがFF(下記のjlmgの提案に従うように試みました)、シーケンスのwrite-undo-writeでエラーが発生します:undoの後にundojointは許可されていません。代わりに、sed ....去った後にいくつかすることができますvimが、これを使用するのでSSH、vimのみのソリューションを好みます(バッファーをアンロードしてからコマンドを実行しても、ファイルに書き込まれません)。

編集2 VIMでこれを試してみてください:空のファイルを開いてください:

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

ここでを実行すると<CTRL>R、VIMは '3'を書き戻し、さらに<CTRL>Rを取得し4ます。これが起こるEVENあなたが行う場合は:w、それぞれの後に<CTRL>R。しかし、あなたが毎回場合は:w、あなたが経由のfuctionを実行しBufWritePre<CTRL>R書きません3背中を。そして、これが私がやりたいことです。それが私が「歴史学を一時停止する」と書いた理由ですが、多分私が求めていることは、フルでの作業以外に不可能undotree()です。


1
この質問このサイトのトピックですが、VIMのかなり難解な機能に関係しているため、代わりにvim.stackexchange.comを試すことを検討しましたか?つまり、私はUNIXも知っていますviが、私にとってviは、元に戻すコマンドは1回元に戻され、次にuもう一度押すと、元に戻す(「やり直し」)が取り消されます。それは本当の viです。したがって、私やこのサイトの他のユーザーは、あなたの質問に対する答えを知らない可能性があります。
Celada、2016

2
@Celada私はそれがだと信じvi.stackexchange.com、またはViとVimの
佐藤桂

@佐藤桂正解です!
Celada、2016

1
@セラダ:私は知らなかったvim.se、私はそれを試みたでしょう。とにかく、佐藤は手伝う方法を知っているようです。
Luis A. Florit 16

「最後の20個の履歴コマンドがすべて失われる」という問題は、元に戻す分岐が存在することで修正されるため、作成を回避して問題を修正するのは混乱を招きます。あなたは、あなたが望む結果を得ることができると言いますがsed、sedは元に戻すことができません。「履歴を一時停止」できるとしたら、後で元に戻すときにvimにどのような動作を期待できますか?私が視覚化できる唯一の動作は、それらの変更を(取り消しと一緒に)1つの取り消しブロックにグループ化することです。しかし、それがそうでなければ、何ですか?
JoL、2016

回答:


12

Vimの履歴を一時停止する必要はありません。実際のデータはツリーを形成し、undotree()関数を使用して取得できます。もちろん、それをよりユーザーフレンドリーなプラグイン、fi gundomundo、およびundotreeに変換するプラグインは多数あります。元に戻す持続性(cf. :h undo-persistence)も有効にすると、ファイルの変更履歴全体を簡単に移動できます。


興味深いことに、元に戻すことが実際にはツリーであることを知りませんでした。私の場合、一度だけ、つまり前のundoブランチに戻りたいです。それを行う方法を知っていますか?それundotree()は助けになるはずですか?
Luis A. Florit 16

実際、私の質問の動機となったこの特定のケースでは、それchangeがどこにも、どこにもhistory、またはundoツリーにも表示されないようにしたいと思っています。それが私の質問が「歴史を一時停止する」ことであった理由です。
Luis A. Florit 16

@ LuisA.Florit:これを行う迅速かつ簡単な方法は:earlier、を使用することです。これは、時間単位を受け入れ、必要に応じて元に戻すブランチを交差さ:earlier 1hせます(たとえば、バッファを1時間前のように見せます)。時間単位を使用できない場合(変更が近すぎたためでしょうか?)、を使用g-して、元に戻すツリーを数歩ずつ歩く必要があります。
Kevin

0

私があなたを正しく理解しているとしたら、後で元に戻す操作を行うと、元に戻してchange20回元に戻すことができます。

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.

残念ながら、を使用:undo 2 | undojoin | normal ohiしてみましたが、エラーメッセージが表示されましたE790: undojoin is not allowed after undo

ただし、アクションが次のような関数で実行される場合:

function F()
  undo 2
  normal ohi
endfunction

次に、それを呼び出して、1つの取り消しブロックでおよびその他のアクションを:call F()実行しundoます。undoを使用しているため、新しいundoブランチを作成していることに注意してください。完了したら、通常モードのコマンドを使用しg-て元に戻すことができますF()。使用u:undo 3最初に行ったようなものになります。


これが機能するかどうかわからない...私が欲しいのは、いくつかの操作を行った後undo、関数で行うすべてF()の操作で新しい取り消しブランチが開かないことです。私の場合、F()ファイルを書き込むたびにが実行されます。ファイルを書き込んでから書き込むと、新しい取り消しブランチが開きundoますF()undojoinの冒頭で試しましたF()が、write-undo-writeのシーケンスでエラーが発生しますundojoint not allowed after undo
Luis A. Florit 16

より明確にするために私の質問を更新しました。
Luis A. Florit 16

@ LuisA.Florit私が:undojoinあなたが望むものに対してうまくいかなかった答えを書いて、同じエラーに言及しました、そして私は:undojoinの冒頭で使用することを提案していませんでしたF()。できなかったF()ことを行うことを意味します。つまり:undojoin、取り消しと他のコマンドを1つの取り消しブロックに結合します。
JoL

@ LuisA.Florit undoブランチの作成を避けたいとおっしゃっていますが、その理由はわかりません。あなたの質問のポイントは、コマンドと複数の取り消しを一度に元に戻すことができることだと思いました。振り返ってみると、元に戻した変更を失わないことがポイントだったのでしょうか。その場合は、元に戻すツリーの存在がまさにあなたが望むものです。g-およびでナビゲートできg+ます。
JoL、2016

はい、元に戻すツリーが必要なようです。
Luis A. Florit 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.