vim:サブマクロでエラーが発生してもマクロを続行しますか?


14

私はvimを使用していくつかのソースコードを美化している最中です。{1}

個々の手順を実行するvimマクロをいくつか作成しました。末尾のwhilespaceを削除し{、その後に空行を削除し、前{に空行を削除します。

次に、すべての個々のマクロを順番に実行するマクロを作成します。ただし、最初の再帰マクロが終了すると(一致するものが見つからないため->一致するエラーが発生するため)、「ラッパー」マクロも終了します。

サブマクロがエラーを生成した後、vimマクロを継続させる方法はありますか?

{1}私が知っている自動reformattersに関する。現在の問題でそれらを使用することもあります。例のためにソースの再フォーマットについて言及しただけです。このソースの美人またはそれについての答えを投稿しないでください。問題は、コード自体の再フォーマットではなく、vimマクロに関するものです。

例:

  • マクロ1-末尾の空白のトリミング- qw/\s\+$d$@wq
  • マクロ2-}の前の空行を削除する- qe/\n\n *}dd@eq
  • ラッパーマクロ-再タブ、マクロ1、マクロ2- qr:retab@w@eq

ラッパーを実行すると、ラッパー@rが再タブ化され、末尾の空白がなくなるまでマクロ1が実行され、その後(マクロ2が実行されずに)終了します。

明確化:

私が探しているのは、サブマクロが終了したときに呼び出しマクロが継続するようにサブマクロを呼び出す方法ですか?

回答:


12

:tryサブマクロのエラーを「吸収」するために使用することをお勧めします。

愚かな例です:

:let @a='f|dt|@a'
:let @q=':try|exe "norm! @a"|endtry^Mj0@q'
@q

ラッパーマクロは次のようになります。

let @r=':retab^M:try|exe "norm! @w"|endtry|try|exe "norm! @e"|endtry^M'

garyjohnはサブマクロにエラーがないことに対する回避策を提供しましたが、これが実際にそのようなエラーを処理する唯一の答えです。ただし、謝罪する必要があります。(期限切れの)報奨金を得るためにあなたの答えを時間内にチェックしませんでした... :
DevSolar

25

失敗したコマンドが、パターンを見つけられない置換である場合、たとえば

:%s/foo/bar/

ときfooバッファに存在しない、あなたが追加することができe、そのエラーを無視するフラグを、例えば、

:%s/foo/bar/e

見る

:help :s_flags

Vimの前に.exコマンドを追加することで、一部の:exコマンドからのエラーを無視するように指示できます:silent!。見る

:help :silent


質問への例の追加に続く編集

マクロ1とマクロ2は両方とも再帰的であり、どちらも再帰を終了するための明示的なメカニズムはありません。私の推測では、無制限の再帰に対するVimの内部テストの1つがトリガーされ、エラーが生成されます。Macro 1がそのようなエラーを生成している場合、そのエラーはの直後にWrapper Macroの実行を終了します@w

私の提案は、マクロを:exコマンドとして書き直し、実行される行の範囲を制限することで、マクロの実行回数を制限することです。例えば:

qw:%s/\s\+$//^Mq
qe:%s/\n\n *}/\r}/^Mq

ここで^M、EnterキーまたはReturnキーを入力します。Wrapper Macroでこれらを一緒にテストしたことはありませんが、間違いを修正できると思います。


これは私の場合の置換ではなく、単純な検索(つまり/foo)です。一方で:silent!実際に再帰的サブマクロのトリックはラッパーマクロを中止していない、今サブマクロはすべてで終了していない...と私はそれが何らかの形で再び終了することと疑う再びあまりにラッパーマクロを終了します。私が立ち往生しているようだ。:-\
DevSolar

使用しているマクロを見ずに何が間違っているのか、または同じ問題を示す簡単な例を見分けるのは困難です。
ゲイリージョン

例を追加しました。
-DevSolar

2

私のために働いたのは、@ Peter Rinckerと@garyjohnの回答の組み合わせでした。別に、奇妙な問題が発生し続けました。

nnoremap <leader>rt :silent! %s/\s\+$//e<CR>
let @r='\rt'
let @t=':try|silent! exe "norm! @r"|endtry|w^M'

私が考えるsilent!<leader>rt、との間のパイプ文字endtrywキーだった-後に単に改行を持つendtry失敗しました。trysが、私はちょうどそれらを入力したいときに働いたが、マクロとして実行すると、検索テキストに関するエラーが発生している続けるだろう見つかりませんでした。


1

多くのファイル間で繰り返しタスクを実行する必要がある場合、マクロをその場で定期的に作成します。私の場合、ウィンドウを作成するVIMにNERDtree(http://www.vim.org/scripts/script.php?script_id=1658)がインストールされてvsplitおり、左側にすべてのファイルのリストがあります現在のディレクトリ。一例でMY_TESTは、ファイル内の文字列の最初のインスタンスを見つけて、CUSTOM_PREFIX-その行からラベル付けされたプレフィックスを削除し、存在する場合はファイルを保存してから次のインスタンスに移動する必要があります。

現在のディレクトリにある約2000個のファイルでこのマクロがどのように機能するかを以下に示します。これを行うためにbashスクリプトを書くこともできますが、私の場合はVIMの方が高速です。+意味キーはサイマルを押されています

# Start recording a macro sequence to register 'A'

qa

# Search silently for the string "MY_TEST"; DO NOT report an error
# if the string could not be found.
:silent! /MY_TEST


# Replace, on just the current line, the string "CUSTOM_PREFIX-", with
# nothing (ie: delete it), and suppress any warning messages if the
# string could not be found on the current line.
:s/CUSTOM_PREFIX-//e


# Now issue some UI commands. CTRL-W then and arrow key lets you hope
# between tabs/splits/windows within vim.

CTRL+ W

# Scroll down to the next file in the list in NERDtree



# Open the next file

ENTER

# End the macro

q

# Run the macro a thousand times in VIM

1000 @a

お役に立てれば!

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