コマンドのデフォルトの動作とCuの動作を入れ替え


7

多くのEmacsコマンドは、1つ以上のC-u接頭辞を付けて呼び出されると、その動作を変更します。場合によっては、コマンドのデフォルトの動作は、プレフィックスを付けたときに得られる動作よりも私にとってはあまり役に立ちませんC-u。同時に、デフォルトの動作を完全に排除したくありません。

具体的な例を示すと、quit-windowコマンド(にバインドさqれているhelp-mode)は現在のウィンドウを終了し、デフォルトでそのウィンドウに表示されているバッファーを埋め込みます。呼び出されC-uたとき、代わりにバッファを殺します。コマンドで、デフォルトでバッファを強制終了し、C-uプレフィックスで呼び出されたときにバッファを埋めたいと思います。

Q: デフォルトの動作をプレフィックスに移動しながら、コマンドが C-u デフォルトでプレフィックス 付きで呼び出されたかのように動作するようにEmacsに指示するにはどうすればよいですか?C-u

元のコマンドを再定義するか、自分の好みに応じてプレフィックス引数を渡すカスタムコマンドにラップすることで、この問題に対処できることを知っています。しかし、私はむしろこのようなことをしたいと思います:

(swap-args 'quit-window)

回答:


4

このようなもの:

(defun swap-args (fun)
  (if (not (equal (interactive-form fun)
                  '(interactive "P")))
      (error "Unexpected")
    (advice-add
     fun
     :around
     (lambda (x &rest args)
       "Swap the meaning the universal prefix argument"
       (if (called-interactively-p 'any)
           (apply x (cons (not (car args)) (cdr args)))
         (apply x args))))))

明らかに、に対してのみ機能し(interactive "P")ます。他のタイプのinteractive場合、最初の引数を否定することは意味がないかもしれません。


1
:filter-args代わりにを使うともう少し簡単:aroundになると思います。
npostavs 2015年

おかげで、swap-argsそれは作ることで動作C-uコマンドにそれを適用する際の動作のデフォルトを。ただし、でコマンドを呼び出すとC-u、元の動作が得られません。多分called-interactively-p非難することですか?私の理解では、引数がの'any場合、この関数はnil、それを含むコマンドがLispから呼び出された場合にのみ返されるため、キーバインディングを介してアドバイスされたコマンドを呼び出すと、elseブランチに到達できません。
itsjeyd

'any大丈夫だった、私funcallapply誤って代わりに使用しました。
abo-abo 2015年

2
docstringにも何かを追加する必要があります。そうしないと、混乱を招きます。
Gilles「SO-邪悪なことをやめなさい」

1
厄介なことに、一部の関数(例:)は、真理値強制チェックではなく、org-insert-subheading文字どおり生のユニバーサル引数(どうやら(4))をチェックします。
olejorgenb 2017年

1

interactive-form関数のplistのプロパティがコードで指定された形式をオーバーライドするという事実に基づく別の方法:(ref

(put 'org-insert-subheading
     'interactive-form
     '(interactive (progn (if current-prefix-arg
                              '(nil)
                            '((4))))))

を使用(interactive-form 'function)して現在の仕様を取得すると、より複雑な仕様を処理することもできます。

(可能な場合)最善の解決策は、関数をラップすること(let ((prefix-arg (not current-prefix-arg)))です


0

思ったほど簡単ではありません。ただし、コマンドを入れ替えることは簡単です。

(defun my-quit-window-args-swapped (&optional bury window)
"Adapted docstring blah, blah "
  (interactive "P")
  (quit-restore-window window (if bury 'bury 'kill)))

おかげで、質問で述べたように、コマンドに固有のラッパーではなく、さまざまなコマンドに適用できる一般的なソリューションを探していますquit-window
itsjeyd

@itsjeyd結果および議論の採用にWRTに有限の制限はありません。「(swap-args ...」ではなく、argsの使用と意味-最終的には無料です
AndreasRöhler

1
もっと慎重に言葉を選んだほうがいい。私は、あなたのソリューションが他のコマンドで機能するように適合できないことを示唆するつもりはありませんでした。これはデフォルトとC-u動作を交換するための完全に優れたソリューションであり、あなたの投稿に遭遇した他の人もそれによって助けられると確信しています!個人的には、動作を変更したいコマンドが複数あり、複数のラッパーを定義する必要がないようにしたいので、使用しません。
itsjeyd

@itsjeyd AFAIUここで定義されている唯一のものは、体がCuを受け取る方法です。argが使用される本文の時点での標準はありません。また、argを使用する多くの方法があります-ここではブール式です。もちろん、これらの可能性をすべてカバーして対処するために、ある種のAIを使用することができます。:)
AndreasRöhler15年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.