问题
Could anyone please give me a hand to briefly pop-up a dired buffer for the purposes of read-file-name
:
(defun dired-insert-file ()
(interactive)
(setq filename (dired-read-file-name "~/Desktop"))
(kill-buffer dired)
(get-buffer-create "*foo*")
(set-buffer "*foo*")
(insert-file filename))
EDIT: Revised example:
(require 'dired)
(defvar open-with-variable nil)
(defvar save-as-variable nil)
(defvar save-as-buffer-filename nil)
(defun dired-read-file-name (&optional directory)
(let* (
output-filename
(working-buffer (buffer-name)))
(if directory
(dired directory)
(dired nil))
(if save-as-buffer-filename
(progn
(goto-char (point-min))
(re-search-forward (file-name-nondirectory save-as-buffer-filename) nil t)))
(recursive-edit)
(switch-to-buffer working-buffer)
output-filename))
(defun dired-insert-file ()
(interactive)
(let* (
(save-as-variable t)
(lawlist-filename (dired-read-file-name)))
(insert-file-contents lawlist-filename)))
;; Open with external application.
(define-key dired-mode-map (kbd "C-c o") (lambda () (interactive)
(let* (
(open-with-variable t)
(lawlist-filename (dired-get-file-for-visit))
(application (dired-read-file-name "/Applications")))
(start-process "external-application" nil "open" "-a" application lawlist-filename))))
(defun lawlist-save-as ()
(interactive)
(let* (
save-as-filename
(save-as-variable t)
(save-as-buffer-filename (if (buffer-file-name) (buffer-file-name)))
(proposed-filename (dired-read-file-name)))
(when proposed-filename ;; needed if aborting recursive-edit
(setq save-as-filename (read-string "Save-As: "
(if (file-directory-p proposed-filename)
(concat proposed-filename (buffer-name))
proposed-filename)))
(when (and save-as-filename (file-exists-p save-as-filename))
(or (y-or-n-p (format "File `%s' exists; overwrite? " save-as-filename))
(error "Canceled")))
(set-visited-file-name save-as-filename)
(set-buffer-modified-p t)
(and (buffer-file-name)
(file-writable-p buffer-file-name)
(setq buffer-read-only nil))
(save-buffer))))
;; delete the buffer after selecting file | application | directory
(define-key dired-mode-map (kbd "<return>") (lambda () (interactive)
(select-file-application-directory t)))
;; do not delete the buffer after selecting file | application | directory
(define-key dired-mode-map (kbd "<C-M-s-return>") (lambda () (interactive)
(select-file-application-directory nil)))
;; select file | application | directory
(defun select-file-application-directory (&optional delete-buffer)
(let* (
(fn-list (dired-get-marked-files))
(rfn-list (mapcar (function dired-make-relative) fn-list))
(dired-one-file (and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
(input-filename (if dired-one-file dired-one-file fn-list))
(ext
(cond
((stringp input-filename)
(file-name-extension input-filename))
((listp input-filename)
(file-name-extension (car input-filename)))))
(path (if (stringp input-filename) (file-name-directory input-filename)))
(dired-buffer-name (buffer-name))
(msword "/Applications/Microsoft Office 2011/Microsoft Word.app/Contents/MacOS/Microsoft Word")
(ooo "/Applications/OpenOffice.org.app")
(excel "/Applications/Microsoft Office 2011/Microsoft Excel.app/Contents/MacOS/Microsoft Excel")
(adobe "/Applications/Adobe Acrobat 9 Pro/Adobe Acrobat Pro.app/Contents/MacOS/AdobeAcrobat")
(preview "/Applications/Preview.app/Contents/MacOS/Preview")
(skim "/Applications/Skim.app/Contents/MacOS/Skim")
(input-regexp '("odt" "wpd" "docx" "doc" "xls" "pdf" "tif" "bmp" "jpg"))
(pdf-regexp '("pdf" "tif" "bmp" "jpg"))
(ooo-regexp '("odt" "wpd"))
(msword-regexp '("doc" "docx")))
(cond
;; only use current path a save-as situation.
((and
(equal input-filename (concat path "."))
save-as-variable)
(setq output-filename (expand-file-name default-directory))
(if delete-buffer (kill-buffer dired-buffer-name))
(throw 'exit nil))
;; save-as (stringp) | dired-insert-file
((and
(stringp input-filename)
(not (file-directory-p input-filename))
(file-exists-p input-filename)
(not (equal input-filename (concat path ".")))
save-as-variable)
(setq output-filename input-filename)
(if delete-buffer (kill-buffer dired-buffer-name))
(throw 'exit nil))
;; open just one file, except input-regexp
((and
(stringp input-filename)
(not (file-directory-p input-filename))
(file-exists-p input-filename)
(not (equal input-filename (concat path ".")))
(not save-as-variable)
(not (regexp-match-p input-regexp ext)))
(if delete-buffer (kill-buffer dired-buffer-name))
(find-file input-filename))
;; open numerous files, except input-regexp
((and
(listp input-filename)
(not (regexp-match-p input-regexp ext)))
(if delete-buffer (kill-buffer dired-buffer-name))
(mapc 'find-file input-filename))
;; open OpenOfficeOrg
((and
(stringp input-filename)
(not (file-directory-p input-filename))
(file-exists-p input-filename)
(not (equal input-filename (concat path ".")))
(not save-as-variable)
(regexp-match-p ooo-regexp ext))
(start-process "ooo-view" nil "open" "-a" ooo input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
;; open msword
((and
(stringp input-filename)
(not (file-directory-p input-filename))
(file-exists-p input-filename)
(not (equal input-filename (concat path ".")))
(not save-as-variable)
(regexp-match-p msword-regexp ext))
(start-process "msword-view" nil "open" "-a" msword input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
;; open excel
((and
(stringp input-filename)
(not (file-directory-p input-filename))
(file-exists-p input-filename)
(not (equal input-filename (concat path ".")))
(not save-as-variable)
(equal ext "xls"))
(start-process "excel-view" nil "open" "-a" excel input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
;; *.pdf -- open just one *.pdf file.
((and
(stringp input-filename)
(not (file-directory-p input-filename))
(file-exists-p input-filename)
(not (equal input-filename (concat path ".")))
(not save-as-variable)
(regexp-match-p pdf-regexp ext))
(lawlist-message "[a]dobe | [p]review | [s]kim")
(let* ((select-pdf-viewer (read-char-exclusive)))
(cond
((eq select-pdf-viewer ?a)
(start-process "pdf-with-adobe" nil "open" "-a" adobe input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
((eq select-pdf-viewer ?p)
(start-process "pdf-with-preview" nil "open" "-a" preview input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
((eq select-pdf-viewer ?s)
(start-process "pdf-with-adobe" nil "open" "-a" skim input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
(t (message "You have exited the sub-function.")) )) )
;; *.pdf -- open more than just one *.pdf file.
((and
(listp input-filename)
(not save-as-variable)
(regexp-match-p pdf-regexp ext))
(lawlist-message "[a]dobe | [p]review | [s]kim")
(let* ((select-pdf-viewer (read-char-exclusive)))
(cond
((eq select-pdf-viewer ?a)
(mapcar (lambda (x)
(start-process "pdf-with-adobe" nil "open" "-a" adobe x) )
input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
((eq select-pdf-viewer ?p)
(mapcar (lambda (x)
(start-process "pdf-with-preview" nil "open" "-a" preview x) )
input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
((eq select-pdf-viewer ?s)
(mapcar (lambda (x)
(start-process "pdf-with-adobe" nil "open" "-a" skim x) )
input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
(t (message "You have exited the sub-function.")) )) )
;; open with external application, because the `open-with-variable` is t.
((and
open-with-variable
(equal ext "app"))
(setq output-filename input-filename)
(if delete-buffer (kill-buffer dired-buffer-name))
(throw 'exit nil))
;; Enter the directory; or, open an application
((and
(file-directory-p input-filename)
(not (equal input-filename (concat path ".")))
(not open-with-variable))
(if (equal ext "app")
(progn
(message "[d]eeper | [o]pen")
(let* ((deeper-open (read-char-exclusive)))
(cond
((eq deeper-open ?d)
(dired-find-file)
(goto-char (point-min))
(re-search-forward " \\.\\.$" nil t)
(if delete-buffer (kill-buffer dired-buffer-name)))
((eq deeper-open ?o)
(start-process "application" nil "open" "-a" input-filename)
(if delete-buffer (kill-buffer dired-buffer-name)))
(t (message "You have exited the sub-function.")) )) )
(dired-find-file)
(goto-char (point-min))
(re-search-forward " \\.\\.$" nil t)
(if delete-buffer (kill-buffer dired-buffer-name)))) )))
;; https://github.com/kentaro/auto-save-buffers-enhanced
;; `regexp-match-p` function modified by @sds on stackoverflow
;; http://stackoverflow.com/questions/20343048/distinguishing-files-with-extensions-from-hidden-files-and-no-extensions
(defun regexp-match-p (regexps string)
(and string
(catch 'matched
(let ((inhibit-changing-match-data t)) ; small optimization
(dolist (regexp regexps)
(when (string-match regexp string)
(throw 'matched t)))))))
(defun lawlist-message (input)
(interactive)
(message
(propertize input 'face 'font-lock-warning-face)))
回答1:
You'll want to look into recursive-edit
: pop up a dired buffer in which you add a way to exit (which works by performing a (throw 'exit <value>)
), and then call (recursive-edit)
which will return the <value>
passed to throw
.
来源:https://stackoverflow.com/questions/19899595/dired-read-file-name-pop-up-dired-mode-to-read-file-name