elscreen-1.4.6004075500007650000000000000000001073546175200122575ustar naotowheelelscreen-1.4.6/ChangeLog010064400007650000000000000521451073546170500141120ustar naotowheel2007-12-30 Naoto Morishima ElScreen 1.4.6 released. 2007-12-29 Naoto Morishima * elscreen.el (elscreen-delete-frame-confs): Don't call elscreen-notify-screen-modification which potentially causes an error when frame has been created via make-frame-on-display. 2007-11-22 Naoto Morishima * elscreen.el (elscreen-display-tab): Change type from boolean to choice of boolean and integer. t means display with automatic width calculation, and integer means display with fixed width. (elscreen-tab-width): Removed. (elscreen-e21-tab-width,elscreen-xmas-tab-width): New functions. (elscreen-e21-tab-update,elscreen-xmas-tab-update): Use them. (elscreen-default-window-configuration): Set dedicated-p of selected-window to nil instead of splitting it. 2007-11-21 Naoto Morishima * elscreen.el (elscreen-default-window-configuration): Split window first to avoid error in case that the selected window is dedicated. (elscreen-copy-tree-1, elscreen-copy-tree): Split elscreen-copy-tree to two functions, backported from trunk. (elscreen-save-screen-excursion) (elscreen-notify-screen-modification-suppress) (elscreen-screen-modified-hook-setup) (elscreen-get-alist-to-nickname): Eliminate old-style backquotes, backported from trunk. (elscreen-get-alist-to-nickname): Define as subst instead of macro, backported from trunk. (elscreen-get-screen-to-name-alist): Rewritten to improve performance, backported from trunk. (elscreen-kill-internal): Returns killed screen, backported from trunk. (elscreen-tab-display-kill-screen): Now it's used to set the location of the icon to kill a screen. Possible values are: 'left, 'right and nil (to hide icons). Backported from trunk. (elscreen-e21-tab-create-keymap): Take arguments forming a sequence of KEY FUNCTION pairs, backported from trunk. (elscreen-e21-tab-update): Follow above changes, and M-mouse-1 on the icon [X] now calls elscreen-kill-screen-and-buffers. 2006-12-06 Naoto Morishima ElScreen 1.4.5 released. 2006-12-03 Naoto Morishima * elscreen.el (elscreen-get-screen-to-name-alist): Use window-minibuffer-p instead of minibufferp, for XEmacs compatibility. 2006-12-01 Naoto Morishima ElScreen 1.4.4 released. 2006-11-30 Naoto Morishima * elscreen.el (elscreen-get-screen-to-name-alist): Don't add buffer name when it is minibuffer. 2006-08-13 Naoto Morishima * elscreen.el (elscreen-get-screen-to-name-alist): Add arguments of truncate-length and padding again. These arguments are deprecated and provided for backward compativility for a while. (elscreen-frame-confs): Make screen-history always have whole screens. (elscreen-append-screen-to-history): New function. (elscreen-create-internal): Call elscreen-append-screen-to-history. (elscreen-get-current-screen): Simply return car of screen-history. (elscreen-get-previouos-screen): Simply return cadr of screen-history. (elscreen-kill-internal): New function. (elscreen-kill, elscreen-kill-others): Use it. (elscreen-clone): Check if screen is alive. (elscreen-swap): Check if there are two or more screens. 2006-08-12 Naoto Morishima * elscreen.el (elscreen-get-conf-list, elscreen-get-conf-list) (elscreen-set-conf-list, elscreen-set-current-screen) (elscreen-get-current-screen, elscreen-get-previous-screen) (elscreen-delete-screen-from-history, elscreen-status-label) (elscreen-screen-modified-p, elscreen-set-screen-modified) (elscreen-get-screen-property, elscreen-set-screen-property) (elscreen-delete-screen-property) (elscreen-get-window-configuration) (elscreen-set-window-configuration) (elscreen-get-screen-nickname, elscreen-set-screen-nickname) (elscreen-delete-screen-nickname) (elscreen-get-screen-to-name-alist-cache) (elscreen-set-screen-to-name-alist-cache) (elscreen-get-number-of-screens, elscreen-one-screen-p) (elscreen-get-screen-list, elscreen-screen-live-p) (elscreen-find-screen): Remove the argument to specify frame. This function always affects selected-frame. (elscreen-find-screens): New function. (elscreen-find-screen): Rewritten with elscreen-find-screens. (elscreen-find-screen-by-buffer) (elscreen-find-and-goto-by-buffer): Use get-buffer-window. 2006-08-11 Naoto Morishima * elscreen.el (elscreen-truncate-screen-name): Fully rewritten. 2006-07-31 Naoto Morishima * elscreen.el (elscreen-run-screen-update-hook): Don't invoke elscreen-screen-update-hook when elscreen-frame-confs is nil. (elscreen-e21-menu-bar-command-entries) (elscreen-xmas-menu-bar-command-entries): Add new entries. (elscreen-menubar): Renamed to... (elscreen-xmas-menubar): this. (elscreen-xmas-tab-glyph): New variable for internal use. (elscreen-xmas-tab-update): New function to support tab on XEmacs. (elscreen-display-screen-number-toggle): Renamed to... (elscreen-toggle-display-screen-number): this. (elscreen-toggle-display-tab): New function. 2006-07-12 Naoto Morishima * elscreen.el (elscreen-get-current-screen) (elscreen-get-previous-screen): Return minimum screen when the value from screen-history is nil. 2006-07-08 Naoto Morishima * elscreen.el (elscreen-frame-confs): Change its structure as following: `screen-property and 'screen-history added. 'status removed ('current-screen and 'previous-screen are absorbed by 'screen-history). (elscreen-get-status, elscreen-set-status) (elscreen-set-previous-screen): Removed. (elscreen-get-screen-property, elscreen-set-screen-property) (elscreen-delete-screen-property): New function. (elscreen-get-window-configuration) (elscreen-set-window-configuration) (elscreen-get-screen-nickname, elscreen-set-screen-nickname) (elscreen-delete-screen-nickname): Use screen-property. (elscreen-delete-widnow-configuration): Removed. 2006-02-26 Naoto Morishima * elscreen.el (elscreen-screen-modified-hook-setup): Check whether hook-or-function is hook or function by its name instead of fboundp and boundp. Moreover fix bug that mode is not set properly. (elscreen-get-alist-to-nickname): Call string-or-function (in case that it is a function) without any arguments in condition-case form for backward compatibility. 2006-02-22 Naoto Morishima * elscreen.el (elscreen-tab-display-create-screen): Renamed to... (elscreen-tab-display-control): this. Now create-screen tab is upgraded to control tab, on which you can switch screen with mouse-1 and mouse-3, create new screen with mouse-2. (elscreen-tab-control-face): New face for control tab. (elscreen-e21-tab-create-keymap): Types of arguments are changed, now it takes 3 functions for mouse-1, mouse-2 and mouse-3. (elscreen-truncate-screen-name): New function. (elscreen-get-screen-to-name-alist): Don't truncate screen-name. Caller should apply (elscreen-truncate-screen-name) for each screen-name if needed. (elscreen-e21-tab-update): Displays control tab instead of create-screen tab. Also displays help-echo of complete screen-name on each screen tab. 2006-02-18 Naoto Morishima * elscreen.el (elscreen-e21-tab-escape-%): New function. (elscreen-e21-tab-update): Use elscreen-e21-tab-escape-% instead of replace-regexp-in-string to keep text properties. (elscreen-e21-mode-line-update): Now mode-line is updated by elscreen-run-screen-update-hook on GNU Emacs. 2005-12-17 Naoto Morishima ElScreen 1.4.3 released. 2005-12-16 Naoto Morishima * (elscreen-select-and-goto): Key binding is changed to ", for more compatibility with GNU screen. * (elscreen-goto): Now ' is bound to this function, for compatibility with GNU screen. * (elscreen-display-time): Display load average in addition to current time. 2005-12-14 Naoto Morishima * (elscreen-notify-screen-modification): Accept notifications on XEmacs 21.4, which does not have window-configuration-equal. 2005-12-13 Naoto Morishima * (elscreen-save-screen-excursion): Don't call elscreen-screen-number-string-update for XEmacs. * (elscreen-goto): Ditto, and call redraw-frame in case of FSF Emacs running on some window system and its major version equals 21. * (elscreen-screen-number-string-update): Renamed to... * (elscreen-xmas-mode-line-update): this, and now mode-line is updated by elscreen-run-screen-update-hook. 2005-12-11 Naoto Morishima * (elscreen-make-frame-confs): Save current buffer. * (elscreen-e21-tab-update): Use replace-regexp-in-string so that screen-names do not lose their properties. 2005-12-09 Naoto Morishima ElScreen 1.4.2 released. 2005-12-01 Naoto Morishima From Hideyuki SHIRAI : * (elscreen-execute-extended-command): Use completing-read instead of read-command to ensure that the extended-command-history is in operation on FSF Emacs. * (elscreen-dired): New function. 2005-11-29 Naoto Morishima * (elscreen-notify-screen-modification-suppress): Restore original flag when exiting from this macro. * (elscreen-make-frame-confs): Add 'screen-to-name-alist-cache to store cache of screen-to-name-alist. * (elscreen-get-screen-to-name-alist-cache): New function. * (elscreen-set-screen-to-name-alist-cache): Ditto. * (elscreen-get-screen-to-name-alist): Use cache of screen-name-to-alist instead of generating it when screen-modified-p is nil. From Hideyuki SHIRAI : * (elscreen-copy-tree): Fully rewritten, and use copy-tree if available. 2005-11-27 Naoto Morishima * (elscreen-kill-screen-and-buffers): New function. * (elscreen-command-line-funcall): New function. Now emacs accepts `-e' or `--elscreen-funcall' option with 1 argument in command line. * (elscreen-find-screen-by-buffer): Call elscreen-create-internal with arg 'noerror instead of t, for readability. * (elscreen-execute-extended-command): Ditto. * elscreen-menu-bar-command-entries: Renamed to... * elscreen-e21-menu-bar-command-entries: this, or... * elscreen-xmas-menu-bar-command-entries: this, properly. * (elscreen-run-screen-update-hook): Don't use post-command-hook to check whether menubar and tab are required to be updated. It is expected that this change improve feeling speed of each command, especially functions to move cursor such as forward-char. From Hideyuki SHIRAI : * (elscreen-e21-tab-update): Avoid unnecessary call of elscreen-get-screen-name-to-alist. 2005-11-26 Naoto Morishima * (elscreen-clone): New function. * (elscreen-bootstrap): Renamed to... * (elscreen-start): this. 2005-11-22 Naoto Morishima ElScreen 1.4.1 released. 2005-11-21 Naoto Morishima * (elscreen-find-and-goto-by-buffer): Select window displaying the specified buffer unless optional argument noselect is t. * (elscreen-find-file-read-only): New function. 2005-11-20 Naoto Morishima ElScreen 1.4.0 released. 2005-11-16 Naoto Morishima * (elscreen-apply-window-configuration): New function. * (elscreen-bootstrap): Ditto. 2005-11-14 Naoto Morishima * (elscreen-default-window-configuration): New function. * (elscreen-make-frame-confs): Set screen 0 to the default window configuration. * (elscreen-add-help): Renamed to... * (elscreen-set-help): this, and now argument of this function should be symbol of help string. * (elscreen-help): Rewritten. 2005-11-13 Naoto Morishima * elscreen-mode-to-nickname-alist-symbol-list: New variable. * elscreen-mode-to-nickname-alist-internal: Ditto. * (elscreen-rebuild-mode-to-nickname-alist): New function. * (elscreen-set-mode-to-nickname-alist): Ditto. * elscreen-buffer-to-nickname-alist-symbol-list: New variable. * elscreen-buffer-to-nickname-alist-internal: Ditto. * (elscreen-rebuild-buffer-to-nickname-alist): New function. * (elscreen-set-buffer-to-nickname-alist): Ditto. 2005-11-12 Naoto Morishima * elscreen-default-buffer-initial-major-mode: New variable. * elscreen-default-buffer-initial-message: Ditto. * (elscreen-create-internal): Insert default message and set major-mode when default buffer is created. * elscreen-startup-command-line-processing: Ditto. * (elscreen-command-line-find-file): New function. * (elscreen-e21-command-line): Ditto. * (elscreen-xmas-command-line-1): New advice. 2005-11-11 Naoto Morishima * Collect codes for mode-line, tab and menu together, and clean up tab and mode-line code for GNU Emacs. * Delete trailing whitespaces. 2005-11-10 Naoto Morishima * (elscreen-select-and-goto): Remove bound but unused variables. * (elscreen-display-screen-name-list): Ditto. * (elscreen-set-prefix-key): New function. * (elscreen-find-screen-by-buffer): Return nil if buffer does not exist. * (elscreen-find-screen-by-major-mode): regexp-quote'ize major-mode name. * (elscreen-find-screen-by-buffer): Don't use `with-selected-window', which does not exist on GNU Emacs 21. * (elscreen-find-screen-by-major-mode)): Ditto. From Hideyuki SHIRAI : * Use static-* to evaluate statically when compilation time. * (elscreen-select-and-goto): Specify tentative history-list in `read-from-minibuffer' to avoid adding its input to the global history-list. 2005-11-09 Naoto Morishima * (elscreen-screen-modified-hook): Renamed to... * (elscreen-notify-screen-modification): this, and now this calls `elscreen-run-screen-update-hook' when argument MODE is set to 'force-immediately. * (elscreen-screen-modified-set-hook): Renamed to... * (elscreen-screen-modified-hook-setup): this, and does not run `elscreen-screen-update-hook' any more. * (elscreen-select-and-goto): Use `read-from-minibuffer' to read key instead of 'read-char-exclusive' so that emacs can receive any commands in the other frames. Also avoid trying delete window for minibuffer when it is active. From Hideyuki SHIRAI : * (elscreen-kill-others): New function. * (elscreen-select-and-goto): Support several commands such as create, next, etc. Also set buffer for candidate read-only. * (elscreen-execute-extended-command): Fix bug that `target-screen' is not bounded by let. 2005-11-05 Naoto Morishima * (elscreen-status-label): New function. * (elscreen-find-screen): Ditto. * (elscreen-find-screen-by-buffer): Ditto. * (elscreen-find-screen-by-major-mode): Ditto. * (elscreen-goto-screen-with-buffer): Renamed to... * (elscreen-find-and-goto-by-buffer): this, and almost rewritten using `elscreen-find-screen-by-buffer'. This function now does not create new screen by default when target screen isn't found. Also this uses iswitchb-read-buffer if iswitchb is loaded. * (elscreen-find-file): Use `elscreen-find-and-goto-by-buffer'. From Hideyuki SHIRAI : * (elscreen-select-and-goto): New function. Now C-z g is bounded to this, instead of primitive `elscreen-goto'. 2005-11-04 Naoto Morishima * elscreen-screen-modified-hook-suppress: Renamed to... * elscreen-notify-screen-modification-suppress-flag: this. * (elscreen-notify-screen-modification-suppress): New macro. Several functions use this instead of setting `elscreen-screen-modified-hook-suppress-flag' directly. * (elscreen-one-screen-p): New function. Several functions now use this. * (elscreen-create-internal): New function. This creates new screen and just returns its number. * (elscreen-create): Just call `elscreen-create-internal' and `elscreen-goto'. * (elscreen-goto): Return screen if success, otherwise nil. 2005-11-03 Naoto Morishima * (elscreen-e21-tab-update): Replace `%' to `%%'. 2005-10-17 Naoto Morishima ElScreen 1.3.5 released. * (elscreen-goto-internal): Restore saved point-marker only when the stored marker is alive. 2005-10-08 Naoto Morishima ElScreen 1.3.4 released. From Yoshinori Koseki : * (elscreen-current-window-configuration): New function. This returns current-window-configuration with point-marker of current-buffer. * (elscreen-create): Use `elscreen-current-window-configuration' instead of `current-window-configuration'. * (elscreen-goto): Ditto. * (elscreen-get-screen-create): Ditto. * (elscreen-get-screen-to-name-alist): Ditto. * (elscreen-goto-internal): Restore saved point-marker in current-buffer in addition to window-configuration. 2005-09-12 Naoto Morishima ElScreen 1.3.3 released. 2004-08-23 Naoto Morishima ElScreen 1.3.2 released. * (elscreen-copy-tree): New function. Use this in `elscreen-save-screen-excursion' macro instead of copy-tree. * (elscreen-save-screen-excursion): Save and restore buffer-list, as set-window-configuration changes it. 2004-08-14 Naoto Morishima ElScreen 1.3.1 released. * (elscreen-save-screen-excursion): New macro. * (elscreen-get-screen-create): Use `elscreen-save-screen-excursion'. * (elscreen-get-screen-to-name-alist): Ditto. 2004-08-12 Naoto Morishima * (elscreen-create): Return screen number if new screen is created, otherwise nil. * (elscreen-kill): Return screen number if specified (or current) screen is successfully killed, otherwise nil. * (elscreen-get-screen-create): Return screen number if existing screen is found or new screen is created, otherwise nil. * (elscreen-e21-tab-update): If elscreen-display-tab is set to nil, set header-line-format to nil for each buffer only once. * (elscreen-swap): New function. * Set key-binding for `j' to `elscreen-link' instead of undefined `elscreen-join'. 2004-08-06 Naoto Morishima ElScreen 1.3.0 released. * Allmost all the functions are rewritten. * Add menu support for both GNU Emacs 21 and XEmacs. * Add tab support for GNU Emacs 21. Tab support for XEmacs is not planned at this moment, sorry. * Define custamizable variables using defcustom, instead of defvar. * Many functions are renamed. (elscreen-display-screen-number): Renamed from `elscreen-show-screen-number'. (elscreen-default-buffer-name): Renamed from `elscreen-scratch-buffer'. (elscreen-mode-to-nickname-alist): Renamed from `elscreen-mode-to-screen-alist'. (elscreen-buffer-to-nickname-alist): Renamed from `elscreen-buffer-to-screen-alist'. (elscreen-goto-internal): Renamed from `elscreen-goto0'. ... and many other functions and variables. * Data structure in which window configurations are kept is changed. 2002-08-28 Naoto Morishima ElScreen 1.2.4 released. 2002-08-21 Naoto Morishima From Dan Debertin : * Add elscreen-alloc-confs to hook after-make-frame-functions when create-frame-hook is not bounded. This will be able to avoid errors on GNU emacs. 2002-08-15 Naoto Morishima From : * Add some keysquences so that following keysequence pairs are bound to the same functionality. C-w / w C-k / k C-m / m 2002-07-18 Naoto Morishima * (elscreen-get-screen-create): In while loop, use elscreen-goto0 instead of elscreen-goto. 2002-06-11 Naoto Morishima From Yoichi NAKAYAMA : * (elscreen-show-list): Bug fixed. * (elscreen-message): Avoid error even when message contains format-string-like characters (e.g. "%" in the buffer name). * (elscreen-get-mode-list): Watch major-mode instead of its name. (elscreen-mode-to-screen-alist): Change default value. (elscreen-buffer-to-screen-alist): Ditto. 2001-09-19 Naoto Morishima ElScreen 1.2.2 released. * (elscreen-goto0): New function. * (elscreen-goto): Call redraw-frame. 2001-03-25 Naoto Morishima * Support multiple frames. 2000-01-08 Naoto Morishima ElScreen 1.12 released. * Use APEL for alist operation, instead of proprietary alist library. 1997-01-13 Naoto Morishima ElScreen 1.02 released. 1997-01-12 Naoto Morishima * Fix the bug of setting 'global-mode-string'. * Change the way to set 'global-map'. * (elscreen-suspend-emacs): Deleted. Use C-x C-z to suspend emacs instead. 1997-01-08 Naoto Morishima ElScreen 1.01 released. * (elscreen-suspend-emacs): New function. 1997-01-07 Naoto Morishima ElScreen 1.0 released. elscreen-1.4.6/elscreen.el010064400007650000000000002174161073546170500144660ustar naotowheel;; -*- Mode: Emacs-Lisp -*- ;; ;; elscreen.el ;; (defconst elscreen-version "1.4.6 (December 30, 2007)") ;; ;; Author: Naoto Morishima ;; Based on: screens.el ;; by Heikki T. Suopanki ;; Created: June 22, 1996 ;; Revised: December 30, 2007 ;; 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. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. (provide 'elscreen) (require 'alist) (eval-when-compile (require 'static)) (static-defconst elscreen-on-xemacs (featurep 'xemacs)) (static-defconst elscreen-on-emacs (and (not elscreen-on-xemacs) (>= emacs-major-version 21))) ;;; User Customizable Variables: (defgroup elscreen nil "ElScreen -- Screen Manager for Emacsen" :tag "ElScreen" :group 'environment) (defcustom elscreen-prefix-key "\C-z" "*Prefix key for ElScreen commands." :tag "Prefix Key of ElScreen" :type '(string :size 10) :set (lambda (symbol value) (when (boundp 'elscreen-map) (elscreen-set-prefix-key value)) (custom-set-default symbol value)) :group 'elscreen) (defcustom elscreen-default-buffer-name "*scratch*" "*Name of a buffer in new screen." :tag "Name of Default Buffer" :type '(string :size 24) :group 'elscreen) (defcustom elscreen-default-buffer-initial-major-mode initial-major-mode "*Major mode command symbol to use for the default buffer." :tag "Major Mode for Default Buffer" :type 'function :group 'elscreen) (defcustom elscreen-default-buffer-initial-message initial-scratch-message "*Initial message displayed in default buffer. If this is nil, no message will be displayed." :tag "Message to Display in the Default Buffer" :type '(choice (text :tag "Message") (const :tag "none" nil)) :group 'elscreen) (defcustom elscreen-mode-to-nickname-alist '(("^dired-mode$" . (lambda () (format "Dired(%s)" dired-directory))) ("^Info-mode$" . (lambda () (format "Info(%s)" (file-name-nondirectory Info-current-file)))) ("^mew-draft-mode$" . (lambda () (format "Mew(%s)" (buffer-name (current-buffer))))) ("^mew-" . "Mew") ("^irchat-" . "IRChat") ("^liece-" . "Liece") ("^lookup-" . "Lookup")) "*Alist composed of the pair of name of major-mode and corresponding screen-name." :tag "Alist to Derive Screen Names from Major Modes" :type '(alist :key-type string :value-type (choice string function)) :set (lambda (symbol value) (custom-set-default symbol value) (when (fboundp 'elscreen-rebuild-mode-to-nickname-alist) (elscreen-rebuild-mode-to-nickname-alist))) :group 'elscreen) (defcustom elscreen-buffer-to-nickname-alist '(("[Ss]hell" . "shell") ("compilation" . "compile") ("-telnet" . "telnet") ("dict" . "OnlineDict") ("*WL:Message*" . "Wanderlust")) "*Alist composed of the pair of regular expression of buffer-name and corresponding screen-name." :tag "Alist to Derive Screen Names from Major Modes" :type '(alist :key-type string :value-type (choice string function)) :set (lambda (symbol value) (custom-set-default symbol value) (when (fboundp 'elscreen-rebuild-buffer-to-nickname-alist) (elscreen-rebuild-buffer-to-nickname-alist))) :group 'elscreen) (defcustom elscreen-startup-command-line-processing t "*If non-nil, ElScreen processes command line when Emacsen starts up, and opens files with new screen if needed." :type 'boolean :tag "Enable/Disable ElScreen to Process Command Line Arguments" :group 'elscreen) (defcustom elscreen-display-screen-number t "*Non-nil to display the number of current screen in the mode line." :tag "Show/Hide Screen Number on the mode-line" :type 'boolean :group 'elscreen) (defcustom elscreen-display-tab t "*Specify how the tabs at the top of frame should be displayed. t means to display tabs whose width should be calculated automatically. A value of integer means to display tabs with fixed width of this value. nil means don't display tabs." :tag "Specify how the tabs at the top of frame should be displayed" :type '(choice (const :tag "Show (automatic width tab)" t) (integer :tag "Show (fixed width tab)" :size 4 :value 16) (const :tag "Hide" nil)) :set (lambda (symbol value) (when (or (booleanp value) (and (numberp value) (> value 0))) (custom-set-default symbol value) (static-cond (elscreen-on-emacs (when (fboundp 'elscreen-e21-tab-update) (elscreen-e21-tab-update t))) (elscreen-on-xemacs (when (fboundp 'elscreen-xmas-tab-update) (elscreen-xmas-tab-update t)))))) :group 'elscreen) (static-when elscreen-on-emacs ;; GNU Emacs 21 (make-obsolete-variable 'elscreen-tab-display-create-screen 'elscreen-tab-display-control) (defcustom elscreen-tab-display-control t "*Non-nil to display control tab at the most left side." :tag "Show/Hide the Control Tab" :type 'boolean :set (lambda (symbol value) (custom-set-default symbol value) (when (fboundp 'elscreen-e21-tab-update) (elscreen-e21-tab-update t))) :group 'elscreen) (defcustom elscreen-tab-display-kill-screen 'left "*Location of the icons to kill a screen on each tab. Possible values are 'left, 'right, or nil (to hide them)." :tag "Location of Buttons to Kill Screen on Each Tab" :type '(choice (const :tag "Left" left) (const :tag "Right" right) (const :tag "None" nil)) :set (lambda (symbol value) (custom-set-default symbol value) (when (fboundp 'elscreen-e21-tab-update) (elscreen-e21-tab-update t))) :group 'elscreen) (defface elscreen-tab-background-face '((((type x w32 mac) (class color)) :background "Gray50") (((class color)) (:background "black"))) "Face to fontify background of tab line." :group 'elscreen) (defface elscreen-tab-control-face '((((type x w32 mac) (class color)) (:background "white" :foreground "black" :underline "Gray50")) (((class color)) (:background "white" :foreground "black" :underline t)) (t (:underline t))) "Face for control tab." :group 'elscreen) (defface elscreen-tab-current-screen-face '((((class color)) (:background "white" :foreground "black")) (t (:underline t))) "Face for current screen tab." :group 'elscreen) (defface elscreen-tab-other-screen-face '((((type x w32 mac) (class color)) :background "Gray85" :foreground "Gray50") (((class color)) (:background "blue" :foreground "black" :underline t))) "Face for tabs other than current screen one." :group 'elscreen)) ;;; Key & Menu bindings: (defvar elscreen-map (make-sparse-keymap) "Keymap for ElScreen.") (define-key elscreen-map "\C-c" 'elscreen-create) (define-key elscreen-map "c" 'elscreen-create) (define-key elscreen-map "C" 'elscreen-clone) (define-key elscreen-map "\C-k" 'elscreen-kill) (define-key elscreen-map "k" 'elscreen-kill) (define-key elscreen-map "\M-k" 'elscreen-kill-screen-and-buffers) (define-key elscreen-map "K" 'elscreen-kill-others) (define-key elscreen-map "\C-p" 'elscreen-previous) (define-key elscreen-map "p" 'elscreen-previous) (define-key elscreen-map "\C-n" 'elscreen-next) (define-key elscreen-map "n" 'elscreen-next) (define-key elscreen-map "\C-a" 'elscreen-toggle) (define-key elscreen-map "a" 'elscreen-toggle) (define-key elscreen-map "'" 'elscreen-goto) (define-key elscreen-map "\"" 'elscreen-select-and-goto) (define-key elscreen-map "0" 'elscreen-jump-0) (define-key elscreen-map "1" 'elscreen-jump) (define-key elscreen-map "2" 'elscreen-jump) (define-key elscreen-map "3" 'elscreen-jump) (define-key elscreen-map "4" 'elscreen-jump) (define-key elscreen-map "5" 'elscreen-jump) (define-key elscreen-map "6" 'elscreen-jump) (define-key elscreen-map "7" 'elscreen-jump) (define-key elscreen-map "8" 'elscreen-jump) (define-key elscreen-map "9" 'elscreen-jump-9) (define-key elscreen-map "\C-s" 'elscreen-swap) (define-key elscreen-map "\C-w" 'elscreen-display-screen-name-list) (define-key elscreen-map "w" 'elscreen-display-screen-name-list) (define-key elscreen-map "\C-m" 'elscreen-display-last-message) (define-key elscreen-map "m" 'elscreen-display-last-message) (define-key elscreen-map "\C-t" 'elscreen-display-time) (define-key elscreen-map "t" 'elscreen-display-time) (define-key elscreen-map "A" 'elscreen-screen-nickname) (define-key elscreen-map "b" 'elscreen-find-and-goto-by-buffer) (define-key elscreen-map "\C-f" 'elscreen-find-file) (define-key elscreen-map "\C-r" 'elscreen-find-file-read-only) (define-key elscreen-map "d" 'elscreen-dired) (define-key elscreen-map "\M-x" 'elscreen-execute-extended-command) (define-key elscreen-map "i" 'elscreen-toggle-display-screen-number) (define-key elscreen-map "T" 'elscreen-toggle-display-tab) (define-key elscreen-map "?" 'elscreen-help) (define-key elscreen-map "v" 'elscreen-display-version) (define-key elscreen-map "j" 'elscreen-link) (define-key elscreen-map "s" 'elscreen-split) (defun elscreen-set-prefix-key (prefix-key) (when (not (eq elscreen-prefix-key prefix-key)) (when elscreen-prefix-key (global-set-key elscreen-prefix-key (get 'elscreen-prefix-key 'global-map-original-definition)) (define-key minibuffer-local-map elscreen-prefix-key (get 'elscreen-prefix-key 'minibuffer-local-map-original-definition))) (put 'elscreen-prefix-key 'global-map-original-definition (lookup-key global-map prefix-key)) (put 'elscreen-prefix-key 'minibuffer-local-map-original-definition (lookup-key minibuffer-local-map prefix-key))) (global-set-key prefix-key elscreen-map) (define-key minibuffer-local-map prefix-key 'undefined) (setq elscreen-prefix-key prefix-key)) (defvar elscreen-help "ElScreen keys: \\[elscreen-create] Create a new screen and switch to it \\[elscreen-clone] Create a new screen with the window-configuration of current screen \\[elscreen-kill] Kill current screen \\[elscreen-kill-screen-and-buffers] Kill current screen and buffers \\[elscreen-kill-others] Kill other screens \\[elscreen-next] Switch to the \"next\" screen in a cyclic order \\[elscreen-previous] Switch to the \"previous\" screen in a cyclic order \\[elscreen-toggle] Toggle to the screen selected previously \\[elscreen-select-and-goto] Jump to the specified screen \\[elscreen-jump-0] : Jump to the screen # \\[elscreen-jump-9] \\[elscreen-swap] Swap current screen with previous one \\[elscreen-display-screen-name-list] Show list of screens \\[elscreen-screen-nickname] Name current screen \\[elscreen-display-last-message] Show last message \\[elscreen-display-time] Show time \\[elscreen-find-and-goto-by-buffer] Switch to the screen in which specified buffer is displayed \\[elscreen-find-file] Create new screen and open file \\[elscreen-find-file-read-only] Create new screen and open file but don't allow changes \\[elscreen-dired] Create new screen and run dired \\[elscreen-execute-extended-command] Read function name, then call it with new screen \\[elscreen-toggle-display-screen-number] Show/hide the screen number in the mode line \\[elscreen-toggle-display-tab] Show/hide the tab at the top of screen \\[elscreen-display-version] Show ElScreen version \\[elscreen-help] Show this help" "Help shown by elscreen-help-mode") ;;; Internal Functions: (defvar elscreen-frame-confs nil "Alist that contains the information about screen configurations.") (defun elscreen-current-window-configuration () (list (current-window-configuration) (point-marker))) (defun elscreen-default-window-configuration () (let ((default-buffer (get-buffer elscreen-default-buffer-name))) (save-window-excursion (set-window-dedicated-p (selected-window) nil) (delete-other-windows) (if default-buffer (switch-to-buffer default-buffer) (switch-to-buffer (get-buffer-create elscreen-default-buffer-name)) (funcall elscreen-default-buffer-initial-major-mode) (insert elscreen-default-buffer-initial-message) (set-buffer-modified-p nil)) (elscreen-current-window-configuration)))) (defun elscreen-apply-window-configuration (elscreen-window-configuration) (let ((window-configuration (car elscreen-window-configuration)) (marker (cadr elscreen-window-configuration))) (set-window-configuration window-configuration) (when (marker-buffer marker) (goto-char marker)))) (defun get-alist (key alist) (cdr (assoc key alist))) (defsubst elscreen-copy-tree (tree) (if (fboundp 'copy-tree) (copy-tree tree) (elscreen-copy-tree-1 tree))) (defun elscreen-copy-tree-1 (tree) (let (clone) (while (consp tree) (setq clone (cons (or (and (consp (car tree)) (elscreen-copy-tree-1 (car tree))) (car tree)) clone)) (setq tree (cdr tree))) (nconc (nreverse clone) tree))) (defmacro elscreen-save-screen-excursion (&rest body) "Execute BODY, preserving ElScreen meta data. Return the value of the last form in BODY." `(let ((original-buffer-list (buffer-list)) (original-buffer-live-p nil) (original-elscreen-window-configuration (elscreen-current-window-configuration)) (original-frame-confs (elscreen-copy-tree elscreen-frame-confs))) (unwind-protect (save-window-excursion ,@body) (setq elscreen-frame-confs original-frame-confs) (elscreen-apply-window-configuration original-elscreen-window-configuration) (mapcar (lambda (buffer) (when (buffer-live-p buffer) (bury-buffer buffer) (setq original-buffer-live-p t))) original-buffer-list) (when original-buffer-live-p (while (not (memq (car (buffer-list)) original-buffer-list)) (bury-buffer (car (buffer-list)))))))) (defsubst elscreen-get-frame-confs (frame) (get-alist frame elscreen-frame-confs)) (defun elscreen-make-frame-confs (frame &optional keep-window-configuration) (when (null (elscreen-get-frame-confs frame)) (let ((selected-frame (selected-frame)) elscreen-window-configuration) (save-current-buffer (select-frame frame) (setq elscreen-window-configuration (if keep-window-configuration (elscreen-current-window-configuration) (elscreen-default-window-configuration))) (set-alist 'elscreen-frame-confs frame (list (cons 'screen-property (list (cons 0 (list (cons 'window-configuration elscreen-window-configuration))))) (cons 'screen-history (list 0)) (cons 'modified-inquirer nil) (cons 'screen-to-name-alist-cache nil))) (elscreen-apply-window-configuration elscreen-window-configuration) (elscreen-notify-screen-modification 'force-immediately) (select-frame selected-frame))))) (defun elscreen-delete-frame-confs (frame) (remove-alist 'elscreen-frame-confs frame)) (static-cond ((boundp 'after-make-frame-functions) ;; GNU Emacs 21 (add-hook 'after-make-frame-functions 'elscreen-make-frame-confs)) (t ;; XEmacs (add-hook 'create-frame-hook 'elscreen-make-frame-confs))) (static-cond ((boundp 'delete-frame-functions) ;; GNU Emacs 22? (add-hook 'delete-frame-functions 'elscreen-delete-frame-confs)) (t ;; XEmacs (add-hook 'delete-frame-hook 'elscreen-delete-frame-confs))) (defsubst elscreen-get-conf-list (type) (get-alist type (elscreen-get-frame-confs (selected-frame)))) (defsubst elscreen-set-conf-list (type conf-list) (let ((frame-conf (elscreen-get-frame-confs (selected-frame)))) (set-alist 'frame-conf type conf-list))) (defun elscreen-get-screen-property (screen) (let ((screen-property-list (elscreen-get-conf-list 'screen-property))) (get-alist screen screen-property-list))) (defun elscreen-set-screen-property (screen property) (let ((screen-property-list (elscreen-get-conf-list 'screen-property))) (set-alist 'screen-property-list screen property) (elscreen-set-conf-list 'screen-property screen-property-list))) (defun elscreen-delete-screen-property (screen) (let ((screen-property-list (elscreen-get-conf-list 'screen-property))) (remove-alist 'screen-property-list screen) (elscreen-set-conf-list 'screen-property screen-property-list))) (defun elscreen-get-number-of-screens () "Return total number of screens." (length (elscreen-get-conf-list 'screen-property))) (defun elscreen-one-screen-p () "Return t if there is only one screen." (= (elscreen-get-number-of-screens) 1)) (defun elscreen-get-screen-list () "Return a list of screen numbers." (mapcar 'car (elscreen-get-conf-list 'screen-property))) (defun elscreen-screen-live-p (screen) "Return t when SCREEN is alive." (not (null (elscreen-get-screen-property screen)))) (defun elscreen-get-window-configuration (screen) "Return pair of window-configuration and marker of SCREEN from `elscreen-frame-confs', a cons cell." (let ((screen-property (elscreen-get-screen-property screen))) (get-alist 'window-configuration screen-property))) (defun elscreen-set-window-configuration (screen winconf) "Set pair of window-configuration and marker of SCREEN to WINCONF." (let ((screen-property (elscreen-get-screen-property screen))) (set-alist 'screen-property 'window-configuration winconf) (elscreen-set-screen-property screen screen-property))) (defun elscreen-get-screen-nickname (screen) "Return nickname of SCREEN from `elscreen-frame-confs', a string." (let ((screen-property (elscreen-get-screen-property screen))) (get-alist 'nickname screen-property))) (defun elscreen-set-screen-nickname (screen nickname) "Set nickname of SCREEN to NICKNAME." (let ((screen-property (elscreen-get-screen-property screen))) (set-alist 'screen-property 'nickname nickname) (elscreen-set-screen-property screen screen-property))) (defun elscreen-delete-screen-nickname (screen) "Remove nickname of SCREEN from `elscreen-frame-confs'." (let ((screen-property (elscreen-get-screen-property screen))) (remove-alist 'screen-property 'nickname) (elscreen-set-screen-property screen screen-property))) (defun elscreen-append-screen-to-history (screen) (let ((screen-history (elscreen-get-conf-list 'screen-history))) (setcdr (last screen-history) (list screen)))) (defun elscreen-delete-screen-from-history (screen) (let ((screen-history (elscreen-get-conf-list 'screen-history))) (setq screen-history (delq screen screen-history)) (elscreen-set-conf-list 'screen-history screen-history))) (defun elscreen-set-current-screen (screen) (let ((screen-history (elscreen-get-conf-list 'screen-history))) (setq screen-history (cons screen (delq screen screen-history))) (elscreen-set-conf-list 'screen-history screen-history))) (defun elscreen-get-current-screen () (car (elscreen-get-conf-list 'screen-history))) (defun elscreen-get-previous-screen () (cadr (elscreen-get-conf-list 'screen-history))) (defun elscreen-status-label (screen &optional default) (let ((default (or default " ")) (current-screen (elscreen-get-current-screen)) (previous-screen (elscreen-get-previous-screen))) (cond ((eq screen current-screen) "+") ((eq screen previous-screen) "-") (t default)))) (defvar elscreen-notify-screen-modification-suppress-flag nil) (defmacro elscreen-notify-screen-modification-suppress (&rest body) `(let ((elscreen-notify-screen-modification-suppress-flag t)) ,@body)) (defvar elscreen-screen-update-hook nil) (defun elscreen-run-screen-update-hook () (when elscreen-frame-confs (elscreen-notify-screen-modification-suppress (run-hooks 'elscreen-screen-update-hook))) (remove-hook 'post-command-hook 'elscreen-run-screen-update-hook)) (defun elscreen-screen-modified-p (inquirer) (let* ((inquirer-list (elscreen-get-conf-list 'modified-inquirer)) (modified (null (memq inquirer inquirer-list)))) (add-to-list 'inquirer-list inquirer) (elscreen-set-conf-list 'modified-inquirer inquirer-list) modified)) (defun elscreen-set-screen-modified () (elscreen-set-conf-list 'modified-inquirer nil) (add-hook 'post-command-hook 'elscreen-run-screen-update-hook)) (cond ((fboundp 'compare-window-configurations)) ;; GNU Emacs ((fboundp 'window-configuration-equal) ;; XEmacs 21.5 (defalias 'compare-window-configurations 'window-configuration-equal))) (defvar elscreen-screen-modified-hook-pwc nil) (defun elscreen-notify-screen-modification (&optional mode) (when (and (not (window-minibuffer-p)) (not elscreen-notify-screen-modification-suppress-flag) (or (eq mode 'force) (eq mode 'force-immediately) (null elscreen-screen-modified-hook-pwc) (not (fboundp 'compare-window-configurations)) (not (compare-window-configurations (current-window-configuration) elscreen-screen-modified-hook-pwc)))) (setq elscreen-screen-modified-hook-pwc (current-window-configuration)) (elscreen-set-screen-modified) (when (eq mode 'force-immediately) (elscreen-run-screen-update-hook)))) (defmacro elscreen-screen-modified-hook-setup (&rest hooks-and-functions) (cons 'progn (mapcar (lambda (hook-or-function) (let ((mode ''normal)) (when (listp hook-or-function) (setq mode (nth 1 hook-or-function)) (setq hook-or-function (nth 0 hook-or-function))) (cond ((string-match "-\\(hooks?\\|functions\\)$" (symbol-name hook-or-function)) `(add-hook (quote ,hook-or-function) (lambda (&rest ignore) (elscreen-notify-screen-modification ,mode)))) (t ;; Assume hook-or-function is function `(defadvice ,hook-or-function (around elscreen-screen-modified-advice activate) ad-do-it (elscreen-notify-screen-modification ,mode)))))) hooks-and-functions))) (elscreen-screen-modified-hook-setup (recenter 'force) (change-major-mode-hook 'force) other-window window-configuration-change-hook window-size-change-functions (handle-switch-frame 'force) ;; GNU Emacs 21 (select-frame-hook 'force) ;; XEmacs (delete-frame 'force) (Info-find-node-2 'force)) (defun elscreen-get-screen-to-name-alist-cache () (elscreen-get-conf-list 'screen-to-name-alist-cache)) (defun elscreen-set-screen-to-name-alist-cache (alist) (elscreen-set-conf-list 'screen-to-name-alist-cache alist)) (defvar elscreen-mode-to-nickname-alist-symbol-list nil) (defvar elscreen-mode-to-nickname-alist-internal nil) (defun elscreen-rebuild-mode-to-nickname-alist () (setq elscreen-mode-to-nickname-alist-internal (apply 'append (mapcar 'symbol-value elscreen-mode-to-nickname-alist-symbol-list))) (elscreen-notify-screen-modification 'force-immediately)) (defun elscreen-set-mode-to-nickname-alist (mode-to-nickname-alist-symbol) (add-to-list 'elscreen-mode-to-nickname-alist-symbol-list mode-to-nickname-alist-symbol) (elscreen-rebuild-mode-to-nickname-alist)) (elscreen-set-mode-to-nickname-alist 'elscreen-mode-to-nickname-alist) (defvar elscreen-buffer-to-nickname-alist-symbol-list nil) (defvar elscreen-buffer-to-nickname-alist-internal nil) (defun elscreen-rebuild-buffer-to-nickname-alist () (setq elscreen-buffer-to-nickname-alist-internal (apply 'append (mapcar 'symbol-value elscreen-buffer-to-nickname-alist-symbol-list))) (elscreen-notify-screen-modification 'force-immediately)) (defun elscreen-set-buffer-to-nickname-alist (buffer-to-nickname-alist-symbol) (add-to-list 'elscreen-buffer-to-nickname-alist-symbol-list buffer-to-nickname-alist-symbol) (elscreen-rebuild-buffer-to-nickname-alist)) (elscreen-set-buffer-to-nickname-alist 'elscreen-buffer-to-nickname-alist) (defsubst elscreen-get-alist-to-nickname (alist op mode-or-buffer-name) (catch 'found (progn (mapcar (lambda (map) (let ((nickname nil) (condition-data (car map)) (string-or-function (cdr map))) (when (funcall op condition-data mode-or-buffer-name) (cond ((functionp string-or-function) (setq nickname (condition-case nil (funcall string-or-function) (wrong-number-of-arguments (funcall string-or-function (current-buffer)))))) (t (setq nickname string-or-function))) (throw 'found (cons 'nickname nickname))))) alist) nil))) (defun elscreen-get-screen-to-name-alist (&optional truncate-length padding) (when (elscreen-screen-modified-p 'elscreen-get-screen-to-name-alist) (elscreen-notify-screen-modification-suppress (elscreen-set-window-configuration (elscreen-get-current-screen) (elscreen-current-window-configuration)) (let* ((screen-list (sort (elscreen-get-screen-list) '<)) screen-name screen-to-name-alist nickname-type-map) (elscreen-save-screen-excursion (mapcar (lambda (screen) ;; If nickname exists, use it. (setq screen-name (elscreen-get-screen-nickname screen)) ;; Nickname does not exist, so examine major-mode and buffer-name. (when (null screen-name) (elscreen-goto-internal screen) (setq nickname-type-map (mapcar (lambda (window) (with-current-buffer (window-buffer window) (or (elscreen-get-alist-to-nickname elscreen-mode-to-nickname-alist-internal 'string-match (symbol-name major-mode)) (elscreen-get-alist-to-nickname elscreen-buffer-to-nickname-alist-internal 'string-match (buffer-name)) (cons 'buffer-name (buffer-name))))) (window-list))) (let (nickname-list) (while (> (length nickname-type-map) 0) (let ((type (caar nickname-type-map)) (name (cdar nickname-type-map))) (when name (setq nickname-list (cons name nickname-list))) (setq nickname-type-map (if (eq type 'nickname) (delete (car nickname-type-map) nickname-type-map) (cdr nickname-type-map))))) (setq screen-name (mapconcat 'identity (reverse nickname-list) ":")))) (set-alist 'screen-to-name-alist screen screen-name)) screen-list)) (elscreen-set-screen-to-name-alist-cache screen-to-name-alist)))) ;; Arguments of truncate-length and padding are deprecated. (if truncate-length (let ((screen-to-name-alist (copy-alist (elscreen-get-screen-to-name-alist-cache)))) (elscreen-message "Arguments for `elscreen-get-screen-to-name-alist' are deprecated. Use elscreen-truncate-screen-name for each screen-name.") (mapc (lambda (screen-to-name) (setcdr screen-to-name (elscreen-truncate-screen-name (cdr screen-to-name) truncate-length padding))) screen-to-name-alist) screen-to-name-alist) (elscreen-get-screen-to-name-alist-cache))) (defun elscreen-truncate-screen-name (screen-name truncate-length &optional padding) (let ((truncate-length (max truncate-length 4))) (cond ((> (string-width screen-name) truncate-length) (concat (truncate-string-to-width screen-name (- truncate-length 3) nil ?.) "...")) (padding (truncate-string-to-width screen-name truncate-length nil ?\ )) (t screen-name)))) (defun elscreen-goto-internal (screen) "Set the configuration of windows, buffers and markers previousuly stored as SCREEN." (let ((elscreen-window-configuration (elscreen-get-window-configuration screen))) (elscreen-apply-window-configuration elscreen-window-configuration))) (defvar elscreen-create-hook nil) (defun elscreen-create-internal (&optional noerror) "Create a new screen. If NOERROR is not nil, no message is displayed in mini buffer when error is occurred." (cond ((>= (elscreen-get-number-of-screens) 10) (unless noerror (elscreen-message "No more screens.")) nil) (t (let ((screen-list (sort (elscreen-get-screen-list) '<)) (screen 0)) (elscreen-set-window-configuration (elscreen-get-current-screen) (elscreen-current-window-configuration)) (while (eq (nth screen screen-list) screen) (setq screen (+ screen 1))) (elscreen-set-window-configuration screen (elscreen-default-window-configuration)) (elscreen-append-screen-to-history screen) (elscreen-notify-screen-modification 'force) (run-hooks 'elscreen-create-hook) screen)))) (defun elscreen-kill-internal (screen) (elscreen-delete-screen-property screen) (elscreen-delete-screen-from-history screen) screen) (defun elscreen-find-screens (condition) (let ((screen-list (sort (elscreen-get-screen-list) '<)) result) (save-current-buffer (elscreen-set-window-configuration (elscreen-get-current-screen) (elscreen-current-window-configuration)) (elscreen-notify-screen-modification-suppress (elscreen-save-screen-excursion (mapc (lambda (screen) (when (funcall condition screen) (setq result (cons screen result)))) screen-list)) result)))) (defun elscreen-find-screen (condition) (catch 'elscreen-find-screen (elscreen-find-screens `(lambda (screen) (when (funcall ,condition screen) (throw 'elscreen-find-screen screen)))))) (defun elscreen-find-screen-by-buffer (buffer &optional create) (let* ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) (screen (when buffer (elscreen-find-screen `(lambda (screen) (elscreen-goto-internal screen) (not (null (get-buffer-window ,buffer)))))))) (when (and buffer (null screen) create) (cond ((setq screen (elscreen-create-internal 'noerror)) (save-window-excursion (elscreen-goto-internal screen) (switch-to-buffer buffer t) (elscreen-set-window-configuration screen (elscreen-current-window-configuration)))) (t (setq screen (elscreen-get-current-screen)) (elscreen-goto-internal screen) (save-selected-window (select-window (split-window)) (switch-to-buffer buffer t))))) screen)) (defun elscreen-find-screen-by-major-mode (major-mode-or-re) (let ((major-mode-re (cond ((stringp major-mode-or-re) major-mode-or-re) ((symbolp major-mode-or-re) (format "^%s$" (regexp-quote (symbol-name major-mode-or-re)))) (t nil)))) (when major-mode-re (elscreen-find-screen (lambda (screen) (elscreen-goto-internal screen) (save-selected-window (catch 'found (mapcar (lambda (window) (select-window window) (when (string-match major-mode-re (symbol-name major-mode)) (throw 'found t))) (window-list)) nil))))))) (defvar elscreen-last-message "Welcome to ElScreen!" "Last shown message.") (defun elscreen-message (message &optional sec) "Display MESSAGE in mini-buffer for SEC seconds. Default value for SEC is 3." (when message (setq elscreen-last-message message) (message "%s" message) (sit-for (or sec 3))) (message nil)) ;;; User Interfaces: (defun elscreen-create () "Create a new screen and switch to it." (interactive) (let ((screen (elscreen-create-internal))) (if screen (elscreen-goto screen)))) (defun elscreen-clone (&optional screen) "Create a new screen with the window-configuration of SCREEN. If SCREEN is ommitted, current-screen is used." (interactive) (let ((screen (or screen (elscreen-get-current-screen))) clone elscreen-window-configuration) (cond ((not (elscreen-screen-live-p screen)) (elscreen-message "There is no such screen, cannot clone")) ((setq clone (elscreen-create-internal)) (save-window-excursion (elscreen-goto-internal screen) (setq elscreen-window-configuration (elscreen-current-window-configuration))) (elscreen-set-window-configuration clone elscreen-window-configuration) (elscreen-goto clone))))) (defvar elscreen-kill-hook nil) (defun elscreen-kill (&optional screen) "Kill SCREEN. If optional argument SCREEN is ommitted, current-screen is killed." (interactive "P") (let ((screen (or (and (numberp screen) screen) (elscreen-get-current-screen)))) (cond ((not (elscreen-screen-live-p screen)) (elscreen-message "There is no such screen, cannot kill") nil) ((elscreen-one-screen-p) (elscreen-message "There is only one screen, cannot kill") nil) (t (elscreen-kill-internal screen) (elscreen-goto-internal (elscreen-get-current-screen)) (elscreen-notify-screen-modification 'force) (run-hooks 'elscreen-kill-hook) screen)))) (defun elscreen-kill-screen-and-buffers (&optional screen) "Kill buffers on SCREEN and SCREEN itself. If optional argument SCREEN is omitted, current screen is killed." (interactive) (let* ((screen (or screen (elscreen-get-current-screen))) (elscreen-window-configuration (elscreen-get-window-configuration screen))) (when (elscreen-kill screen) (save-window-excursion (elscreen-apply-window-configuration elscreen-window-configuration) (mapc (lambda (buffer) (when (buffer-live-p buffer) (kill-buffer buffer))) (mapcar 'window-buffer (window-list)))) screen))) (defun elscreen-kill-others (&optional screen) "Kill screens other than SCREEN. If optional argument SCREEN is ommitted, current screen will survive." (interactive) (let* ((screen (or screen (elscreen-get-current-screen))) (screen-list (when (elscreen-screen-live-p screen) (delq screen (sort (elscreen-get-screen-list) '<)))) screen-list-string) (cond ((not (elscreen-screen-live-p screen)) ;; XXX (when (interactive-p) (elscreen-message "There is no such screen"))) ((null screen-list) (when (interactive-p) (elscreen-message "There is only one screen, cannot kill"))) ((or (not (interactive-p)) (yes-or-no-p (format "Really kill screens other than %d? " screen))) (setq screen-list-string (mapconcat (lambda (screen) (elscreen-kill-internal screen) (number-to-string screen)) screen-list ",")) (elscreen-goto-internal screen) (elscreen-notify-screen-modification 'force-immediately) (when (interactive-p) (elscreen-message (format "screen %s killed" screen-list-string))))) screen-list)) (defvar elscreen-goto-hook nil) (defun elscreen-goto (screen) "Switch to screen SCREEN." (interactive "NGoto screen number: ") (cond ((eq (elscreen-get-current-screen) screen)) ((elscreen-screen-live-p screen) (elscreen-set-window-configuration (elscreen-get-current-screen) (elscreen-current-window-configuration)) (elscreen-set-current-screen screen) (elscreen-goto-internal screen) (static-when (and elscreen-on-emacs (= emacs-major-version 21)) (when window-system (redraw-frame (selected-frame)))) (elscreen-notify-screen-modification 'force) (run-hooks 'elscreen-goto-hook) screen) (t (elscreen-message (format "No screen %d" screen)) nil))) (defun elscreen-next () "Switch to the next screen." (interactive) (cond ((elscreen-one-screen-p) (elscreen-message (format "You cannot escape from screen %d!" (elscreen-get-current-screen)))) (t (let* ((screen-list (sort (elscreen-get-screen-list) '<)) (next-screen (or (nth 1 (memq (elscreen-get-current-screen) screen-list)) (car screen-list)))) (elscreen-goto next-screen))))) (defun elscreen-previous () "Switch to the previous screen." (interactive) (cond ((elscreen-one-screen-p) (elscreen-message (format "You cannot escape from screen %d!" (elscreen-get-current-screen)))) (t (let* ((screen-list (sort (elscreen-get-screen-list) '>)) (previous-screen (or (nth 1 (memq (elscreen-get-current-screen) screen-list)) (car screen-list)))) (elscreen-goto previous-screen))))) (defun elscreen-toggle () "Toggle to the screen selected previously." (interactive) (cond ((elscreen-one-screen-p) (elscreen-message (format "You cannot escape from screen %d!" (elscreen-get-current-screen)))) (t (elscreen-goto (elscreen-get-previous-screen))))) (defun elscreen-jump () "Switch to specified screen." (interactive) (let ((next-screen (string-to-number (string last-command-char)))) (if (and (<= 0 next-screen) (<= next-screen 9)) (elscreen-goto next-screen)))) (defalias 'elscreen-jump-0 'elscreen-jump) (defalias 'elscreen-jump-9 'elscreen-jump) (defun elscreen-swap () "Interchange screens selected currently and previously." (interactive) (cond ((elscreen-one-screen-p) (elscreen-message "There is only one screen, cannot swap")) (t (let* ((current-screen (elscreen-get-current-screen)) (previous-screen (elscreen-get-previous-screen)) (current-screen-property (elscreen-get-screen-property current-screen)) (previous-screen-property (elscreen-get-screen-property previous-screen))) (elscreen-set-screen-property current-screen previous-screen-property) (elscreen-set-screen-property previous-screen current-screen-property) (elscreen-goto-internal (elscreen-get-current-screen)))))) (defun elscreen-screen-nickname (nickname) "Set nickname for current screen to NICKNAME." (interactive "sSet window title to: ") (cond ((zerop (length nickname)) (elscreen-delete-screen-nickname (elscreen-get-current-screen))) (t (elscreen-set-screen-nickname (elscreen-get-current-screen) nickname))) (elscreen-notify-screen-modification 'force)) (defun elscreen-display-screen-name-list () "Display the list of screens in mini-buffer." (interactive) (let ((screen-list (sort (elscreen-get-screen-list) '<)) (screen-to-name-alist (elscreen-get-screen-to-name-alist))) (elscreen-message (mapconcat (lambda (screen) (let ((screen-name (get-alist screen screen-to-name-alist))) (format "%d%s %s" screen (elscreen-status-label screen "") screen-name))) screen-list " ")))) ;;; Help (defvar elscreen-help-symbol-list nil) (defun elscreen-set-help (help-symbol) (add-to-list 'elscreen-help-symbol-list help-symbol t)) (elscreen-set-help 'elscreen-help) (defun elscreen-help () "Show key bindings of ElScreen and Add-On softwares." (interactive) (with-output-to-temp-buffer "*ElScreen Help*" (princ (substitute-command-keys (mapconcat 'symbol-value elscreen-help-symbol-list "\n\n"))) (print-help-return-message))) ;;; Utility Functions (defun elscreen-display-version () "Display ElScreen version." (interactive) (elscreen-message (concat "ElScreen version " elscreen-version))) (defun elscreen-toggle-display-screen-number () "Toggle the screen number in the mode line." (interactive) (setq elscreen-display-screen-number (null elscreen-display-screen-number)) (elscreen-notify-screen-modification 'force)) (defun elscreen-toggle-display-tab () "Toggle the tab on the top of screen." (interactive) (setq elscreen-display-tab (null elscreen-display-tab)) (elscreen-notify-screen-modification 'force)) (defun elscreen-display-last-message () "Repeat the last message displayed in the mini-buffer." (interactive) (elscreen-message elscreen-last-message 5)) (defun elscreen-display-time () "Show system information." (interactive) (elscreen-message (format "%s %s / %s" (current-time-string) (nth 1 (current-time-zone)) (mapconcat (lambda (load) (format "%.2f" (/ load 100.0))) (load-average) " ")))) (defun elscreen-select-and-goto () (interactive) (let* ((screen-list (sort (elscreen-get-screen-list) '<)) (screen-to-name-alist (elscreen-get-screen-to-name-alist)) (command-list '(("c" . elscreen-create) ("n" . elscreen-next) ("p" . elscreen-previous) ("t" . elscreen-toggle))) (truncate-length (- (frame-width) 6)) (candidate-window-height (max (+ (elscreen-get-number-of-screens) 4) window-min-height)) (candidate-buffer (get-buffer-create (format " *ElScreen-select:%s*" (prin1-to-string (selected-frame))))) (candidate (concat "Current screen list: \n\n" (mapconcat (lambda (screen) (format " %d%s %s\n" screen (elscreen-status-label screen) (elscreen-truncate-screen-name (get-alist screen screen-to-name-alist) truncate-length))) screen-list nil))) (prompt "Select screen or (c)reate, (n)ext, (p)revious, (t)oggle: ") (minibuffer-map (copy-keymap minibuffer-local-map)) window frame-last-window command-or-target-screen mini-hist) ;; prepare window to show candidates (save-window-excursion (setq frame-last-window (previous-window (static-if elscreen-on-xemacs (frame-highest-window) (frame-first-window)))) (while (minibuffer-window-active-p frame-last-window) (setq frame-last-window (previous-window frame-last-window))) (while (and (not (one-window-p)) (or (< (window-width frame-last-window) (frame-width)) (< (window-height frame-last-window) (+ candidate-window-height window-min-height)))) (setq window frame-last-window) (setq frame-last-window (previous-window window)) (delete-window window)) (select-window (split-window frame-last-window)) (shrink-window (- (window-height) candidate-window-height)) ;; now switch to the buffer for candidates and fill it (switch-to-buffer candidate-buffer) (let ((buffer-read-only nil)) (erase-buffer) (insert candidate) (goto-char (point-min)) (save-excursion (while (not (eobp)) (when (looking-at "^ \\([0-9]\\)\\(.\\) \\(.*\\)$") (put-text-property (match-beginning 1) (match-end 1) 'face 'bold) (cond ((string= (match-string 2) "+") (put-text-property (match-beginning 3) (match-end 3) 'face 'bold)))) (forward-line 1))) (setq buffer-read-only t) (set-buffer-modified-p nil)) ;; make keymap for minibuffer (suppress-keymap minibuffer-map t) (define-key minibuffer-map "\C-g" 'abort-recursive-edit) (define-key minibuffer-map "\C-m" 'exit-recursive-edit) (define-key minibuffer-map "q" 'exit-recursive-edit) (define-key minibuffer-map " " 'exit-recursive-edit) (mapcar (lambda (command) (define-key minibuffer-map (car command) 'self-insert-and-exit)) command-list) (mapcar (lambda (screen) (define-key minibuffer-map (number-to-string screen) 'self-insert-and-exit)) screen-list) ;; read key from minibuffer (unwind-protect (setq command-or-target-screen (read-from-minibuffer prompt nil minibuffer-map nil 'mini-hist)) (kill-buffer candidate-buffer))) (cond ((string= command-or-target-screen "")) ((get-alist command-or-target-screen command-list) (funcall (get-alist command-or-target-screen command-list))) (t (elscreen-goto (string-to-number command-or-target-screen)))))) (defun elscreen-find-and-goto-by-buffer (&optional buffer create noselect) "Go to the screen that has the window with buffer BUFFER, creating one if none already exists." (interactive) (let* ((prompt "Go to the screen with specified buffer: ") (create (or create (interactive-p))) (buffer-name (or (and (bufferp buffer) (buffer-name buffer)) (and (stringp buffer) buffer) (and (featurep 'iswitchb) (iswitchb-read-buffer prompt)) (read-buffer prompt))) (target-screen (elscreen-find-screen-by-buffer (get-buffer-create buffer-name) create))) (when target-screen (elscreen-goto target-screen) (unless noselect (select-window (get-buffer-window buffer-name)))) target-screen)) (defun elscreen-find-file (filename) "Edit file FILENAME. Switch to a screen visiting file FILENAME, creating one if none already exists." (interactive "FFind file in new screen: ") (elscreen-find-and-goto-by-buffer (find-file-noselect filename) 'create)) (defun elscreen-find-file-read-only (filename) "Edit file FILENAME with new screen but don't allow changes. Like \\[elscreen-find-file] but marks buffer as read-only. Use \\[toggle-read-only] to permit editing." (interactive "FFind file read-only in new screen: ") (elscreen-find-file filename) (toggle-read-only 1)) (defun elscreen-dired (dirname &optional switches) (interactive (progn (or (featurep 'dired) (require 'dired)) (dired-read-dir-and-switches "in new screen "))) (elscreen-find-and-goto-by-buffer (dired-noselect dirname switches) 'create)) (defun elscreen-execute-extended-command (prefix-arg) (interactive "P") (let ((prefix-arg prefix-arg) (prefix-key (key-description elscreen-prefix-key)) target-screen) (setq this-command (intern (completing-read ;; Note: this has the hard-wired ;; "C-u" and "M-x" string bug in common ;; with all Emacs's. ;; (i.e. it prints C-u and M-x regardless of ;; whether some other keys were actually bound ;; to `execute-extended-command' and ;; `universal-argument'. (cond ((eq prefix-arg '-) (format "- %s M-x " prefix-key)) ((equal prefix-arg '(4)) (format "C-u %s M-x " prefix-key)) ((integerp prefix-arg) (format "%d %s M-x " prefix-arg prefix-key)) ((and (consp prefix-arg) (integerp (car prefix-arg))) (format "%d %s M-x " (car prefix-arg) prefix-key)) (t (format "%s M-x " prefix-key))) obarray 'commandp t nil (static-if elscreen-on-xemacs 'read-command-history 'extended-command-history)))) (if (setq target-screen (elscreen-create-internal 'noerror)) (elscreen-goto target-screen) (select-window (split-window))) (command-execute this-command t))) ;;; Mode Line & Menu & Tab ;; GNU Emacs (static-when elscreen-on-emacs ;; Mode Line (defvar elscreen-e21-mode-line-string "[0]") (defun elscreen-e21-mode-line-update () (when (elscreen-screen-modified-p 'elscreen-e21-mode-line-update) (setq elscreen-e21-mode-line-string (format "[%d]" (elscreen-get-current-screen))) (force-mode-line-update))) (let ((point (or ;; GNU Emacs 21.3.50 or later (memq 'mode-line-position mode-line-format) ;; GNU Emacs 21.3.1 (memq 'mode-line-buffer-identification mode-line-format))) (elscreen-mode-line-elm '(elscreen-display-screen-number (" " elscreen-e21-mode-line-string)))) (when (null (member elscreen-mode-line-elm mode-line-format)) (setcdr point (cons elscreen-mode-line-elm (cdr point))))) (add-hook 'elscreen-screen-update-hook 'elscreen-e21-mode-line-update) ;; Menu (define-key-after (lookup-key global-map [menu-bar]) [elscreen] (cons "ElScreen" (make-sparse-keymap "ElScreen")) 'buffer) (defvar elscreen-e21-menu-bar-command-entries (list (list 'elscreen-command-separator 'menu-item "--") (list 'elscreen-create 'menu-item "Create Screen" 'elscreen-create :help "Create a new screen and switch to it") (list 'elscreen-clone 'menu-item "Clone Screen" 'elscreen-clone :help "Create a new screen with the window-configuration of current screen") (list 'elscreen-kill 'menu-item "Kill Screen" 'elscreen-kill :help "Kill current screen") (list 'elscreen-kill-screen-and-buffers 'menu-item "Kill Screen and Buffers" 'elscreen-kill-screen-and-buffers :help "Kill current screen and buffers") (list 'elscreen-kill-others 'menu-item "Kill Other Screens" 'elscreen-kill-others :help "Kill other screens") (list 'elscreen-next 'menu-item "Next Screen" 'elscreen-next :help "Switch to the \"next\" screen in a cyclic order") (list 'elscreen-previous 'menu-item "Previous Screen" 'elscreen-previous :help "Switch to the \"previous\" screen in a cyclic order") (list 'elscreen-toggle 'menu-item "Toggle Screen" 'elscreen-toggle :help "Toggle to the screen selected previously") (list 'elscreen-command-separator 'menu-item "--") (list 'elscreen-toggle-display-screen-number 'menu-item "Display Screen Number" 'elscreen-toggle-display-screen-number :help "Display screen number on the mode line" :button '(:toggle . elscreen-display-screen-number)) (list 'elscreen-toggle-display-tab 'menu-item "Display Tab" 'elscreen-toggle-display-tab :help "Display tab on the top of screen" :button '(:toggle . elscreen-display-tab)))) (defun elscreen-e21-menu-bar-update (&optional force) (when (and (lookup-key (current-global-map) [menu-bar elscreen]) (or force (elscreen-screen-modified-p 'elscreen-menu-bar-update))) (let ((screen-list (sort (elscreen-get-screen-list) '<)) (screen-to-name-alist (elscreen-get-screen-to-name-alist)) (elscreen-menu nil)) (setq elscreen-menu (mapcar (lambda (screen) (list (string-to-char (number-to-string screen)) 'menu-item (format "%d%s %s" screen (elscreen-status-label screen) (elscreen-truncate-screen-name (get-alist screen screen-to-name-alist) 25)) 'elscreen-jump :keys (format "%s %d" (key-description elscreen-prefix-key) screen))) screen-list)) (setq elscreen-menu (nconc elscreen-menu elscreen-e21-menu-bar-command-entries)) (setq elscreen-menu (cons 'keymap (cons "Select Screen" elscreen-menu))) (define-key (current-global-map) [menu-bar elscreen] (cons (copy-sequence "ElScreen") elscreen-menu))))) (add-hook 'elscreen-screen-update-hook 'elscreen-e21-menu-bar-update) ;; Tab (defvar elscreen-e21-tab-format nil) (make-variable-buffer-local 'elscreen-e21-tab-format) (defsubst elscreen-e21-tab-create-keymap (&rest definitions) (let ((keymap (make-sparse-keymap)) (key-function-pairs (eval-when-compile (mapcar (lambda (key) (cons key 'ignore)) (list 'mouse-1 'mouse-2 'mouse-3 'down-mouse-1 'down-mouse-2 'down-mouse-3 'drag-mouse-1 'drag-mouse-2 'drag-mouse-3))))) (while definitions (set-alist 'key-function-pairs (car definitions) (cadr definitions)) (setq definitions (cddr definitions))) (mapc (lambda (key-function-pair) (let ((key (car key-function-pair)) (function (cdr key-function-pair))) (define-key keymap (vector 'header-line key) function))) key-function-pairs) keymap)) (defsubst elscreen-e21-tab-width () (if (numberp elscreen-display-tab) elscreen-display-tab (let* ((number-of-screens (elscreen-get-number-of-screens)) (available-width (- (frame-width) (if elscreen-tab-display-control 4 0))) (tab-width (round (- (/ available-width number-of-screens) (if elscreen-tab-display-kill-screen 5.5 1.5))))) (max (min tab-width 16) 1)))) (defun elscreen-e21-tab-escape-% (string) (if (string-match "%" string) (let ((retval "") start (end 0) substring) (while (setq start end) (setq end (next-property-change start string)) (setq substring (replace-regexp-in-string "%" "%%" (substring string start end))) (set-text-properties 0 (length substring) (text-properties-at start string) substring) (setq retval (concat retval substring))) retval) string)) (defun elscreen-e21-tab-update (&optional force) (when (and (not (window-minibuffer-p)) (or (elscreen-screen-modified-p 'elscreen-tab-update) force)) (walk-windows (lambda (window) (with-current-buffer (window-buffer window) (when (and (boundp 'elscreen-e21-tab-format) (equal header-line-format elscreen-e21-tab-format) (or (not (eq (window-buffer window) (window-buffer (frame-first-window)))) (not elscreen-display-tab))) (kill-local-variable 'elscreen-e21-tab-format) (setq header-line-format nil)))) 'other 'other) (when elscreen-display-tab (let ((screen-list (sort (elscreen-get-screen-list) '<)) (screen-to-name-alist (elscreen-get-screen-to-name-alist)) (current-screen (elscreen-get-current-screen)) (half-space (eval-when-compile (propertize " " 'display '(space :width 0.5)))) (tab-separator (eval-when-compile (propertize " " 'face 'elscreen-tab-background-face 'display '(space :width 0.5)))) (control-tab (eval-when-compile (propertize "<->" 'face 'elscreen-tab-control-face 'local-map (elscreen-e21-tab-create-keymap 'mouse-1 'elscreen-previous 'mouse-2 'elscreen-create 'mouse-3 'elscreen-next) 'help-echo "mouse-1: previous screen, mouse-2: create new screen, mouse-3: next screen")))) (with-current-buffer (window-buffer (frame-first-window)) (kill-local-variable 'elscreen-e21-tab-format) (when elscreen-tab-display-control (setq elscreen-e21-tab-format (nconc elscreen-e21-tab-format (list control-tab tab-separator)))) (mapcar (lambda (screen) (let ((kill-screen (propertize "[X]" 'local-map (elscreen-e21-tab-create-keymap 'mouse-1 `(lambda (e) (interactive "e") (elscreen-kill ,screen)) 'M-mouse-1 `(lambda (e) (interactive "e") (elscreen-kill-screen-and-buffers ,screen))) 'help-echo (format "mouse-1: kill screen %d, M-mouse-1: kill screen %d and buffers on it" screen screen)))) (setq elscreen-e21-tab-format (nconc elscreen-e21-tab-format (list (propertize (concat (when (or (eq elscreen-tab-display-kill-screen 'left) (eq elscreen-tab-display-kill-screen t)) kill-screen) half-space (propertize (format "%d%s%s%s" screen (elscreen-status-label screen) half-space (elscreen-e21-tab-escape-% (elscreen-truncate-screen-name (get-alist screen screen-to-name-alist) (elscreen-e21-tab-width) t))) 'help-echo (get-alist screen screen-to-name-alist) 'local-map (elscreen-e21-tab-create-keymap 'mouse-1 `(lambda (e) (interactive "e") (elscreen-goto ,screen)))) (when (eq elscreen-tab-display-kill-screen 'right) (concat half-space kill-screen))) 'face (if (eq current-screen screen) 'elscreen-tab-current-screen-face 'elscreen-tab-other-screen-face)) tab-separator))))) screen-list) (setq elscreen-e21-tab-format (nconc elscreen-e21-tab-format (list (propertize (make-string (window-width) ?\ ) 'face 'elscreen-tab-background-face 'local-map (elscreen-e21-tab-create-keymap))))) (setq header-line-format elscreen-e21-tab-format)))))) (add-hook 'elscreen-screen-update-hook 'elscreen-e21-tab-update)) ;; XEmacs (static-when elscreen-on-xemacs ;; Mode Line (defvar elscreen-xmas-mode-line-string "[0]") (defun elscreen-xmas-mode-line-update () (when (elscreen-screen-modified-p 'elscreen-xmas-mode-line-update) (setq elscreen-xmas-mode-line-string (format "[%d]" (elscreen-get-current-screen))) (force-mode-line-update))) (let ((point (memq 'global-mode-string mode-line-format)) (elscreen-mode-line-elm '(elscreen-display-screen-number (" " elscreen-xmas-mode-line-string)))) (if (null (member elscreen-mode-line-elm mode-line-format)) (setcdr point (cons elscreen-mode-line-elm (cdr point))))) (add-hook 'elscreen-screen-update-hook 'elscreen-xmas-mode-line-update) ;; Menu (defvar elscreen-xmas-menu-bar-command-entries '("%_ElScreen" :filter elscreen-xmas-menu-bar-filter "----" ["%_Create Screen" elscreen-create] ["%_Clone Screen" elscreen-clone] ["%_Kill Screen" elscreen-kill] ["%_Kill Screen and Buffers" elscreen-kill-screen-and-buffers] ["%_Kill Other Screens" elscreen-kill-others] ["%_Next Screen" elscreen-next] ["%_Previous Screen" elscreen-previous] ["%_Toggle Screen" elscreen-toggle] "----" ["%_Display Screen Number" elscreen-toggle-display-screen-number :style toggle :selected elscreen-display-screen-number] ["%_Display Tab" elscreen-toggle-display-tab :style toggle :selected elscreen-display-tab])) (defconst elscreen-xmas-menubar (copy-sequence default-menubar)) (let ((menubar elscreen-xmas-menubar)) (catch 'buffers-menu-search (while (car menubar) (when (equal (car (car menubar)) "%_Buffers") (throw 'buffers-menu-search menubar)) (setq menubar (cdr menubar)))) (setcdr menubar (cons elscreen-xmas-menu-bar-command-entries (cdr menubar)))) (set-menubar elscreen-xmas-menubar) (set-menubar-dirty-flag) (defun elscreen-xmas-menu-bar-filter (menu) (let ((screen-list (sort (elscreen-get-screen-list) '<)) (screen-to-name-alist (elscreen-get-screen-to-name-alist)) (elscreen-menu nil)) (setq elscreen-menu (mapcar (lambda (screen) (vector (format "%d%s %s" screen (elscreen-status-label screen) (elscreen-truncate-screen-name (get-alist screen screen-to-name-alist) 25)) `(elscreen-goto ,screen) :active t :keys (format "%s %d" (key-description elscreen-prefix-key) screen))) screen-list)) (append elscreen-menu menu))) ;; Tab (defsubst elscreen-xmas-tab-width () (if (numberp elscreen-display-tab) elscreen-display-tab 16)) (defvar elscreen-xmas-tab-glyph (make-glyph)) (let* ((gutter-string (copy-sequence "\n")) (gutter-elscreen-tab-extent (make-extent 0 1 gutter-string))) (set-extent-begin-glyph gutter-elscreen-tab-extent elscreen-xmas-tab-glyph) (mapcar (lambda (console-type) (when (valid-image-instantiator-format-p 'tab-control console-type) (set-specifier top-gutter-border-width 0 'global console-type) (set-gutter-element top-gutter 'elscreen-tab gutter-string 'global console-type))) (console-type-list))) (defun elscreen-xmas-tab-update (&optional force) (if (or (not elscreen-display-tab) (window-dedicated-p (selected-window))) (set-gutter-element-visible-p default-gutter-visible-p 'elscreen-tab nil) (when (and (not (window-minibuffer-p)) (or (elscreen-screen-modified-p 'elscreen-tab-update) force)) (set-gutter-element-visible-p default-gutter-visible-p 'elscreen-tab t) (when (valid-image-instantiator-format-p 'tab-control) (let* ((screen-list (sort (elscreen-get-screen-list) '<)) (screen-to-name-alist (elscreen-get-screen-to-name-alist)) (current-screen (elscreen-get-current-screen)) (tab-items (mapcar (lambda (screen) (vector (format "%d%s %s" screen (elscreen-status-label screen) (elscreen-truncate-screen-name (get-alist screen screen-to-name-alist) (elscreen-xmas-tab-width) t)) `(elscreen-goto ,screen) :selected (eq screen current-screen))) screen-list))) (set-glyph-image elscreen-xmas-tab-glyph (vector 'tab-control :descriptor "ElScreen" :face 'default :orientation 'top :pixel-width '(gutter-pixel-width) :items tab-items) (selected-frame))) (set-gutter-dirty-p 'top))))) (add-hook 'elscreen-screen-update-hook 'elscreen-xmas-tab-update)) ;;; Command-line processing at startup time (defun elscreen-command-line-funcall (switch-string) (let ((argval (intern (car command-line-args-left))) screen elscreen-window-configuration) (setq command-line-args-left (cdr command-line-args-left)) (save-window-excursion (elscreen-apply-window-configuration (elscreen-default-window-configuration)) (if (commandp argval) (command-execute argval) (funcall argval)) (setq elscreen-window-configuration (elscreen-current-window-configuration))) (setq file-count (1+ file-count)) (cond ((= file-count 1) (elscreen-apply-window-configuration elscreen-window-configuration)) ((setq screen (elscreen-create-internal 'noerror)) (elscreen-set-window-configuration screen elscreen-window-configuration))))) (defun elscreen-command-line-find-file (file file-count &optional line column) (let ((line (or line 0)) (column (or column 0))) (cond ((= file-count 1) (find-file file)) ((> file-count 10) (find-file-noselect file)) (t (elscreen-find-screen-by-buffer (find-file-noselect file) 'create))) (or (zerop line) (goto-line line)) (unless (< column 1) (move-to-column (1- column))))) (when elscreen-startup-command-line-processing (setq command-switch-alist (append command-switch-alist '(("-elscreen-funcall" . elscreen-command-line-funcall) ("-e" . elscreen-command-line-funcall)))) (static-when elscreen-on-emacs (defun elscreen-e21-command-line () (when (string-match "\\`-" argi) (error "Unknown option `%s'" argi)) (setq file-count (1+ file-count)) (setq inhibit-startup-buffer-menu t) (let* ((file (expand-file-name (command-line-normalize-file-name orig-argi) dir))) (elscreen-command-line-find-file file file-count line column)) (setq line 0) (setq column 0) t) (add-hook 'after-init-hook (lambda () (add-to-list 'command-line-functions 'elscreen-e21-command-line t)))) (static-when elscreen-on-xemacs (defadvice command-line-1 (around elscreen-xmas-command-line-1 activate) (cond ((null command-line-args-left) ad-do-it) (t (let ((dir command-line-default-directory) (file-count 0) (line nil) (end-of-options nil) file-p arg tem) (while command-line-args-left (setq arg (pop command-line-args-left)) (cond (end-of-options (setq file-p t)) ((setq tem (when (eq (aref arg 0) ?-) (or (assoc arg command-switch-alist) (assoc (substring arg 1) command-switch-alist)))) (funcall (cdr tem) arg)) ((string-match "\\`\\+[0-9]+\\'" arg) (setq line (string-to-int arg))) ((or (string= arg "-") (string= arg "--")) (setq end-of-options t)) (t (setq file-p t))) (when file-p (setq file-p nil) (incf file-count) (elscreen-command-line-find-file (expand-file-name arg dir) file-count line) (setq line nil))))))))) ;;; Unsupported Functions... (defun elscreen-link () (interactive) (cond ((null (one-window-p)) (elscreen-message "current screen must not have two or more window!")) ((or (null (elscreen-get-previous-screen)) (elscreen-one-screen-p)) (elscreen-message "must specify previous screen!")) ((and (elscreen-goto (elscreen-get-previous-screen)) (null (one-window-p))) (elscreen-goto (elscreen-get-previous-screen)) (elscreen-message "previous screen must not have two or more window!")) (t (let ((elscreen-link-buffer (current-buffer))) (elscreen-kill) (switch-to-buffer-other-window elscreen-link-buffer))))) (defun elscreen-split () (interactive) (if (and (null (one-window-p)) (< (elscreen-get-number-of-screens) 10)) (let ((elscreen-split-buffer (current-buffer))) (delete-window) (elscreen-create) (switch-to-buffer elscreen-split-buffer) (elscreen-goto (elscreen-get-previous-screen))) (elscreen-message "cannot split screen!"))) ;;; Start ElScreen! (defun elscreen-start () (mapcar (lambda (frame) (elscreen-make-frame-confs frame 'keep)) (frame-list)) (let ((prefix-key elscreen-prefix-key) (elscreen-prefix-key nil)) (elscreen-set-prefix-key prefix-key))) (elscreen-start) elscreen-1.4.6/README010064400007650000000000000135171072131615500132110ustar naotowheelElScreen 1.4.6 README file This is the distribution of ElScreen 1.4.6, released December 2007. It is an Emacs utility with which you can have multiple screens (window-configuration) on your GNU Emacs as well as GNU screen on terminal. If you use emacs-lisp applications which have many windows (like Gnus, irchat, Wanderlust, Mew...), ElScreen makes it easy to switch to a different screen, with its configuration unchanged. You can also create and kill screen, jump to them, rename the screen, and so on. This version is developed on (Carbon) Emacs 22.1.50, with APEL 10.7. Files ----- This package should contain the following files: elscreen.el ElScreen version 1.4.6 main file README Introduction to ElScreen 1.4.6 (this file) ChangeLog ElScreen ChangeLog file Installation ------------ To use ElScreen, APEL is required. You will find it at ftp://ftp.m17n.org/pub/mule/apel/ Then, simply install elscreen.el file in this directory to your load-path, and put following line into your .emacs: (load "elscreen" "ElScreen" t) Usage ----- You may use following sequences on ElScreen: C-z c C-z C-c Create a new screen and switch to it. C-z C Create a new screen with the window-configuration of the current screen. C-z k C-z C-k Kill current screen. C-z M-k Kill current screen and buffers. C-z K Kill other screens. C-z n C-z C-n Switch to the "next" screen in a cyclic order. C-z p C-z C-p Switch to the "previous" screen in a cyclic order. C-z a C-z C-a Toggle to the screen selected previously. C-z ' Prompt for a screen number to switch to. C-z " Present a list of all screens for selection. C-z 0 : Jump to the screen number 0-9. C-z 9 C-z C-s Swap current screen with previous one. C-z w C-z C-w Show a list of screen. C-z A Allow the user to enter a name for the current screen. C-z m C-z C-m Repeat the last message displayed in the mini-buffer. C-z t C-z C-t Show system information. C-z b Switch to the screen in which specified buffer is displayed. C-z C-f Create new screen and open file. C-z C-r Create new screen and open file but don't allow changes. C-z d Create new screen and run dired. C-z M-x Read function name, then call it with new screen. C-z i Show/hide the screen number in the mode line. C-z T Show/hide the tab on the top of each frame. C-z v Display ElScreen version. C-z ? Show key bindings of ElScreen and Add-On softwares. Setup ----- You can set the following variables to configure ElScreen. These can be set in .emacs file directly or "Options" in your menu bar. elscreen-prefix-key ElScreen prefix-key. The default value is `\C-z'. elscreen-buffer-to-nickname-alist The pairs of buffer-name and corresponding screen nickname or function that returns nickname, which are listed by 'elscreen-display-screen-name-list' only when major-mode cannot determine its screen nickname. The default value is: '(("^dired-mode$" . (lambda () (format "Dired(%s)" dired-directory))) ("^Info-mode$" . (lambda () (format "Info(%s)" (file-name-nondirectory Info-current-file)))) ("^mew-draft-mode$" . (lambda () (format "Mew(%s)" (buffer-name (current-buffer))))) ("^mew-" . "Mew") ("^irchat-" . "IRChat") ("^liece-" . "Liece") ("^lookup-" . "Lookup")) elscreen-mode-to-nickname-alist The pairs of major-mode and corresponding screen nickname or function that returns nickname, which are listed by 'elscreen-display-screen-name-list'. The default value is: '(("[Ss]hell" . "shell") ("compilation" . "compile") ("-telnet" . "telnet") ("dict" . "OnlineDict") ("*WL:Message*" . "Wanderlust")) elscreen-startup-command-line-processing If non nil, ElScreen processes command line arguments of Emacsen when starting up, and opens files with new screens if needed. The default value is `t'. elscreen-display-screen-number If non nil, show the number of the current screen in mode line. The default value is `t'. elscreen-display-tab Specify how the tabs at the top of frame should be displayed. t means to display tabs whose width should be calculated automatically. A value of integer means to display tabs with fixed width of this value. nil means don't display tabs. The default value is `t'. elscreen-tab-display-control (only for GNU Emacs 21) If non nil, display the tab (labeled with [<->]) to switch to next/previous screen or create new screen at the most left side of the tab line. The default value is `t'. elscreen-tab-display-kill-screen (only for GNU Emacs 21) Location of the icon ([X]) to kill corresponding screen on each tab. Possible values are 'left, 'right and nil (to hide icons). The default value is 'left. Where Can I Get ElScreen? ------------------------- ElScreen is available from the following anonymous ftp site. ftp://ftp.morishima.net/pub/morishima.net/naoto/ElScreen/ Bugs ---- Under multiple-frame environment, screen numbers displayed on mode line of each frame is changed at the same time. On GNU Emacs 21, tabs also has this restriction. Bug Reports ----------- ElScreen is maintained by Naoto Morishima. Please mail bug reports and any comments to: naoto@morishima.net Acknowledgment -------------- Many people contributed to ElScreen by reporting problems or suggesting various improvements. Here is a list of these people. Tohru Sugayama Yoshinobu Takenaga Masatoshi Takamura Jin Kashimura Takahiko Sakai Norio Suzuki Yoshitatsu Takeshita Yoichi Nakayama sen_ml@eccosys.com Dan Debertin Yoshinori Koseki Hideyuki Shirai Masahiro Ishiyama Alexy Khrabrov