2

私の目的は、xml ファイル内の重複したスタンザを削除することです。スタンザの最初の行がファイル内で複数回見つかった場合、スタンザが重複していると確信しています。

対話型検索でスタンザの最初の行を見つけ、次に Ctrl-S をもう一度押して次の行に移動するマクロを作成しました。見つかった場合は、削除するセクションをマークして削除します。私のマクロはここで終了します。

Ctrl-s が次のオカレンスを見つけられない場合、マクロは停止します。これは、まさに私がやりたいことです。ただし、マクロを複数回実行するために Esc 1000 Ctrl-x e を実行すると、エラーが検出されると 1000 サイクルも停止します。マクロが停止してよかったのですが、エラー後に再度実行したいです。これは可能ですか?それとも、ファイルから重複するスタンザまたは行のグループを削除するためのマクロが既にどこかにありますか?

私のマクロ:

C-s         ;; isearch-forward
<Conduit        ;; self-insert-command * 8
SPC         ;; self-insert-command
6*C-w           ;; kill-region
C-s         ;; isearch-forward
C-a         ;; beginning-of-line
C-SPC           ;; set-mark-command
C-s         ;; isearch-forward
<           ;; self-insert-command
/           ;; nxml-electric-slash
Conduit>        ;; self-insert-command * 8
<right>         ;; forward-char
C-w         ;; kill-region

ありがとう

ジョー

4

3 に答える 3

1

エラーに関係なくマクロを繰り返し実行することを達成したい場合は、次の方法で実行できます。

(defun repeat-macro-until-abort ()
  (interactive)
  (while t
    (ignore-errors
      (kmacro-call-macro 0))))

Cg を押すまで、最後のマクロが実行されます。バッファエンドになっても停止しないので注意してください。

于 2013-11-11T07:55:17.110 に答える
1

うーん。Emacs がキーボード マクロ内でエラー状態を処理するための便利な対話型の方法を提供してくれればいいのですが、現時点では juanleon の回答が最善の策かもしれません。

一般的な回避策は を使用せずC-s、代わりM-: (search-forward "foo" nil t) RETに "foo" が存在しない場合にエラーを発生させずに "foo" を検索するなどの方法を使用することです。ただし、この例にはさらに多くのことがあります。

1 回限りの処理の場合、この種の状況で私がよく行うのは、関心のある結果のバッファーを生成し、それをキーボード マクロで処理することです。

この例は実際には少しトリッキーですがoccur、パターンに一致するすべての行をパイプで通しsort | uniq --all-repeated=separate、各グループの最初の行を削除することができます。これにより、複製ごとに削除したいインスタンスの正確な数が残るため、キーボード マクロはそのリストから行を取得し、元のバッファーで最後のインスタンスを見つけて削除し、次の行に移動できます。リストで。

これが一般的なアクティビティである場合は、カスタム elisp 関数が適しているように思われます。

于 2013-11-11T11:50:28.847 に答える
0

正規表現に一致する行を削除する簡単な方法があります:M-x flush-lines

削除したいスタンザの正規表現がわかっている場合は、入力C-M-% <your-regexp> RET RETして、何を削除するかを選択する出現を繰り返すことができます (すべてを削除するには ! を入力します)。CM-% は のデフォルトのキーバインドですquery-replace-regexp

于 2013-11-06T09:41:55.927 に答える