SFbay007
SFbay007

Reputation: 2027

Asking emacs for default directory path "once"

I want to have a variable that keeps the default directory a user enters and keep using it throughout the run of emacs.

Basically, when the user executes a custom command, the prompt will ask for a default directory path to execute the command (only once) and whenever the user calls the same command emacs uses the same path onward.

How can I program that snippet of code in lisp?

I basically want this code in the igrep library to accept the input from user once and not ask again:

(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))))

Upvotes: 1

Views: 273

Answers (3)

seanmcl
seanmcl

Reputation: 9946

You could have a custom variable for the sane default, and then have the user enter the path or accept the default on the first call.

(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))

The first time you do M-x foo, it prompts for the path. A common idiom is to allow the user to specify a prefix argument when they want to change the value (after the first time.) This code will have the desired effect:

(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))

Now doing M-x foo is the same as before, but C-0 M-x foo will prompt for a new value. In your example, something like this will work.

(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)))

Upvotes: 2

thisirs
thisirs

Reputation: 788

You could use advices to do that:

(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))

The variable wd-list stores the association (FUNCTION . PATH). The list mapc iterate over are the advised functions. Now, when calling find-grep, it asks for the working directory (after interactive arguments, so you first have to type the pattern and enter...) and stores it in wd-list for further use. Now your find-grep are always done in that directory.

Upvotes: 2

abo-abo
abo-abo

Reputation: 20342

Have a look at the code of sendmail-query-once. Although it's not very fashionable to do this sort of thing. Usually package writers pick a sane default and let the user customize it as they want.

Upvotes: 0

Related Questions