我正在编写一个交互式函数,我想记住用户提供的最后一个参数并将其用作默认值。
(defun run-rake (param)
(interactive "sTask: ")
(shell-command (format "rake %s" task)))
第一次调用该函数时,我希望它记住用户提供的参数,以便下次调用该函数时,只需按Enter键,它将使用前一次提供的值。
我似乎无法在文档中找到这个 - 你如何在elisp中做到这一点?
答案 0 :(得分:8)
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'调用的历史记录。另一个选择是使用'完成 - 读 - 但假设你有一个你想要限制用户使用的选项列表(对于类似shell的命令通常不是这种情况)。
答案 1 :(得分:5)
您可以看到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
函数?
答案 2 :(得分:0)
我想出了如何使用defvar(全局)手动执行此操作,但这感觉就像核心库应该已经提供的那种(类似于scheme的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)))