如何在打开文件之前拦截文件并决定哪个文件
我正在寻找一些关于如何在打开文件之前拦截一个文件的想法,并决定打开哪个文件。
我有一个由frame-bufs
克尔 – https://github.com/alpaker/Frame-Bufs – frame-bufs
的修改版本 – 与当前版本的Emacs中继工作。 我写了一个函数,将正在打开的文件与具有焦点的帧相关联。 我想进一步,并build立一个file types
和buffer names
,将永远与一个特定的框架相关的列表。 我正在考虑一个这样的function:
* If the file being opened is (or (eq major-mode 'text-mode) (eq major-mode 'latex-mode) ) (switch-to-frame "TEXT") * If the buffer being opened is (or (equal (buffer-name) "Folder") (equal (buffer-name) "Summary") ) (switch-to-frame "WANDERLUST") * After completing either of the above, open the file / buffer. * Run the custom frame association function -- (associate-current-buffer)
我认为有可能确定一个文件在一个帧中实际打开之前的模式。 什么是最好的方法来做到这一点?
;; To try out this example, copy and paste the entire contents of everything ;; in this answer to the `*scratch*' buffer and type: Mx eval-buffer RET ;; Then type: Mx db-example RET ;; ;; `db-open-file' also works out-of-the-box by typing: Mx db-open-file RET ;; ;; ;; The frame names are defined with the variable `db-frame-name'. ;; The preconfigured frame names are: SYSTEM, MAIN, ORG, MISCELLANEOUS. ;; ;; Buffers are displayed in specific frames based on the `buffer-name'. ;; ;; If the `buffer-name' matches a regexp defined `db-special-buffer', ;; then display that buffer in the current frame. ;; ;; If the `buffer-name' matches a regexp defined by `db-system-buffer', ;; then display that buffer in a frame named SYSTEM. ;; ;; If the `buffer-name' matches a regexp defined by `db-main-buffer', ;; then display that buffer in a frame named MAIN. ;; ;; If the `buffer-name' matches a regexp defined by `db-org-buffer', ;; then display that buffer in a frame named ORG. ;; ;; If the `buffer-name' does not match any of the above-mentioned regexp, ;; then display that buffer in a frame named MISCELLANEOUS. ;; ;; ;; The following are a few methods of setting the `display-buffer-alist': ;; ;; (1) Set the `display-buffer-alist' explicitly with `setq': ;; ;; (setq display-buffer-alist '((".*" . (db-pop-up-frame)))) ;; ;; (2) Add to an existing `display-buffer-alist' using `add-to-list': ;; ;; (add-to-list 'display-buffer-alist '(".*" . (db-pop-up-frame))) ;; ;; (3) Call the function as part of the `display-buffer' statement: ;; ;; (display-buffer (get-buffer-create "foo") '(db-pop-up-frame)) ;; ;; (4) Use the `display-buffer-alist' on a let-bound basis: ;; ;; (let ((display-buffer-alist '((".*" . (db-pop-up-frame))))) ;; [any additional code] ) (defvar db-frame-name "^\\(?:SYSTEM\\|MAIN\\|ORG\\|MISCELLANEOUS\\)$" "Frame names that are used to help organize buffers.") (defvar db-system-buffer '("\\*scratch\\*" "\\*bbdb\\*" "\\*bar\\*") "Regexp of file / buffer names displayed in frame `SYSTEM`.") (defvar db-main-buffer '("\\.txt" "\\.tex" "\\.el" "\\.yasnippet" "\\*foo\\*") "Regexp of file / buffer names displayed in frame `MAIN`.") (defvar db-org-buffer '("\\*TODO\\*" "\\*Org Agenda\\*" "\\.org_archive" "\\.org") "Regexp of file / buffer names displayed in frame `ORG`.") (defvar db-special-buffer '("\\*special\\*" "\\*baz\\*") "Regexp of file / buffer names that will display in current frame.") (defun db-pop-up-frame (buffer alist) (cond ;; condition # 1 -- either file-visiting or no-file buffers ((db-regexp-match-p db-org-buffer (buffer-name buffer)) (if (db-get-frame--drew-adams "ORG") (select-frame-set-input-focus (db-get-frame--drew-adams "ORG")) ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match db-frame-name (frame-parameter frame 'name))) (throw 'break (progn (select-frame-set-input-focus (db-get-frame--drew-adams (frame-parameter frame 'name))) (set-frame-name "ORG")))))) ;; If dolist found no unnamed frame, then create / name it. (when (not (db-get-frame--drew-adams "ORG")) (make-frame (list '(name . "ORG")))) ) (unless (get-buffer-window buffer) (set-window-buffer (get-largest-window) buffer)) (select-window (get-buffer-window buffer)) ) ;; condition # 2 -- either file-visiting or no-file buffers ((db-regexp-match-p db-main-buffer (buffer-name buffer)) (if (db-get-frame--drew-adams "MAIN") (select-frame-set-input-focus (db-get-frame--drew-adams "MAIN")) ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match db-frame-name (frame-parameter frame 'name))) (throw 'break (progn (select-frame-set-input-focus (db-get-frame--drew-adams (frame-parameter frame 'name))) (set-frame-name "MAIN")))))) ;; If dolist found no unnamed frame, then create / name it. (when (not (db-get-frame--drew-adams "MAIN")) (make-frame (list '(name . "MAIN")))) ) (unless (get-buffer-window buffer) (set-window-buffer (get-largest-window) buffer)) (select-window (get-buffer-window buffer)) ) ;; condition # 3 -- either file-visiting or no-file buffers ((db-regexp-match-p db-system-buffer (buffer-name buffer)) (if (db-get-frame--drew-adams "SYSTEM") (select-frame-set-input-focus (db-get-frame--drew-adams "SYSTEM")) ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match db-frame-name (frame-parameter frame 'name))) (throw 'break (progn (select-frame-set-input-focus (db-get-frame--drew-adams (frame-parameter frame 'name))) (set-frame-name "SYSTEM")))))) ;; If dolist found no unnamed frame, then create / name it. (when (not (db-get-frame--drew-adams "SYSTEM")) (make-frame (list '(name . "SYSTEM")))) ) (unless (get-buffer-window buffer) (set-window-buffer (get-largest-window) buffer)) (select-window (get-buffer-window buffer)) ) ;; condition # 4 ;; display buffer in the existing frame ((db-regexp-match-p db-special-buffer (buffer-name buffer)) (unless (get-buffer-window buffer) (set-window-buffer (get-largest-window) buffer)) (select-window (get-buffer-window buffer)) ) ;; condition # 5 ;; file-visiting buffers that do NOT match any pre-defined regexp ((and (not (db-regexp-match-p db-org-buffer (buffer-name buffer))) (not (db-regexp-match-p db-main-buffer (buffer-name buffer))) (not (db-regexp-match-p db-system-buffer (buffer-name buffer))) (not (db-regexp-match-p db-special-buffer (buffer-name buffer))) (buffer-file-name (get-buffer (buffer-name buffer)))) (if (db-get-frame--drew-adams "MISCELLANEOUS") (select-frame-set-input-focus (db-get-frame--drew-adams "MISCELLANEOUS")) ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match db-frame-name (frame-parameter frame 'name))) (throw 'break (progn (select-frame-set-input-focus (db-get-frame--drew-adams (frame-parameter frame 'name))) (set-frame-name "MISCELLANEOUS")))))) ;; If dolist found no unnamed frame, then create / name it. (when (not (db-get-frame--drew-adams "MISCELLANEOUS")) (make-frame (list '(name . "MISCELLANEOUS")))) ) (unless (get-buffer-window buffer) (set-window-buffer (get-largest-window) buffer)) (select-window (get-buffer-window buffer)) ) ;; condition # 6 ;; default display for no-file-visiting buffers (t nil ))) ;; https://github.com/kentaro/auto-save-buffers-enhanced ;; `db-regexp-match-p` function modified by @sds on stackoverflow ;; http://stackoverflow.com/a/20343715/2112489 (defun db-regexp-match-p (regexps string) (and string (catch 'matched (let ((inhibit-changing-match-data t)) (dolist (regexp regexps) (when (string-match regexp string) (throw 'matched t))))))) ;; Original Author: Drew Adams -- http://www.emacswiki.org/emacs/frame-fns.el ;; @lawlist combined the functions `get-frame-name` and `get-a-frame`. (defun db-get-frame--drew-adams (frame) "Return a frame, if any, named FRAME (a frame or a string). If none, return nil. If FRAME is a frame, it is returned." (let ((get-frame-name--drew-adams (lambda (&optional frame) (unless frame (setq frame (selected-frame))) (if (framep frame) (cdr (assq 'name (frame-parameters frame))) (error "Argument not a frame: `%s'" frame))))) (cond ((framep frame) frame) ((stringp frame) (catch 'get-a-frame-found (dolist (fr (frame-list)) (when (string= frame (funcall get-frame-name--drew-adams fr)) (throw 'get-a-frame-found fr))) nil)) (t (error "Arg neither a string nor a frame: `%s'" frame))))) (defun db-open-file (&optional filename) "With assistance from the `display-buffer-alist', locate or create a specific frame, and then open the file." (interactive) (let ((display-buffer-alist '((".*" . (db-pop-up-frame))))) (display-buffer (find-file-noselect (if filename filename (if (eq system-type 'darwin) (ns-read-file-name "Select File: " "~/" t nil nil) (read-file-name "Select File: " "~/" nil nil nil nil) )))))) (when (eq system-type 'darwin) (defun db-ns-find-file () "Do a `find-file' with the `ns-input-file' as argument." (interactive) (let* ( (display-buffer-alist '((".*" . (db-pop-up-frame)))) (f (file-truename (expand-file-name (pop ns-input-file) command-line-default-directory))) ) (ns-hide-emacs 'activate) (display-buffer (find-file-noselect f)))) (defalias 'ns-find-file 'db-ns-find-file) ) (defun db-example () "This is an example that uses the custom function `db-pop-up-frame' to display buffers in different frames or windows depending upon the situation. The `auto-mode-alist' is set to `nil` due to a bug in one of the versions of `org-mode' where it attempts to recenter a window that is not visible." (interactive) ;; condition # 3 | file-visiting buffer (let* ( (auto-mode-alist nil) (display-buffer-alist '((".*" . (db-pop-up-frame)))) ) (display-buffer (find-file-noselect "*bar*")) (set-frame-height (selected-frame) 20) (set-frame-width (selected-frame) 80) (set-frame-position (selected-frame) 0 0) (message "\*bar\* appears in frame name SYSTEM.") (sit-for 2) ;; condition # 4(a) | no-file-visiting buffer (display-buffer (get-buffer-create "*default*")) (message "NO-FILE buffer existing frame.") (sit-for 2) ;; condition # 2(a) | file-visiting buffer (display-buffer (find-file-noselect "foo.txt")) (set-frame-height (selected-frame) 20) (set-frame-width (selected-frame) 80) (set-frame-position (selected-frame) 100 100) (message "\"foo.txt\" appears in frame name MAIN.") (sit-for 2) ;; condition # 1 | file-visiting buffer (display-buffer (find-file-noselect "doe.org")) (set-frame-height (selected-frame) 20) (set-frame-width (selected-frame) 80) (set-frame-position (selected-frame) 200 200) (message "\"doe.org\" appears in frame name ORG.") (sit-for 2) ;; condition # 4(b) | file-visiting buffer (display-buffer (find-file-noselect "*special*")) (message "FILE buffer existing frame.") (sit-for 2) ;; condition # 6 | no-file-visiting buffer default display (calendar) (message "Default for no-file-visiting-buffers.") (sit-for 2) ;; condition # 5 | file-visiting buffer with no pre-defined regexp. (display-buffer (find-file-noselect "*undefined*")) (set-frame-height (selected-frame) 20) (set-frame-width (selected-frame) 80) (set-frame-position (selected-frame) 300 300) (message "\*IS\* buffer-filename. \*NOT\* defined by any particular regexp.") (sit-for 2) ;; condition # 2(b) | no-file-visiting buffer (display-buffer (get-buffer-create "*foo*")) (set-frame-height (selected-frame) 20) (set-frame-width (selected-frame) 80) (set-frame-position (selected-frame) 400 400) (message "\*NOT\* buffer-filename. \*IS\* defined by db-main-buffer.") (sit-for 2) (kill-buffer "*foo*") (kill-buffer "*bar*") (kill-buffer "*default*") (kill-buffer "*undefined*") (kill-buffer "*Calendar*") (kill-buffer "*special*") (kill-buffer "foo.txt") (kill-buffer "doe.org") (make-frame) (delete-frame (db-get-frame--drew-adams "SYSTEM")) (delete-frame (db-get-frame--drew-adams "MAIN")) (delete-frame (db-get-frame--drew-adams "ORG")) (delete-frame (db-get-frame--drew-adams "MISCELLANEOUS")) (message "THE END.")))