Package: emacs;
Reported by: Keith David Bershatsky <esq <at> lawlist.com>
Date: Mon, 26 Aug 2013 00:52:02 UTC
Severity: normal
Found in version 24.3.50
Done: Glenn Morris <rgm <at> gnu.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Keith David Bershatsky <esq <at> lawlist.com> To: martin rudalics <rudalics <at> gmx.at> Cc: 15189 <at> debbugs.gnu.org Subject: bug#15189: 24.3.50; display-buffer does not work well with custom frames. Date: Tue, 27 Aug 2013 15:30:09 -0700
Thank you for the suggestions and examples -- greatly appreciated !!! Here is the revised code that appears to be working correctly for both types of situations -- i.e., file-visiting buffers, and nofile-visiting buffers. Keith ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXAMPLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun example () (interactive) (custom-find-file "*bar*") (set-frame-position (selected-frame) 0 0) (minibuffer-message "\*bar\* appears in frame name SYSTEM.") (sit-for 3) (custom-find-file "foo.txt") (set-frame-position (selected-frame) 100 100) (minibuffer-message "\"foo.txt\" appears in frame name MAIN.") (sit-for 3) (custom-find-file "doe.org") (set-frame-position (selected-frame) 200 200) (minibuffer-message "\"doe.org\" appears in frame name ORG.") (sit-for 3) (custom-find-file "*undefined*") (set-frame-position (selected-frame) 300 300) (minibuffer-message "\*undefined\* appears in frame name MISCELLANEOUS.") (sit-for 3) (display-buffer (get-buffer-create "*example*")) (other-window 1) (minibuffer-message "display-buffer-alist controls where \*example\* is displayed.") (sit-for 3) (kill-buffer "*bar*") (kill-buffer "foo.txt") (kill-buffer "doe.org") (kill-buffer "*undefined*") (kill-buffer "*example*") (make-frame) (delete-frame (get-frame "SYSTEM")) (delete-frame (get-frame "MAIN")) (delete-frame (get-frame "ORG")) (delete-frame (get-frame "MISCELLANEOUS"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FILE-VISITING BUFFER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar lawlist-regexp-frame-names "^\\(?:MAIN\\|SYSTEM\\|ORG\\|MISCELLANEOUS\\)$" "Regexp matching frames with specific names.") (defvar lawlist-system-buffer-regexp nil "Regexps matching `buffer-filename` for frame name `SYSTEM`.") (setq lawlist-system-buffer-regexp '("*scratch*" "*bar*")) (defvar lawlist-main-buffer-regexp nil "Regexps matching `buffer-filename` for frame name `MAIN`.") (setq lawlist-main-buffer-regexp '("\\.txt" "\\.tex" "\\.el" "\\.yasnippet")) (defvar lawlist-org-buffer-regexp nil "Regexps matching `buffer-filename` for frame name `ORG`.") (setq lawlist-org-buffer-regexp '("[*]todo-list[*]" "\\.org_archive" "\\.org")) (defvar buffer-filename nil) (defun custom-find-file (&optional buffer-filename) "Locate or create a specific frame, and then open the file." (interactive) (unless buffer-filename (setq buffer-filename (read-file-name "Select File: "))) (if buffer-filename (progn (setq display-buffer-function 'lawlist-display-buffer-function) (display-buffer (find-file-noselect buffer-filename)) (setq display-buffer-function nil) ))) (defun lawlist-display-buffer-function (&optional buffer flag) (if buffer-filename (progn (cond ((lawlist-regexp-match-p lawlist-org-buffer-regexp buffer-filename) (if (frame-exists "ORG") (switch-to-frame "ORG") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "ORG")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "ORG")) (progn (make-frame) (set-frame-name "ORG"))) )) ((lawlist-regexp-match-p lawlist-main-buffer-regexp buffer-filename) (if (frame-exists "MAIN") (switch-to-frame "MAIN") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "MAIN")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "MAIN")) (progn (make-frame) (set-frame-name "MAIN"))) )) ((lawlist-regexp-match-p lawlist-system-buffer-regexp buffer-filename) (if (frame-exists "SYSTEM") (switch-to-frame "SYSTEM") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "SYSTEM")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "SYSTEM")) (progn (make-frame) (set-frame-name "SYSTEM"))) )) ((and (not (lawlist-regexp-match-p lawlist-org-buffer-regexp buffer-filename)) (not (lawlist-regexp-match-p lawlist-main-buffer-regexp buffer-filename)) (not (lawlist-regexp-match-p lawlist-system-buffer-regexp buffer-filename)) ) (if (frame-exists "MISCELLANEOUS") (switch-to-frame "MISCELLANEOUS") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "MISCELLANEOUS")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "MISCELLANEOUS")) (progn (make-frame) (set-frame-name "MISCELLANEOUS"))))) (t (display-buffer-same-window))) (switch-to-buffer (get-file-buffer buffer-filename)) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAY BUFFER NO FILE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar system-nofile-regexp nil "Regexps matching `buffer-name buffer` for frame name `SYSTEM`.") (setq system-nofile-regexp '("\\(\\*Metahelp\\*\\|\\*Help\\*\\)")) (defvar main-nofile-regexp nil "Regexps matching `buffer-name buffer` for frame name `MAIN`.") (setq main-nofile-regexp '("\\*example\\*")) (defvar org-nofile-regexp nil "Regexps matching `buffer-name buffer` for frame name `ORG`.") (setq org-nofile-regexp '("\\*Org Agenda\\*")) (setq display-buffer-alist '((lawlist-p . (nofile-display-buffer-pop-up-frame)))) (defun lawlist-p (buffer action) (let ((buffer (get-buffer buffer))) (or (lawlist-regexp-match-p org-nofile-regexp (buffer-name buffer)) (lawlist-regexp-match-p main-nofile-regexp (buffer-name buffer)) (lawlist-regexp-match-p system-nofile-regexp (buffer-name buffer)) ))) (defun nofile-display-buffer-pop-up-frame (buffer alist) (cond ((lawlist-regexp-match-p org-nofile-regexp (buffer-name buffer)) (if (frame-exists "ORG") (switch-to-frame "ORG") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "ORG")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "ORG")) (progn (make-frame) (set-frame-name "ORG"))) )) ((lawlist-regexp-match-p main-nofile-regexp (buffer-name buffer)) (if (frame-exists "MAIN") (switch-to-frame "MAIN") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "MAIN")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "MAIN")) (progn (make-frame) (set-frame-name "MAIN"))) )) ((lawlist-regexp-match-p system-nofile-regexp (buffer-name buffer)) (if (frame-exists "SYSTEM") (switch-to-frame "SYSTEM") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "SYSTEM")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "SYSTEM")) (progn (make-frame) (set-frame-name "SYSTEM"))) )) ((and (not (lawlist-regexp-match-p org-nofile-regexp (buffer-name buffer))) (not (lawlist-regexp-match-p main-nofile-regexp (buffer-name buffer))) (not (lawlist-regexp-match-p system-nofile-regexp (buffer-name buffer))) ) (if (frame-exists "MISCELLANEOUS") (switch-to-frame "MISCELLANEOUS") ;; If unnamed frame exists, then take control of it. (catch 'break (dolist (frame (frame-list)) (if (not (string-match lawlist-regexp-frame-names (frame-parameter frame 'name))) (throw 'break (progn (switch-to-frame (frame-parameter frame 'name)) (set-frame-name "MISCELLANEOUS")))))) ;; If dolist found no unnamed frame, then create / name it. (if (not (frame-exists "MISCELLANEOUS")) (progn (make-frame) (set-frame-name "MISCELLANEOUS"))))) (t (display-buffer-same-window))) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GENERIC REGEXP FUNCTION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun lawlist-regexp-match-p (regexps string) (catch 'matched (dolist (regexp regexps) (if (string-match regexp string) (throw 'matched t))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;; GENERIC BUFFER / FRAME UTILITIES ;;;;;;;;;;;;;;;;;;;;;;;; (defun frame-exists (frame-name) (not (eq nil (get-frame frame-name)))) (defun get-frame-name (&optional frame) "Return the string that names FRAME (a frame). Default is selected frame." (unless frame (setq frame (selected-frame))) (if (framep frame) (cdr (assq 'name (frame-parameters frame))) (error "Function `get-frame-name': Argument not a frame: `%s'" frame))) (defun get-frame (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." (cond ((framep frame) frame) ((stringp frame) (catch 'get-a-frame-found (dolist (fr (frame-list)) (when (string= frame (get-frame-name fr)) (throw 'get-a-frame-found fr))) nil)) (t (error "Function `get-frame-name': Arg neither a string nor a frame: `%s'" frame)))) (defun switch-to-frame (frame-name) (let ((frames (frame-list))) (catch 'break (while frames (let ((frame (car frames))) (if (equal (frame-parameter frame 'name) frame-name) (throw 'break (select-frame-set-input-focus frame)) (setq frames (cdr frames)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; At Tue, 27 Aug 2013 08:47:19 +0200, martin rudalics wrote: > > > Using your suggestion of find-file-noselect works well with the initial example, and then just adding (switch-to-buffer (get-file-buffer buffer-filename)) to the tail end of the lawlist-display-buffer-function. > > If you want to show a file-visiting buffer in the selected window, yes. > I'd rather add a rule that calls `display-buffer-same-window' and rewrite > the code > > (when (lawlist-regexps-match-p ...) > ...) > (when (lawlist-regexps-match-p ...) > ...) > > as > > (cond > ((lawlist-regexps-match-p ...) > ...) > ((lawlist-regexps-match-p ...) > ...) > (t > (display-buffer-same-window ...))) > > BTW you should also make code like > > (if (and > (not (equal "MAIN" (frame-parameter frame 'name))) > (not (equal "SYSTEM" (frame-parameter frame 'name))) > (not (equal "ORG" (frame-parameter frame 'name))) > (not (equal "WANDERLUST" (frame-parameter frame 'name))) > (not (equal "MISCELLANEOUS" (frame-parameter frame 'name))) ) > > more readable by defining a variable like > > (defvar my-regexp "^\\(?:MAIN\\|SYSTEM\\|ORG\\|WANDERLUST\\| MISCELLANEOUS\\)$" > "My doc-string.") > > and using > (not (string-match my-regexp (frame-parameter frame 'name))) > > instead. > > martin
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.