如何将 current-prefix-arg 传递给 this-command

How to pass current-prefix-arg to this-command

我想在调用 this-command 时重用 current-prefix-arg。我可以想象捕获它的值并将其传递给修改后的函数的方法。但是,这似乎不是一个很好的解决方案。我怎样才能重用它(例如,将它推回某种调用堆栈,或任何 emacs 使用的东西)?

这个例子是一个简单的函数,用于 increment/decrement 我刚刚写的区域中的数字,我想临时绑定 i 以增加或减少,如果它被调用字首。我可以不向函数添加另一个参数而只使用原始前缀来执行此操作吗?

(defun my-toggle-increment-numbers (start end)
  "Simple function to increment numbers in region. Decrement with prefix."
  (interactive "r")
  (let (deactivate-mark)
    (goto-char start)
    (while (re-search-forward "\([[:digit:]]+\)" end 'move)
      (replace-match (number-to-string
                      (+ (if current-prefix-arg -1 1)
                         (string-to-number (match-string 1))))
                     nil nil nil 1))
    ;; what is good way to reused the current-prefix-argument value when
    ;; calling this-command?
    (set-transient-map
     (let ((km (make-sparse-keymap)))
       (define-key km "i" this-command)
       km)
     t)))

试试这个:

(defun my-toggle-increment-numbers (start end &optional decrement)
  "Simple function to increment numbers in region. Decrement with prefix."
  (interactive "r\nP")
  (let (deactivate-mark)
    (setq start  (copy-marker start)
          end    (copy-marker end))
    (goto-char start)
    (while (re-search-forward "\([-]?[[:digit:]]+\)" end 'move)
      (replace-match (number-to-string (+ (if decrement -1 1)
                                          (string-to-number (match-string 1))))
                     nil nil nil 1))
    (set-transient-map
     (let ((km  (make-sparse-keymap)))
       (define-key km "i" `(lambda ()
                             (interactive)
                             (my-toggle-increment-numbers ',start ',end ',decrement)))
       km)
     t)))
  1. 您忘记在 [[:digit:]] 前面添加减号。

  2. 您需要使用词法绑定或构造一个命令来绑定 startendcurrent-prefix-arg(或 decrement - 见下一个)。

  3. 如果使用参数而不是current-prefix-arg,会简单一些。

    (您询问是否可以只使用 current-prefix-arg 而不是为其添加 arg。是的。在那种情况下,让绑定 current-prefix-arg 在构造的命令中被调用以供后续调用.)

  4. 由于替换可以改变数字中的位数(例如从 910,您需要使用标记而不是 [= 的数值13=] 在随后的调用中。

我认为最简洁的方法是创建一个调用 this-command 并向其传递前缀 arg:

的命令
;; This relies on -*- lexical-binding:t -*-
(defun my-toggle-increment-numbers (start end)
  [...]
  (set-transient-map
   (let ((km (make-sparse-keymap))
         (tc this-command)
         (cpa current-prefix-arg))
     (define-key km "i"
       (lambda () (interactive)
         (let ((current-prefix-arg cpa))
           (call-interactively tc))))
     km)
   t)))

它可能比您想象的更冗长,但我认为它最接近您的要求。获得几乎相同结果的更简单方法可能是:

(defun my-toggle-increment-numbers (start end)
  [...]
  (setq prefix-arg current-prefix-arg)
  (set-transient-map
   (let ((km (make-sparse-keymap)))
     (define-key km "i" this-command)
     km)
   t)))