Emacs Lisp: read-from-minibuffer Propels Deep Questions
slightly frustrated with emacs lisp
read-from-minibuffer. Spent now about a hour on this.
what i want is simple, like this:
(read-from-minibuffer (format "Directory (default %s):" default-directory) default-directory )
prompt user to enter a dir, with default of current dir.
however, according to inline doc of
read-from-minibuffer, the second arg for default input is
obsolete “mostly deprecated”. Instead, you have to use the 6th arg. Quote:
(read-from-minibuffer PROMPT &optional INITIAL-CONTENTS KEYMAP READ HIST DEFAULT-VALUE INHERIT-INPUT-METHOD)
the doc is long so i won't paste here. See it by calling
describe-function. (info "(elisp) Text from Minibuffer")
Now, so i do:
(read-from-minibuffer (format "Directory (default %s):" default-directory) nil nil nil nil default-directory)
doesn't work. Read the doc again, it turns out that the 4th arg must be true in order for the default value to work, else you get empty string if the user just press Enter ↵.
So i do:
(read-from-minibuffer (format "Directory (default %s):" default-directory) nil nil t nil default-directory)
No go! because if the 4th arg is true, it means the input as a string will be fed to lisp reader, then interpreted as a lisp object. Hot damn. This means, if you want a string, you have to feed it
"\"mystring\"". (the outter quote pair makes it a lisp string to be fed to lisp reader, then, the inner quote pair gets you a lisp string object)
So, now i have to do this:
(read-from-minibuffer (format "Directory (default %s):" default-directory) nil nil t nil (format "\"%s\"" default-directory) )
But no! Because, now if user actually enter a value, for example, type
mary, lisp reader freaks out. Again, it doesn't undertand what the letter sequence
mary is. It wants a string
"\"mary\"". So, user will have to actually type
"mary" for this to work.
This line is supposed to be done in 20 seconds. I think i've spent 40 min on this. Now, my mind wanders to the deep question of humanity….
You should use
read-directory-name. Like this:
(defun test-fun (arg) "Prompt user to enter a file path, with file name completion and input history support." (interactive (list (read-file-name "Open directory:")) ) (message "Path is 「%s」." arg) )
If you really want to use
read-from-minibuffer, you can simply:
(read-from-minibuffer "Directory: " default-directory)
Or, check if the return string is empty.
(let ((directory (read-from-minibuffer (format "Directory (default %s): " default-directory) nil nil nil nil default-directory))) (if (equal directory "") default-directory directory))