1

我想要一个变量来保存用户输入的默认目录,并在整个 emacs 运行期间继续使用它。

基本上,当用户执行自定义命令时,提示符会询问执行命令的默认目录路径(仅一次),并且每当用户调用相同的命令时,emacs 都会使用相同的路径。

如何在 lisp 中编写该代码片段?

我基本上希望 igrep 库中的这段代码接受一次用户的输入,而不是再次询问:

(defvar default-files-string-new "*.[sch]")
(defun igrep-read-files (&optional prompt-prefix)
  "Read and return a file name pattern from the minibuffer.
If `current-prefix-arg' is '(16) or '(64), read multiple file name
patterns and return them in a list.  Optional PROMPT-PREFIX is
prepended to the \"File(s): \" prompt."
  (let* ((default-files (igrep-default-files))
     (default-files-string (mapconcat 'identity default-files " "))
     (insert-default-directory igrep-insert-default-directory)
     (file (igrep-read-file-name
        (igrep-prefix prompt-prefix
                  (if default-files
                  (format "File(s) [default: %s]: "
                      default-files-string)
                "File(s): "))
        nil (if default-files default-files-string "") nil nil
        'igrep-files-history))
     (files (list file)))
    (if (or igrep-read-multiple-files
        (and (consp current-prefix-arg)
         (memq (prefix-numeric-value current-prefix-arg)
               '(16 64))))
    (let* ((key (igrep-default-key 'exit-minibuffer
                       minibuffer-local-completion-map
                       "\r"))
           (prompt
        (igrep-prefix prompt-prefix
                  (if igrep-verbose-prompts
                  (format "File(s): [Type `%s' when done] "
                      (key-description key))
                "File(s): "))))
      (while (and (setq file
                (igrep-read-file-name prompt
                          nil "" nil nil
                          'igrep-files-history))
              (not (equal file "")))
        (setq files (cons file files)))))
    (mapcar (lambda (file)
          (if (file-directory-p file)
          ;; really should map expand-file-name over default-files:
          (expand-file-name (if default-files default-files-string-new "*")
                    file)
        file))
        (nreverse files))))
4

3 回答 3

2

您可以为健全的默认值设置一个自定义变量,然后让用户输入路径或在第一次调用时接受默认值。

(defcustom default-path "/tmp/foo" "Path")
(setq current-path nil)


(defun foo ()
  (interactive)
  (unless current-path
    (setq current-path
          (read-from-minibuffer 
           (format "Path [%s]" default-path) nil nil t nil default-path)))
  (message "Path is: %s" current-path))

第一次执行 Mx foo 时,它会提示输入路径。一个常见的习惯用法是允许用户在想要更改值时(在第一次之后)指定前缀参数。这段代码将产生预期的效果:

(defun foo (choose)
  (interactive "P")
  (when (or choose (not current-path))
    (setq current-path
          (read-from-minibuffer 
           (format "Path [%s]" default-path) nil nil t nil default-path)))
  (message "Path is: %s" current-path))

现在做 Mx foo 和以前一样,但是 C-0 Mx foo 会提示输入一个新值。在你的例子中,这样的事情会起作用。

(defun igrep-read-files (&optional prompt-prefix)   
  (interactive "P")  
  (when (or prompt-prefix (not current-path ))
    (setq current-path
          (read-file-name "Dir: " default-path nil t)))   
  (message (expand-file-name default-files-string-new current-path)))
于 2013-08-01T21:25:33.770 回答
2

您可以使用建议来做到这一点:

(defvar wd-alist nil)

(mapc
 (lambda (function)
   (eval
    `(defadvice ,function (around ,(intern (format "%s-wd" function)) activate)
       (let ((wd (cdr (assoc ',function wd-alist))))
         (unless wd
           (setq wd (read-file-name "Default directory: "))
           (push (cons ',function wd) wd-alist))
         (let ((default-directory wd))
           ad-do-it)))))
 '(grep-find))

变量wd-list存储关联(FUNCTION . PATH)。列表mapc迭代是建议的功能。现在,当调用 时find-grep,它会询问工作目录(在交互式参数之后,因此您首先必须键入模式并输入...)并将其存储起来以wd-list供进一步使用。现在你find-grep总是在那个目录中完成。

于 2013-08-01T22:26:17.113 回答
0

看看代码sendmail-query-once。虽然做这种事情不是很时髦。通常包编写者会选择一个合理的默认值,并让用户根据需要自定义它。

于 2013-08-01T18:51:50.437 回答