Emacs: Как съхранявате последния параметър, предоставен от потребителя като стандартен?

Пиша интерактивна функция, която бих искал да запомни последния аргумент, предоставен от потребителя, и да го използва като стандартен.

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

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

Изглежда не мога да намеря това в документацията - как правите това в 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. Друг вариант би бил да използвате „завършване-четене – но това предполага, че имате списък с възможности за избор, които искате да ограничите на потребителя да използва (което обикновено не е случаят с подобни на обвивка команди).

person Trey Jackson    schedule 29.09.2008

Разбрах как да направя това ръчно с помощта на defvar (глобален), но това ми се струва като нещо, което вече трябва да бъде осигурено от основната библиотека (нещо като make-parameter на схемата). Това просто изглежда като повече код и повече ръчно, отколкото трябва да бъде:

(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