Emacs: Как вы сохраняете последний параметр, предоставленный пользователем, по умолчанию?

Я пишу интерактивную функцию, в которой я хотел бы запомнить последний аргумент, предоставленный пользователем, и использовать его по умолчанию.

(defun run-rake (param)
  (interactive "sTask: ")
  (shell-command (format "rake %s" task)))

При первом вызове функции я хочу, чтобы она запомнила аргумент, предоставленный пользователем, чтобы в следующий раз, когда они вызывают функцию, они могли просто нажать клавишу ввода, и она будет использовать значение, которое они указали в предыдущий раз.

Кажется, я не могу найти это в документации - как вы это делаете в elisp?


person Kyle Burton    schedule 28.09.2008    source источник


Ответы (3)


Вы можете увидеть, как это делает команда compile. Вызовите текст справки для команды компиляции с помощью C-h f compile, наведите курсор на имя файла, содержащего функцию, затем нажмите RETURN. Это вызовет исходный файл для compile.

По сути, есть динамическая/глобальная переменная compile-command, которая содержит последнюю команду компиляции. Emacs — это однопользовательская однопоточная система, так что большего и не требуется. Также имейте в виду, что Elisp — это Lisp очень старой школы, и переменные имеют динамическую (стек вызовов), а не лексическую область видимости. В такой системе естественно:

(let ((compile-command "gcc -o foo foo.c frobnicate.c"))
     ...
     (compile)
     ...)

Говоря о команде compile, пробовали ли вы использовать ее вместо собственной функции run-rake?

person jfm3    schedule 28.09.2008

read-from-minibuffer

это то, что вы хотите использовать. В нем есть место для исторической переменной.

Вот пример кода:

(defvar run-rake-history nil "History for run-rake")
(defun run-rake (cmd)
(interactive (list (read-from-minibuffer "Task: " (car run-rake-history) nil nil 'run-rake-history)))
  (shell-command (format "rake %s " cmd)))

Очевидно, настроить под свои нужды. 'run-rake-history' - это просто переменная, которая используется для хранения истории этого вызова 'read-from-minibuffer. Другим вариантом может быть использование «complete-read», но это предполагает, что у вас есть список вариантов, которые вы хотите ограничить пользователем (что обычно не относится к командам, подобным оболочке).

person Trey Jackson    schedule 29.09.2008

Я понял, как сделать это вручную, используя defvar (глобальный), но это похоже на то, что уже должно быть предоставлено основной библиотекой (вроде параметра make-схемы). Это просто кажется большим количеством кода и более ручным, чем должно быть:

(defvar *editconf-ruby-run-rake-last-rake-task* nil)

(defun editconf-ruby-run-rake-last-rake-task (&optional new-val)
  (when new-val
    (setf *editconf-ruby-run-rake-last-rake-task* new-val))
  *editconf-ruby-run-rake-last-rake-task*)

(defun editconf-ruby-run-rake (task-name)
  "Execute rake `task-name'.  See                                                                                            
`krb-ruby-get-rakefile-path-for-current-buffer' for how the                                                                  
Rakefile is located.."
  (interactive
   (let* ((rakefile (krb-ruby-get-rakefile-path-for-current-buffer))
          (rake-tasks (krb-ruby-get-rake-tasks rakefile))
          (default-task (or (editconf-ruby-run-rake-last-rake-task)
                            (editconf-ruby-run-rake-last-rake-task (car rake-tasks)))))
     (list
      (read-string (format "Task [%s|%s]: "
                           rake-tasks
                           default-task)
                   nil nil default-task))))
  (editconf-ruby-run-rake-last-rake-task task-name)
  (let ((cmd (format "cd %s; rake %s"
                     (krb-lisp-strip-path-suffix rakefile 1)
                     task-name)))
    (message "editconf-ruby-run-rake: cmd='%s'" cmd)
    (shell-command cmd)))
person Kyle Burton    schedule 28.09.2008