home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / gnu / epoch / misc / 1135 < prev    next >
Encoding:
Text File  |  1992-11-18  |  12.1 KB  |  367 lines

  1. Path: sparky!uunet!charon.amdahl.com!pacbell.com!sgiblab!sgigate!sgi!fido!shankar
  2. From: shankar@sgi.com (Shankar Unni)
  3. Newsgroups: gnu.epoch.misc
  4. Subject: Screen-per-buffer for Epoch
  5. Date: 19 Nov 1992 00:03:42 GMT
  6. Organization: Silicon Graphics, Inc.
  7. Lines: 355
  8. Message-ID: <1eelkuINNcvt@fido.asd.sgi.com>
  9. NNTP-Posting-Host: boris.wpd.sgi.com
  10. X-Newsreader: Tin 1.1 PL5
  11.  
  12. I've seen enough requests for this, so I'm posting the current version
  13. of my screen-per-buffer package.
  14.  
  15. What this package does is to force each new buffer to be put in its
  16. own screen. If you try to find an existing buffer, it will simply
  17. bring up its corresponding screen.
  18.  
  19. The package can be safely pre-loaded into epoch. Or else, you can load
  20. this up in your .emacs.
  21.  
  22. Its behavior is controlled by two variables which you should set in
  23. your .emacs:
  24.  
  25.   screen-per-buffer:  If non-nil, it will enforce the
  26.          one-screen-per-buffer behavior (this is 'nil by default).
  27.  
  28.   buffer-no-new-screen:  This is a list of buffers for which no new
  29.          screen is to be created. By default, it contains two buffers:
  30.          *Completions* and *mh_temp*.  The default is generally good
  31.          enough, though you can change this to your taste.
  32.  
  33. Either of these can be changed at any time by the user.
  34.  
  35. ================ cut here ================ cut here ================
  36. ; -*-Emacs-Lisp-*-
  37. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  38. ;
  39. ; File:         scrperbuf.el
  40. ; RCS:          $Id: scrperbuf.el,v 1.6 92/10/07 15:25:54 shankar Exp $
  41. ; Description:  Code to make Epoch create an X window per Epoch buffer (1-to-1)
  42. ; Author:       Shankar Unni, SGI.
  43. ; Created:      Fri Jun 26 11:00:00 1992
  44. ; Modified:     Wed Oct  7 15:24:54 1992 (Shankar Unni) shankar@sgi.com
  45. ; Language:     Emacs-Lisp
  46. ; Package:      N/A
  47. ; Status:       Experimental (Do Not Distribute)
  48. ;
  49. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  50.  
  51. ; This piece of E-lisp allows Epoch users to associate one epoch screen (==
  52. ; X window) per Epoch buffer. It does this by overriding the definitions
  53. ; of "find-buffer" and "find-buffer-other-window", making each put up
  54. ; a new X window for each new buffer, or, if the buffer already exists,
  55. ; selecting its existing X window and raising it.
  56.  
  57. ; It also overrides "kill-buffer", so that the X window for a buffer is
  58. ; deleted when the buffer is killed, and "delete-window", so that it merely
  59. ; unmaps (from the window manager, but preserves) the screen which contains
  60. ; the buffer.
  61.  
  62. ; This is *NOT* a major-mode, since it is not on a per-buffer basis.
  63.  
  64. ; It has a default list of buffers for which a new X window is never created.
  65. ; Keep the list as is. At the very least, " *Completions*" must be there,
  66. ; or the completion mechanism will cause a new window to be popped up,
  67. ; screwing up the focus..
  68.  
  69. ; $Log:    scrperbuf.el,v $
  70. ; Revision 1.6  92/10/07  15:25:54  shankar
  71. ; Changed calls of raise-screen to mapraised-screen. This should fix the
  72. ; problem with displaying file-completions when all buffers are unmapped.
  73. ; Also added a new function to make find-alternate-file reuse current screen.
  74. ; Revision 1.5  92/09/24  10:17:03  shankar
  75. ; Oops. Fixed the tests in the switch-to-* defuns - I had the test
  76. ; reversed..  Also, fixed spb-delete-window to just delete the window
  77. ; if more than one window are on the screen, else just delete the screen.
  78. ; Revision 1.4  92/09/22  14:18:15  shankar
  79. ; More refinements to modification check in spb-kill-buffer.
  80. ; Also, put a copy of a modified find-buffer-other-screen here, rather
  81. ; than modify the copy in epoch-lisp/epoch.el. This modification is to
  82. ; prevent two copies of the same buffer from popping up.
  83. ; Revision 1.3  92/08/19  18:41:15  shankar
  84. ; Don't blow away screen if kill-buffer is aborted.
  85. ; Revision 1.2  92/07/13  15:18:45  shankar
  86. ; Fixes for enabling pre-loaded scrperbuf.el (toggled by user setting
  87. ; screen-per-buffer to non-nil).
  88. ; Revision 1.1  92/07/13  14:24:38  shankar
  89. ; Initial revision
  90. ;
  91.  
  92. (defvar screen-per-buffer 'nil
  93.     "If non-nil, a unique Epoch screen should be associated with each Epoch
  94. buffer, except the ones mentioned in \\[buffer-no-new-screen]")
  95.  
  96. (defvar buffer-no-new-screen '(" *Completions*" " *mh_temp*")
  97.     "The list of buffers for which a separate screen is not created")
  98.  
  99.  
  100. ;
  101. ; SPB-SWITCH-TO-BUFFER is a replacement for switch-to-buffer, that creates
  102. ; a new X window for a buffer if it is not already associated with one. 
  103. ; However, if the name of the buffer is in buf-no-new-screen, a new X window
  104. ; is not created.
  105. ;
  106. (defun spb-switch-to-buffer (buffername)
  107.   "Switch to buffer BUFFERNAME in another screen, unless it is in
  108. the list BUFFER-NO-NEW-SCREEN"
  109.   (interactive "BSwitch to buffer in other screen: ")
  110.   (setq bufnm (spb-buffer-name buffername))
  111.   (cond
  112.      ((or (not screen-per-buffer) (strmember bufnm buffer-no-new-screen))
  113.      (spb-real-switch-to-buffer buffername)
  114.      )
  115.      (t
  116.          (find-buffer-other-screen buffername)
  117.      )
  118.   )
  119.   (epoch::mapraised-screen (car (epoch::screens-of-buffer bufnm)))
  120.   buffername
  121. )
  122.  
  123. ;
  124. ; save the old value of "switch-to-buffer" in "spb-real-switch-to-buffer",
  125. ; and replace it with the definition above.
  126. ;
  127. (or (fboundp 'spb-real-switch-to-buffer)
  128.     (fset 'spb-real-switch-to-buffer (symbol-function 'switch-to-buffer)))
  129.  
  130. (fset 'switch-to-buffer 'spb-switch-to-buffer)
  131.  
  132.  
  133. ;
  134. ; SPB-SWITCH-TO-BUFFER-OTHER-WINDOW is a replacement for switch-to-buffer-
  135. ; other-window, that creates a new X window for a buffer if it is not 
  136. ; already associated with one. However, if the name of the buffer is in
  137. ; buf-no-new-screen, a new X window is not created.
  138. ;
  139. (defun spb-switch-to-buffer-other-window (buffername)
  140.   "Switch to buffer BUFFERNAME in another screen, unless it is in
  141. the list BUFFER-NO-NEW-SCREEN"
  142.   (interactive "BSwitch to buffer in other screen: ")
  143.   (setq bufnm (spb-buffer-name buffername))
  144.   (cond
  145.      ((or (not screen-per-buffer) (strmember bufnm buffer-no-new-screen))
  146.      (progn (spb-real-switch-to-buffer-other-window buffername) (other-window 1))
  147.      )
  148.      (t
  149.          (find-buffer-other-screen buffername)
  150.      )
  151.   )
  152.   (epoch::mapraised-screen (car (epoch::screens-of-buffer bufnm)))
  153.   buffername
  154. )
  155.  
  156. ;
  157. ; save the old value of "switch-to-buffer-other-window" in "spb-real-switch-
  158. ; to-buffer-other-window", and replace it with the definition above.
  159. ;
  160. (or (fboundp 'spb-real-switch-to-buffer-other-window)
  161.     (fset 'spb-real-switch-to-buffer-other-window (symbol-function 'switch-to-buffer-other-window)))
  162.  
  163. (fset 'switch-to-buffer-other-window 'spb-switch-to-buffer-other-window)
  164.  
  165. (setq temp-buffer-show-hook 'spb-switch-to-buffer-other-window)
  166.  
  167.  
  168. ;
  169. ; SPB-KILL-BUFFER is replacement for kill-buffer, which also removes all
  170. ; screens (X windows) associated with the buffer.
  171. ;
  172. (defun spb-kill-buffer (buffer)
  173.     "Kill buffer named BUFFER, and also remove all screens showing this
  174. buffer. If any of those screens are also showing other buffers, tough. In
  175. any case, their screens can be brought back by calling find-buffer"
  176.     (interactive "bKill buffer: ")
  177.     (set-buffer buffer)
  178.     (and (buffer-modified-p)
  179.      (not buffer-read-only)
  180.      (buffer-file-name)
  181.      (not (yes-or-no-p (format "Buffer %s modified; kill anyway? "
  182.                    (buffer-name))))
  183.      (error "Aborted"))
  184.  
  185.     ;; hack!! to prevent a second confirmation message if the
  186.     ;; buffer was really modified..
  187.     (set-buffer-modified-p nil)
  188.     ;;
  189.     (setq screenlist (epoch::screens-of-buffer buffer))
  190.     (spb-real-kill-buffer buffer)
  191.     (if (and screen-per-buffer screenlist)
  192.        (mapcar 'remove-screen screenlist)
  193.     )
  194. )
  195.  
  196. ;
  197. ; replace kill-buffer with the definition above, saving the old symbol value
  198. ; in spb-real-kill-buffer
  199. ;
  200. (or (fboundp 'spb-real-kill-buffer)
  201.     (fset 'spb-real-kill-buffer (symbol-function 'kill-buffer)))
  202.  
  203. (fset 'kill-buffer 'spb-kill-buffer)
  204.  
  205. ;
  206. ; SPB-DELETE-WINDOW is replacement for delete-window, which unmaps the
  207. ; screen associated with the window
  208. ;
  209. (defun spb-delete-window (&optional window)
  210.   "Delete WINDOW (default is current window), and optionally remove the
  211. screen associated with it"
  212.   ;; I only handle the current screen here. Sorry..
  213.   (interactive)
  214.   (setq screen (epoch::screen-of-window window))
  215.   (cond
  216.    ((one-window-p)
  217.     (if (and screen-per-buffer screen)
  218.     (remove-screen screen)
  219.       )
  220.    )
  221.    (t
  222.     (spb-real-delete-window window)
  223.    )
  224.   )
  225. )
  226.  
  227. ;
  228. ; replace delete-window with spb-delete-window, saving the old symbol value
  229. ; in spb-real-delete-window
  230. ;
  231. (or (fboundp 'spb-real-delete-window)
  232.     (fset 'spb-real-delete-window (symbol-function 'delete-window)))
  233.  
  234. (fset 'delete-window 'spb-delete-window)
  235.  
  236. ;
  237. ; variant of find-alternate-file that preserves the screen (but is
  238. ; smart enough to rename it after the file is loaded). This function
  239. ; should work even if screen-per-buffer is nil, since that is basically
  240. ; all that this function is doing (i.e. setting screen-per-buffer to nil
  241. ; temporarily while executing the real find-alternate-file).
  242. ;
  243. (defun spb-find-alternate-file(filename)
  244.   "Find file FILENAME, select its buffer, kill previous buffer.
  245. If the current buffer now contains an empty file that you just visited
  246. \(presumably by mistake), use this command to visit the file you really want.
  247.  
  248. This function sets screen-per-buffer to nil and calls the real
  249. find-alternate-file \(spb-real-find-alternate-file)"
  250.   (interactive "FFind alternate file: ")
  251.   (let ((screen-per-buffer nil))
  252.     (spb-real-find-alternate-file filename)
  253.     (let ((buf (window-buffer (epoch::selected-window (current-screen)))))
  254.       (epoch::title (concat (buffer-name buf) (sys-name)) (current-screen) )
  255.       (epoch::icon-name (epoch::title nil (current-screen)) (current-screen) )
  256.     )
  257.   )
  258. )
  259.  
  260.  
  261. (or (fboundp 'spb-real-find-alternate-file)
  262.     (fset 'spb-real-find-alternate-file (symbol-function 'find-alternate-file)))
  263. (fset 'find-alternate-file 'spb-find-alternate-file)
  264.  
  265. ;;; --------------------------------------------------------------------------
  266. ;
  267. ; replacement for the function with the same name in epoch-lisp/epoch.el:
  268. ;
  269. ;;; --------------------------------------------------------------------------
  270. (defun find-buffer-other-screen (buffer)
  271.   "Switch to BUFFER in other screen.  If buffer is already in another
  272. screen then select that, else make a new screen."
  273.   (interactive "BSwitch to buffer other screen: ")
  274.   (setq target-buffer (get-buffer buffer))
  275.   (when (not target-buffer)
  276.     (setq target-buffer (get-buffer-create buffer))
  277.     (save-excursion
  278.       (set-buffer target-buffer)
  279.       (setq allowed-screens nil)
  280.     )
  281.   )
  282.   (let
  283.     (
  284.       (scr
  285.     (car (epoch::screens-of-buffer target-buffer))
  286.       )
  287.       (xname (concat (buffer-name target-buffer) (sys-name)))
  288.     )
  289.     (when (null scr)
  290.       (setq scr
  291.     (create-screen
  292.       target-buffer
  293.       (list (cons 'title xname) (cons 'icon-name xname))
  294.     )
  295.       )
  296.     )
  297.     (if (screen-mapped-p scr)
  298.       (cursor-to-screen (select-screen scr))
  299.       (progn
  300.     (on-map-do scr 'cursor-to-screen)
  301.     (mapraised-screen (select-screen scr))
  302.       )
  303.     )
  304.     (select-window (get-buffer-window target-buffer))
  305.     target-buffer            ;return value
  306.   )
  307. )
  308.  
  309. ;
  310. ; utility function to canonicalize a buffer name or buffer reference to
  311. ; a string value.
  312. ;
  313. (defun spb-buffer-name (buffernm)
  314.    "Returns name of buffer if argument is a buffer, else returns arg."
  315.    (let (retval)
  316.    (cond
  317.       ((bufferp buffernm)
  318.           (setq retval (buffer-name buffernm))
  319.       )
  320.       (t
  321.           (setq retval buffernm)
  322.       )
  323.    )
  324.    retval
  325.    )
  326. )
  327.  
  328. ;; ---------------------------------------------------------------------------
  329.  
  330. ;
  331. ; string lookup in string list
  332. ;
  333. (defun strmember (elt list)
  334.    "Look for string ELT in list of string LIST, and return the sublist from
  335. that element to the end of LIST"
  336.    (let ((l1 list)
  337.          result)
  338.        (cond
  339.          ((listp list)
  340.             (while l1
  341.                 (if (string-equal elt (car l1))
  342.                     (progn  (setq result (cdr l1))
  343.                 (if (not result) (setq result '("*DUMMYRESULT*")))
  344.                 (setq l1 nil))  ;; break out of loop
  345.           (setq l1 (cdr l1))
  346.                 )
  347.             )
  348.          )
  349.          (t
  350.             (setq result nil)
  351.          )
  352.        )
  353.        result
  354.    )
  355. )
  356. ================ cut here ================ cut here ================
  357.  
  358. --
  359. Shankar Unni                E-Mail:    shankar@sgi.com
  360. Silicon Graphics Inc.            Phone:    +1-415-390-2072
  361.