キーボードマクロのクエリ置換


7

私は次のように入力します。私はキーボードマクロを定義してみましょうC-x (、それから始まるに行きM-<、その後、入力M-%のいくつかの出現-置き換えるクエリにFOOをすることによってバー。見つかった3つのオカレンスのうち、最後の2つだけを置き換えてから保存しC-x C-s、kbd-macroをで終了しC-x )ます。よくやった!!

ここで別のバッファーでkbd-macroを実行すると、foobarで置き換えるかどうかは尋ねられず、以前のいいえはい答えを正確に再現し、2番目と3番目の結果を置き換えます!4番目または5番目のオカレンスは要求されません(この2番目のバッファーにはさらにfooが含まれます)!! これは、マクロを定義したときに期待したものではありません。私はそれを呼び出してquery-replace、その質問に答えさせたいと思いました...

脇の質問:これは間違っていると思いませんか?[ M-x edit-last-kbd-macro記録されている内容を確認して、そのロジックをすべて理解できますが、それでもまだ間違っていると思います。]

本当の質問:query-replace私のkbd-macroを期待どおりに動作させる代わりに何を使用できたでしょうか?


1
個人的に、私はそれを間違っているとは思いません。キーボードマクロは、すべてのキーストローク(入力を指定するものを含む)を記録M-%正確に再生します。インタラクティブな部分を持つマクロを見たことがなく、期待もしていません。この時点で、通常のインタラクティブなelisp関数を作成する方がよいでしょう。
Tikhon Jelvis 2014年

シンプル。クエリに答える前に、キーボードマクロを終了します。編集:私はそれを試してみました、おそらくそれはそれほど単純ではありません。誰かが新しいコマンドを書くことができると思いstart-kbd-macro-dwimます。
nispio 2014年

回答:


6

Emacsマクロは、ユーザーがマクロをエスケープしない限り、ユーザーがマクロの途中で入力したものをすべて再生します。進行中のマクロをエスケープする方法は、を使用することですC-x q kbd-macro-query

具体的には、マクロを続行する前にミニバッファーでコマンドを要求できる再帰編集を入力する必要があると思います。

query-replaceマクロを呼び出すときに自分を定義したいと思います。

  • F3 マクロを開始する
  • M-< 最初にジャンプ
  • C-u C-x q 再帰編集を入力するには
  • C-M-c 再帰編集を終了するには
  • ...残りのマクロアクション
  • F4 保存して繰り返す

kmacro-end-or-call-macroので、バッファの先頭にジャンプし、を呼び出すことができる再帰編集を入力しますquery-replace。その後、再帰編集を終了するC-M-cと、そのポイントからマクロが続行されます。

の代替引数を求めるプロンプトを表示したい場合は、再帰編集を使用するのでquery-replacequery-replaceなく、単純なインタラクティブラッパー関数を作成することをお勧めします。


1
私が誤解していない限り、これはへの呼び出し以外のすべてを記録してますquery-replace。これはFROM-STRINGまたはを保存するようには見えませんTO-STRING
nispio 2014年

1
はい、それはまさに私が言っていたものです。マクロ内でインタラクティブにquery-replaceを使用する必要があり、replace allを実行しない場合、マクロは適切ではないと思います
dgtized

3

ユーザー入力を要求する必要があるため、これはキーボードマクロにはあまり適していません。これはquery-replace頻繁に行うつもりなので、おそらくマクロを記録したいでしょう。キーボードマクロで目的を達成できない場合は、query-replace次のように特定の呼び出しへのキーバインドを作成できます。

(global-set-key (kbd "C-c q")   ;; Create a key binding for "Ctrl+c, q"
  (lambda () (interactive)      ;; Define an anonymous interactive funcion
  (query-replace "foo" "bar"    ;; Query-replace "foo" with "bar"
   nil                          ;; Don't require matching whole words
   1 (buffer-end 1))))          ;; Run from beginning to end of buffer

これをinitファイルに追加して、次にemacsを起動したときに使用できるようにするか、それを*scratch*バッファーに貼り付けて実行することで、テストドライブに使用できますM-x eval-buffer。これはにバインドC-c qされていますが、必要に応じて簡単に変更できます。

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