;;; file-confirm.el --- Confirm creation of duplicate frames
;; Copyright (c) 2000-2002 Pekka Marjola
;; Author: Pekka Marjola
;; Keywords: file, frame
;; Version: 0.9
;; This file is not part of XEmacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; A copy of the GNU General Public License can be obtained from this
;; program's author (send electronic mail to [email protected]) or from
;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
;; 02139, USA.
;;
;; Send bug reports to [email protected]
;; Created: 2.4.2000
;; $Modified: Mon Oct 28 13:03:51 2002 by pema $
;;; Commentary:
;; Some utility functions to avoid creation of extra frames or buffers
;; unnecessarily.
;;
;; Tested so far only in XEmacs-21.1.4.
;; Requires custom.
;; Most likely does not work in GNU Emacs.
;;; Code:
(defgroup file-confirm nil
"Confirmation for finding non-existing files and creation of duplicate frames."
:group 'files
:prefix "file-confirm-")
;;;###autoload
(defcustom file-confirm-warp-mouse t
"*If non-nil, warp mouse when using an old frame.
This is contrary to ICCCM, but may be useful."
:group 'file-confirm
:type 'boolean)
(defconst file-confirm-version "0.9"
"Version of file-confirm package.")
(defcustom file-confirm-mode nil
"*If non-nil, activates file-confirm-mode."
:type 'boolean
:require 'file-confirm
:group 'file-confirm)
;;;###autoload
(defcustom file-confirm-mode-line-string " FC"
"*Modeline indicator for file-confirm."
:group 'file-confirm
:type 'string)
;;;###autoload
(defvar file-confirm-mode-map nil
"Keymap for file-confirm minor mode.")
(defcustom file-confirm-mode-hook nil
"*List of functions to call when entering file-confirm minor mode."
:group 'file-confirm
:type 'hook)
(defcustom file-confirm-load-hook nil
"*List of functions to call after loading file-confirm."
:group 'file-confirm
:type 'hook)
;;;###autoload
(if file-confirm-mode-map
nil
(setq file-confirm-mode-map (make-sparse-keymap "file-confirm-map"))
(define-key file-confirm-mode-map [(control x) ?5 f] 'find-file-frame-or-file)
(define-key file-confirm-mode-map [(control x) (control f)] 'find-file-confirm-non-existing)
(define-key file-confirm-mode-map [(control x) ?5 b] 'switch-to-frame-or-buffer-other-frame))
;;;###autoload
(defun find-file-frame-or-file (file &optional codesys)
"If a frame is already showing the file, show the frame,
if the file is in a buffer, open a new frame for buffer. Otherwise
open the file in a new frame."
(interactive "FFind file in other frame: \nZCoding system: ")
(find-file-frame-or-file-internal file codesys))
(defun find-file-frame-or-file-internal (file &optional codesys)
(let ((buf (find-buffer-visiting file)))
(if buf
;; Must use get-buffer-window-list or sothing that allows specifying
;; parameters for walk-windows to get all frames. frames-of-buffer
;; does not work. Insane!
(let* ((window (get-buffer-window-list buf nil 0))
(frm (and window
(window-frame (car window)))))
(if (and frm
(y-or-n-p (concat "Show " file " in existing frame instead? ")))
(progn
(make-frame-visible frm)
;;(focus-frame frm)
;; Against ICCCM, but...
(when file-confirm-warp-mouse
(while (not (frame-visible-p frm)) (sleep-for .5))
(set-mouse-position (car window) 2 2)))
(find-file-other-frame file codesys)))
(if (or (file-exists-p file)
(y-or-n-p (concat "File " file " does not exist, visit anyway? ")))
;; Really, I should set the focus here, too(?)
(find-file-other-frame file codesys)
;; fake "dir" argument to get the default prompt
(find-file-frame-or-file-internal (read-file-name "Find file in other frame: " file file) codesys))
)))
;;;###autoload
(defun find-file-confirm-non-existing (file &optional codesys)
"Ask for confirmation, before calling find-file for non-existing files."
(interactive "FFind file: \nZCoding system: ")
(find-file-confirm-non-existing-internal file codesys))
(defun find-file-confirm-non-existing-internal (file &optional codesys)
(if (or (file-exists-p file)
(y-or-n-p (concat "File " file " does not exist, visit anyway? ")))
(find-file file)
;; fake "dir" argument to get the default prompt
(find-file-confirm-non-existing-internal (read-file-name "Find file in other frame: " file file) codesys)))
;;;###autoload
(defun switch-to-frame-or-buffer-other-frame (buffer)
"Switch to buffer BUFFER in a newly-created frame."
(interactive "BSwitch to buffer in other frame: ")
(let* ((name (get-frame-name-for-buffer buffer))
(window (get-buffer-window-list buffer nil 0))
(frm (and window
(window-frame (car window)))))
(if (and frm
(y-or-n-p (concat "Show " buffer " in existing frame instead? ")))
t
(setq frm (make-frame (if name
(list (cons 'name (symbol-name name))))))
(pop-to-buffer buffer t frm)
(setq window (get-buffer-window-list buffer nil 0)))
(make-frame-visible frm)
;;(focus-frame frm)
;; Against ICCCM, but...
(when file-confirm-warp-mouse
(while (not (frame-visible-p frm)) (sleep-for .5))
(set-mouse-position (car window) 2 2))
buffer))
;;;###autoload
(defun file-confirm-mode (&optional arg)
"Toggle file-confirm minor mode.
With arg, turn file-confirm mode on iff arg is positive. When
file-confirm mode is enabled, the editor asks for confirmation before
opening buffers for non-existing files and tries to use existing
frame, if a frame is already showing requested file or buffer.
Special commands:
\\
key binding
--- -------
\\[find-file-frame-or-file] find-file-frame-or-file
\\[find-file-confirm-non-existing] find-file-confirm-non-existing
\\[switch-to-frame-or-buffer-other-frame] switch-to-frame-or-buffer-other-frame
"
(interactive "*P")
(setq file-confirm-mode
(if (null arg)
(not file-confirm-mode)
(> (prefix-numeric-value arg) 0)))
(when file-confirm-mode
(run-hooks 'file-confirm-mode-hook)))
;;;###autoload
(defun turn-on-file-confirm ()
"Unconditionally turn on File-confirm mode."
(interactive)
(file-confirm-mode 1))
;;;###autoload
(when (fboundp 'add-minor-mode)
;; XEmacs
(add-minor-mode 'file-confirm-mode
file-confirm-mode-line-string
file-confirm-mode-map))
;; Emacs -- don't autoload
(unless (assq 'file-confirm-mode minor-mode-alist)
(setq minor-mode-alist
(cons '(file-confirm-mode file-confirm-mode-line-string)
minor-mode-alist)))
(run-hooks 'file-confirm-load-hook)
(provide 'file-confirm)