最後のコマンドを繰り返す(複雑かどうか)


8

Emacsにはとがrepeatありrepeat-complex-command、コマンド履歴からさまざまなコマンドを描画し、さまざまなキーにバインドされています。単一のキーで、最後のコマンドを(複雑であるかどうかにかかわらず)どのように繰り返しますか?つまり、このような繰り返しコマンドはrepeat-complex-command、最後のコマンドが入力を必要とする場合と同様に動作し、それ以外の場合はと同様に動作しますrepeat

EDIT:つまり、私は複雑かどうか最後のコマンドを、読むための方法を探していますし、その後のいずれかを呼び出すrepeat-complex-commandrepeat適切な方、それに。たとえば、そのような新しいコマンドがにバインドされて<f8>いるとしましょう。次に:

  • (と模倣C-x M-: (repeat-complex-command)するM-z (zap-to-char)):C-u M-z a <f8> <f8>と同等になりますC-u M-z a C-x M-: RET C-x M-: RET

  • (と模倣C-x z (repeat)するC-f (forward-char)):C-u C-f <f8> <f8>と同等になりますC-u C-f C-x z z

ここで、repeat-complex-command実行されるLispフォームを確認する必要があります。確認なしで複雑なコマンドを繰り返すことを可能にするためにrepeat-complex-command、と呼ばれるの代替バージョンを作成しましたrepeat-complex-command-no-confirm(実装については以下を参照)。問題は、を押すrepeatrepeat-complex-command-no-confirm、を押すかを判断する方法が理解できないこと<f8>です。

-

(defun repeat-complex-command-no-confirm (arg)
  "Like `repeat-complex-command' but does not require confirmation."
  ;; Adapted from `repeat-complex-command' of Emacs 24.5.1.
  (interactive "p")
  (let ((elt (nth (1- arg) command-history))
        newcmd)
    (if elt
        (progn
          (setq newcmd elt)

          ;; If command to be redone does not match front of history,
          ;; add it to the history.
          (or (equal newcmd (car command-history))
              (setq command-history (cons newcmd command-history)))
          (unwind-protect
              (progn
                ;; Trick called-interactively-p into thinking that `newcmd' is
                ;; an interactive call (bug#14136).
                (add-hook 'called-interactively-p-functions
                          #'repeat-complex-command--called-interactively-skip)
                (eval newcmd))
            (remove-hook 'called-interactively-p-functions
                         #'repeat-complex-command--called-interactively-skip)))
      (if command-history
          (error "Argument %d is beyond length of command history" arg)
        (error "There are no previous complex commands to repeat")))))

回答:


5

他の人が間違いなく別の解決策を提供するでしょう。これが図書館の私のものですmisc-cmds.el

(defun repeat-command (command)
  "Repeat COMMAND."
  (let ((repeat-message-function  'ignore))
    (setq last-repeatable-command  command)
    (repeat nil)))

次に、繰り返しのないコマンドに対して新しい繰り返しコマンドを定義し、非リピーターからリピーターにキーを再マップします。例えば:

(defun next-buffer-repeat ()
  "Switch to the next buffer in the selected window.
You can repeat this by hitting the last key again..."
  (interactive)
  (require 'repeat)
  (repeat-command 'next-buffer))

(global-set-key [remap next-buffer] 'next-buffer-repeat)

特に、これを使用して、プレフィックスキーにあるコマンドを繰り返すことができます。たとえば、への再マッピングは、を使用できることnext-buffernext-buffer-repeat意味しますC-x <right> <right>...。バインドされているキーはC-x <right>、繰り返しキーである必要はありません(押し続けることができるキーです。必要なのは、C-x一度使用してから押し続けるだけ<right>です。


申し訳ありませんが、「複雑なコマンド」も繰り返し実行したいことに気づきました。実際(IMHO)、複雑なコマンドを繰り返すのは誤称です。(デフォルトでは)同じ引数でコマンドを繰り返すことを意味します。意図的にそれを行うLisp sexpを編集できるので、たとえば引数を変更できます。

つまり、コマンドrepeat-complex-commandC-x ESC ESCたとえばにバインドされている)は特別な処理を行い、最後のコマンドを繰り返し実行する(つまり、上で示したようなものを実行する)とはまったく異なります。「複雑なコマンド」を繰り返し繰り返すことの意味や、それがどのように使用されるかは明確ではありません。IOW、たとえばコマンドがバインドされているキーを押し続けることによるコマンドの繰り返しの概念は、repeat-complex-command特定の引数値を指定してコマンドを編集してから呼び出すことができるダイアログを開始するの使用とはかなり異なります。

したがって、通常の意味でのコマンドの繰り返しを何とかして何とか考えて、あなたが考えていることをよりよく説明できない限りrepeat-complex-command、私はあなたの質問のその部分を手伝うことができないと思います。


説明が終わったら更新してください。

したがって、これは基本的に、最後の「複雑な」コマンドを繰り返すために必要なものです。つまり、ミニバッファーから入力を読み取る最後のコマンドを意味します。(repeat-complex-command-no-confirm履歴から削除する必要があることに注意してください。)

(defun repeat-complex-command-no-confirm ()
  "..."
  (interactive)
  (let* ((hist  command-history)
         newcmd)
    (while (eq 'repeat-complex-command-no-confirm (caar hist))
      (setq hist  (cdr hist)))
    (setq newcmd  (car hist))
    (if newcmd
        (apply #'funcall-interactively (car newcmd)
               (mapcar (lambda (ee) (eval ee t)) (cdr newcmd)))
      (error "There are no previous complex commands to repeat"))))

これを繰り返し可能なキーにバインドできます(例:C-o'). Or you can define a repeatable command using繰り返しコマンド、(i.e., pass繰り返し、複雑なコマンド、非確認to it), to be able to have it work when bound to a repeatable key that is on a prefix key (e.g.C-x o`)。

ただし、そのようなキーを使用してを呼び出すrepeat-complex-command-no-confirmと、ミニバッファーを使用した最後のコマンドが繰り返されます。必ずしも最後のコマンドではありません。

とにかく、あなたはあなたが望むことを得るのに次のようなものを使うことができます。最後の行はmy-repeat、最後のコマンドになるのを防ぎます。そのため、それを再度使用してもmy-repeat、繰り返されることはありませんが、最後に繰り返されたコマンドが繰り返されます。

(defun my-repeat ()
  "..."
  (interactive)
  (if (eq last-command (caar command-history))
      (repeat-complex-command-no-confirm)
    (call-interactively last-command))
  (setq this-command  last-command))

(global-set-key "\C-o" 'my-repeat) ; Bind it to a repeatable key

この質問には、repeatrepeat-complex-commandの違いを説明する回答があります。
Emacsユーザー

@EmacsUser:はい、ご覧のとおり、リンクした質問はマップ全体に広がっています。質問は不明確だったため、回答は多岐にわたります。それらはすべて、質問のいくつかの解釈に関連していますが、それらは混合バッグです。(そこでのこの回答に対する私のコメントを参照してください。)
Drew

はい、明確にしていただきありがとうございます。その回答は確かに誰でも深く掘り下げるのに役立ちます。
Emacsユーザー

@Drew詳しい回答ありがとうございます。質問を拡大しましたが、うまくいけば、より明確になりました。
Elena
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.