Как создать интерактивную функцию elisp с необязательными аргументами - PullRequest
11 голосов
/ 24 марта 2012

Как написать функцию elisp, которая должна быть связана с нажатием клавиши, которая по умолчанию работает без запроса, но когда ей предшествует Ctrl-u, запрашивает у пользователя аргумент.Что-то похожее (неправильный синтаксис, но я надеюсь, вы поняли)?

 (defun my-message (&optional (print-message "foo"))
   (interactive "P")
   (message print-message))
 (global-set-key "\C-c\C-m" 'my-message)

Ответы [ 3 ]

20 голосов
/ 25 марта 2012

Следующее использует функцию interactive, которая позволяет использовать код вместо строки.Этот код будет выполняться только тогда, когда функция вызывается в интерактивном режиме (что делает этот ответ другим по сравнению с предыдущим ответом).Код должен соответствовать списку, в котором элементы отображаются на параметры.

(defun my-test (&optional arg)
  (interactive (list (if current-prefix-arg
                         (read-from-minibuffer "MyPrompt: ")
                       nil)))
  (if arg
      (message arg)
    (message "NO ARG")))

Используя этот метод, эту функцию можно вызывать из кода, подобного (my-test) или (my-test "X"), без запроса пользователядля ввода.В большинстве случаев вы хотели бы разработать функции таким образом, чтобы они запрашивали ввод только при интерактивном вызове.

4 голосов
/ 25 марта 2012

Если вы просто хотите использовать функцию в качестве интерактивной, этот код - все, что вам нужно:

(defun my-message (&optional ask)
  (interactive "P")
  (message (if ask
               (read-from-minibuffer "Message: ")
             "foo")))
4 голосов
/ 25 марта 2012

Следуя той же реализации, что и в вашем примере, вы можете сделать что-то вроде этого:

(defun my-message (&optional arg)
  (interactive "P")
  (let ((msg "foo"))
    (when arg
      (setq msg (read-from-minibuffer "Message: ")))
    (message msg)))
...