hide-mode-line.el 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. ;;; hide-mode-line.el --- Hides the mode line when there is only one frame and
  2. ;;; one buffer.
  3. ;;
  4. ;; Filename: hide-mode-line.el
  5. ;; Description: Hides the mode line when there is only one frame and one
  6. ;; buffer.
  7. ;; Author: Darren Embry
  8. ;; Copyright (c) 2008, 2011 Darren Embry
  9. ;; URL: http://webonastick.com/emacs-lisp/hide-mode-line.el
  10. ;; Keywords: mode line, writeroom
  11. ;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
  12. ;;
  13. ;; Features that might be required by this library:
  14. ;;
  15. ;; None
  16. ;;
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18. ;;
  19. ;; This program is free software; you can redistribute it and/or modify it
  20. ;; under the terms of the GNU General Public License as published by the Free
  21. ;; Software Foundation; either version 2, or (at your option) any later
  22. ;; version.
  23. ;;
  24. ;; This program is distributed in the hope that it will be useful, but WITHOUT
  25. ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  26. ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  27. ;; more details.
  28. ;;
  29. ;; You should have received a copy of the GNU General Public License along
  30. ;; with this program; see the file COPYING. If not, write to the Free
  31. ;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  32. ;; 02110-1301, USA.
  33. ;;
  34. ;; GPL 2 is available here:
  35. ;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  36. ;;
  37. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  38. ;;
  39. ;;; Commentary:
  40. ;;
  41. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  42. ;;
  43. ;; Basically, automatically hides the mode-line if all of the following
  44. ;; are true:
  45. ;; - there is only one frame.
  46. ;; - there is only one window displayed in that frame.
  47. ;; - there is no minibuffer.
  48. ;; - the hide-mode-line variable is set.
  49. ;; and automatically shows the mode-line when any of the above isn't true.
  50. ;;
  51. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  52. ;;
  53. ;; HOW TO USE
  54. ;;
  55. ;; Just put this file in your Emacs library directory and add this line to
  56. ;; your ~/.emacs:
  57. ;;
  58. ;; (autoload 'hide-mode-line "hide-mode-line" nil t)
  59. ;;
  60. ;; and use M-x hide-mode-line to toggle. Setting the hide-mode-line variable
  61. ;; won't automatically update the buffers' mode-line visibilities.
  62. ;;
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64. ;;
  65. ;; MYSTERY BUG: every once in a while a few lines of text will be hidden
  66. ;; for some reason until you do a redraw-display. See if you can
  67. ;; reproduce this in a reliable fashion!
  68. ;;
  69. ;; MYSTERY BUG: not specific to this module, but... load linum, run M-x
  70. ;; linum-mode, then (setq mode-line-format nil) this triggers display
  71. ;; problems more reproducibly: sometimes the last line in the buffer
  72. ;; doesn't have the line number show up; and sometimes the cursor line
  73. ;; or the one after it doesn't have the line number show up. May be
  74. ;; related to above bug.
  75. ;;
  76. ;; CAVEAT: this code does not instruct your window system to make the
  77. ;; window full-screen.
  78. ;;
  79. ;; TODO: briefly show modeline for (example) 2 seconds when the following
  80. ;; happens:
  81. ;; - hide-mode-line is about to be activated
  82. ;; - you switch to another buffer
  83. ;;
  84. ;; TODO: Emacs 21 does not implement window-tree.
  85. ;;
  86. ;; BUG: if the hide-mode-line-window-configuration-change-hook function
  87. ;; displays a (message "moo") before it does its work, the screen is blanked
  88. ;; when you resize the window until you hit C-l.
  89. ;;
  90. ;; BUG: if a frame is closed and there is only one frame remaining, and
  91. ;; there is only one buffer in that window, mode lines are not hidden.
  92. ;;
  93. ;; SEE ALSO:
  94. ;; http://www.emacswiki.org/cgi-bin/wiki/LineNumbers
  95. ;; http://www.emacswiki.org/cgi-bin/wiki/WriteRoom
  96. ;;
  97. ;;=============================================================================
  98. ;;; History:
  99. ;;
  100. ;; 2008-01-31 r3090 initial version
  101. ;; 2008-02-01 r3097 explicitly defint default for
  102. ;; hide-mode-line-saved-mode-line-format
  103. ;; 2008-02-01 r3100 implement hide-mode-line-unaffected-by-minibuffer
  104. ;; 2008-02-01 r3101 more robust handling of case where mode-line-format is
  105. ;; nil before this code runs
  106. ;; 2008-02-01 r3106 disable in emacs21: window-tree function not available
  107. ;; 2011-03-08 r5835 fix emacsw32 bug
  108. ;;; Code:
  109. (defvar hide-mode-line-saved-mode-line-format nil)
  110. (make-variable-buffer-local 'hide-mode-line-saved-mode-line-format)
  111. ; TODO: add a hook of some kind when setting mode-line-format.
  112. (defvar hide-mode-line nil)
  113. ; TODO: add a hook to run hide-mode-line-update when setting hide-mode-line.
  114. ; [or just use M-x hide-mode-line for now]
  115. (defcustom hide-mode-line-unaffected-by-minibuffer nil
  116. "If non-nil, a minibuffer by itself does not un-hide the modeline."
  117. :group 'hide-mode-line
  118. :type 'boolean)
  119. (defun there-is-only-one-frame ()
  120. "Return non-nil if there is only one frame, nil otherwise."
  121. (let ((frames (frames-on-display-list)))
  122. (if (= (length frames) 1)
  123. (car frames)
  124. nil)))
  125. (defun there-is-only-one-window-in (frame)
  126. "Return non-nil if there is only one window in the specified FRAME."
  127. (let ((root (car (window-tree frame)))) ;FIXME: does not work with emacs21
  128. (not (listp root))))
  129. (defun there-is-only-one-frame-and-one-window ()
  130. "Return non-nil if there is only one frame and one window."
  131. (let ((the-only-frame (there-is-only-one-frame)))
  132. (and the-only-frame
  133. (or hide-mode-line-unaffected-by-minibuffer
  134. (= (minibuffer-depth) 0))
  135. (there-is-only-one-window-in the-only-frame))))
  136. (defun hide-mode-line-in (buffer)
  137. "Hide the specified BUFFER's mode line.
  138. Saves the buffer's previous `mode-line-format' value if it's not
  139. already hidden."
  140. (with-current-buffer buffer
  141. (if (and (not hide-mode-line-saved-mode-line-format)
  142. ;; minibuffers don't have modelines :p
  143. (not (minibufferp buffer)))
  144. (progn (setq hide-mode-line-saved-mode-line-format
  145. (list mode-line-format))
  146. (setq mode-line-format nil)
  147. ;; bug workaround
  148. (redraw-modeline)))))
  149. (defun show-mode-line-in (buffer)
  150. "If the specified BUFFER's mode line is hidden, un-hides it.
  151. Restores the buffer's `mode-line-format' from what was saved when
  152. hide-mode-line-in was called."
  153. (with-current-buffer buffer
  154. (if (and hide-mode-line-saved-mode-line-format
  155. ;; minibuffers don't have modelines :p
  156. (not (minibufferp buffer)))
  157. (progn (setq mode-line-format
  158. (car hide-mode-line-saved-mode-line-format))
  159. (setq hide-mode-line-saved-mode-line-format nil)))))
  160. (defun hide-mode-lines ()
  161. "Hide all buffers' mode lines using hide-mode-line-in."
  162. (mapcar 'hide-mode-line-in (buffer-list)))
  163. (defun show-mode-lines ()
  164. "Show all buffers' mode lines using show-mode-line-in."
  165. (mapcar 'show-mode-line-in (buffer-list))
  166. (if (equal window-system 'w32)
  167. ;; bug workaround
  168. (redraw-display)))
  169. (defun hide-mode-line-update ()
  170. "Update the state of all buffers' mode lines.
  171. This uses hide-mode-lines or show-mode-lines."
  172. (if hide-mode-line
  173. (if (there-is-only-one-frame-and-one-window)
  174. (hide-mode-lines)
  175. (show-mode-lines))
  176. (show-mode-lines)))
  177. (defun hide-mode-line-minibuffer-setup-hook ()
  178. "Internal function."
  179. (hide-mode-line-update))
  180. (defun hide-mode-line-minibuffer-exit-hook ()
  181. "Internal function."
  182. (hide-mode-line-update))
  183. (defun hide-mode-line-make-frame-function (new-frame)
  184. "Internal function."
  185. (hide-mode-line-update))
  186. (defun hide-mode-line-delete-frame-function (dead-frame-walking)
  187. "Internal function."
  188. (hide-mode-line-update))
  189. (defun hide-mode-line-window-configuration-change-hook ()
  190. "Internal function."
  191. (hide-mode-line-update))
  192. (defun hide-mode-line-add-hooks ()
  193. "Internal function."
  194. (interactive)
  195. (add-hook 'minibuffer-setup-hook
  196. 'hide-mode-line-minibuffer-setup-hook)
  197. (add-hook 'minibuffer-exit-hook
  198. 'hide-mode-line-minibuffer-exit-hook)
  199. (add-hook 'after-make-frame-functions
  200. 'hide-mode-line-make-frame-function)
  201. (add-hook 'delete-frame-functions
  202. 'hide-mode-line-delete-frame-function)
  203. (add-hook 'window-configuration-change-hook
  204. 'hide-mode-line-window-configuration-change-hook))
  205. (defun hide-mode-line-remove-hooks ()
  206. "Internal function."
  207. (interactive)
  208. (remove-hook 'minibuffer-setup-hook
  209. 'hide-mode-line-minibuffer-setup-hook)
  210. (remove-hook 'minibuffer-exit-hook
  211. 'hide-mode-line-minibuffer-exit-hook)
  212. (remove-hook 'after-make-frame-functions
  213. 'hide-mode-line-make-frame-function)
  214. (remove-hook 'delete-frame-functions
  215. 'hide-mode-line-delete-frame-function)
  216. (remove-hook 'window-configuration-change-hook
  217. 'hide-mode-line-window-configuration-change-hook))
  218. (defun hide-mode-line ()
  219. "Toggle the hide-mode-line functionality."
  220. (interactive)
  221. (if (functionp 'window-tree)
  222. (progn
  223. (setq hide-mode-line (not hide-mode-line))
  224. (hide-mode-line-update))
  225. (error (concat "Your Emacs does not provide the window-tree function. "
  226. "Please upgrade to GNU Emacs 22 "
  227. "or to some other version of Emacs that provides it."))))
  228. (hide-mode-line-add-hooks)
  229. (provide 'hide-mode-line)
  230. ;;; hide-mode-line.el ends here