253 lines
9.1 KiB
EmacsLisp
253 lines
9.1 KiB
EmacsLisp
|
;;; hide-mode-line.el --- Hides the mode line when there is only one frame and
|
||
|
;;; one buffer.
|
||
|
;;
|
||
|
;; Filename: hide-mode-line.el
|
||
|
;; Description: Hides the mode line when there is only one frame and one
|
||
|
;; buffer.
|
||
|
;; Author: Darren Embry
|
||
|
;; Copyright (c) 2008, 2011 Darren Embry
|
||
|
;; URL: http://webonastick.com/emacs-lisp/hide-mode-line.el
|
||
|
;; Keywords: mode line, writeroom
|
||
|
;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
|
||
|
;;
|
||
|
;; Features that might be required by this library:
|
||
|
;;
|
||
|
;; None
|
||
|
;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;
|
||
|
;; 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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||
|
;; 02110-1301, USA.
|
||
|
;;
|
||
|
;; GPL 2 is available here:
|
||
|
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||
|
;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;
|
||
|
;;; Commentary:
|
||
|
;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;
|
||
|
;; Basically, automatically hides the mode-line if all of the following
|
||
|
;; are true:
|
||
|
;; - there is only one frame.
|
||
|
;; - there is only one window displayed in that frame.
|
||
|
;; - there is no minibuffer.
|
||
|
;; - the hide-mode-line variable is set.
|
||
|
;; and automatically shows the mode-line when any of the above isn't true.
|
||
|
;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;
|
||
|
;; HOW TO USE
|
||
|
;;
|
||
|
;; Just put this file in your Emacs library directory and add this line to
|
||
|
;; your ~/.emacs:
|
||
|
;;
|
||
|
;; (autoload 'hide-mode-line "hide-mode-line" nil t)
|
||
|
;;
|
||
|
;; and use M-x hide-mode-line to toggle. Setting the hide-mode-line variable
|
||
|
;; won't automatically update the buffers' mode-line visibilities.
|
||
|
;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;
|
||
|
;; MYSTERY BUG: every once in a while a few lines of text will be hidden
|
||
|
;; for some reason until you do a redraw-display. See if you can
|
||
|
;; reproduce this in a reliable fashion!
|
||
|
;;
|
||
|
;; MYSTERY BUG: not specific to this module, but... load linum, run M-x
|
||
|
;; linum-mode, then (setq mode-line-format nil) this triggers display
|
||
|
;; problems more reproducibly: sometimes the last line in the buffer
|
||
|
;; doesn't have the line number show up; and sometimes the cursor line
|
||
|
;; or the one after it doesn't have the line number show up. May be
|
||
|
;; related to above bug.
|
||
|
;;
|
||
|
;; CAVEAT: this code does not instruct your window system to make the
|
||
|
;; window full-screen.
|
||
|
;;
|
||
|
;; TODO: briefly show modeline for (example) 2 seconds when the following
|
||
|
;; happens:
|
||
|
;; - hide-mode-line is about to be activated
|
||
|
;; - you switch to another buffer
|
||
|
;;
|
||
|
;; TODO: Emacs 21 does not implement window-tree.
|
||
|
;;
|
||
|
;; BUG: if the hide-mode-line-window-configuration-change-hook function
|
||
|
;; displays a (message "moo") before it does its work, the screen is blanked
|
||
|
;; when you resize the window until you hit C-l.
|
||
|
;;
|
||
|
;; BUG: if a frame is closed and there is only one frame remaining, and
|
||
|
;; there is only one buffer in that window, mode lines are not hidden.
|
||
|
;;
|
||
|
;; SEE ALSO:
|
||
|
;; http://www.emacswiki.org/cgi-bin/wiki/LineNumbers
|
||
|
;; http://www.emacswiki.org/cgi-bin/wiki/WriteRoom
|
||
|
;;
|
||
|
;;=============================================================================
|
||
|
|
||
|
;;; History:
|
||
|
;;
|
||
|
;; 2008-01-31 r3090 initial version
|
||
|
;; 2008-02-01 r3097 explicitly defint default for
|
||
|
;; hide-mode-line-saved-mode-line-format
|
||
|
;; 2008-02-01 r3100 implement hide-mode-line-unaffected-by-minibuffer
|
||
|
;; 2008-02-01 r3101 more robust handling of case where mode-line-format is
|
||
|
;; nil before this code runs
|
||
|
;; 2008-02-01 r3106 disable in emacs21: window-tree function not available
|
||
|
;; 2011-03-08 r5835 fix emacsw32 bug
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(defvar hide-mode-line-saved-mode-line-format nil)
|
||
|
(make-variable-buffer-local 'hide-mode-line-saved-mode-line-format)
|
||
|
; TODO: add a hook of some kind when setting mode-line-format.
|
||
|
|
||
|
(defvar hide-mode-line nil)
|
||
|
; TODO: add a hook to run hide-mode-line-update when setting hide-mode-line.
|
||
|
; [or just use M-x hide-mode-line for now]
|
||
|
|
||
|
(defcustom hide-mode-line-unaffected-by-minibuffer nil
|
||
|
"If non-nil, a minibuffer by itself does not un-hide the modeline."
|
||
|
:group 'hide-mode-line
|
||
|
:type 'boolean)
|
||
|
|
||
|
(defun there-is-only-one-frame ()
|
||
|
"Return non-nil if there is only one frame, nil otherwise."
|
||
|
(let ((frames (frames-on-display-list)))
|
||
|
(if (= (length frames) 1)
|
||
|
(car frames)
|
||
|
nil)))
|
||
|
(defun there-is-only-one-window-in (frame)
|
||
|
"Return non-nil if there is only one window in the specified FRAME."
|
||
|
(let ((root (car (window-tree frame)))) ;FIXME: does not work with emacs21
|
||
|
(not (listp root))))
|
||
|
(defun there-is-only-one-frame-and-one-window ()
|
||
|
"Return non-nil if there is only one frame and one window."
|
||
|
(let ((the-only-frame (there-is-only-one-frame)))
|
||
|
(and the-only-frame
|
||
|
(or hide-mode-line-unaffected-by-minibuffer
|
||
|
(= (minibuffer-depth) 0))
|
||
|
(there-is-only-one-window-in the-only-frame))))
|
||
|
|
||
|
(defun hide-mode-line-in (buffer)
|
||
|
"Hide the specified BUFFER's mode line.
|
||
|
|
||
|
Saves the buffer's previous `mode-line-format' value if it's not
|
||
|
already hidden."
|
||
|
(with-current-buffer buffer
|
||
|
(if (and (not hide-mode-line-saved-mode-line-format)
|
||
|
;; minibuffers don't have modelines :p
|
||
|
(not (minibufferp buffer)))
|
||
|
(progn (setq hide-mode-line-saved-mode-line-format
|
||
|
(list mode-line-format))
|
||
|
(setq mode-line-format nil)
|
||
|
;; bug workaround
|
||
|
(redraw-modeline)))))
|
||
|
(defun show-mode-line-in (buffer)
|
||
|
"If the specified BUFFER's mode line is hidden, un-hides it.
|
||
|
|
||
|
Restores the buffer's `mode-line-format' from what was saved when
|
||
|
hide-mode-line-in was called."
|
||
|
(with-current-buffer buffer
|
||
|
(if (and hide-mode-line-saved-mode-line-format
|
||
|
;; minibuffers don't have modelines :p
|
||
|
(not (minibufferp buffer)))
|
||
|
(progn (setq mode-line-format
|
||
|
(car hide-mode-line-saved-mode-line-format))
|
||
|
(setq hide-mode-line-saved-mode-line-format nil)))))
|
||
|
|
||
|
(defun hide-mode-lines ()
|
||
|
"Hide all buffers' mode lines using hide-mode-line-in."
|
||
|
(mapcar 'hide-mode-line-in (buffer-list)))
|
||
|
(defun show-mode-lines ()
|
||
|
"Show all buffers' mode lines using show-mode-line-in."
|
||
|
(mapcar 'show-mode-line-in (buffer-list))
|
||
|
(if (equal window-system 'w32)
|
||
|
;; bug workaround
|
||
|
(redraw-display)))
|
||
|
|
||
|
(defun hide-mode-line-update ()
|
||
|
"Update the state of all buffers' mode lines.
|
||
|
|
||
|
This uses hide-mode-lines or show-mode-lines."
|
||
|
(if hide-mode-line
|
||
|
(if (there-is-only-one-frame-and-one-window)
|
||
|
(hide-mode-lines)
|
||
|
(show-mode-lines))
|
||
|
(show-mode-lines)))
|
||
|
|
||
|
(defun hide-mode-line-minibuffer-setup-hook ()
|
||
|
"Internal function."
|
||
|
(hide-mode-line-update))
|
||
|
(defun hide-mode-line-minibuffer-exit-hook ()
|
||
|
"Internal function."
|
||
|
(hide-mode-line-update))
|
||
|
(defun hide-mode-line-make-frame-function (new-frame)
|
||
|
"Internal function."
|
||
|
(hide-mode-line-update))
|
||
|
(defun hide-mode-line-delete-frame-function (dead-frame-walking)
|
||
|
"Internal function."
|
||
|
(hide-mode-line-update))
|
||
|
(defun hide-mode-line-window-configuration-change-hook ()
|
||
|
"Internal function."
|
||
|
(hide-mode-line-update))
|
||
|
|
||
|
(defun hide-mode-line-add-hooks ()
|
||
|
"Internal function."
|
||
|
(interactive)
|
||
|
(add-hook 'minibuffer-setup-hook
|
||
|
'hide-mode-line-minibuffer-setup-hook)
|
||
|
(add-hook 'minibuffer-exit-hook
|
||
|
'hide-mode-line-minibuffer-exit-hook)
|
||
|
(add-hook 'after-make-frame-functions
|
||
|
'hide-mode-line-make-frame-function)
|
||
|
(add-hook 'delete-frame-functions
|
||
|
'hide-mode-line-delete-frame-function)
|
||
|
(add-hook 'window-configuration-change-hook
|
||
|
'hide-mode-line-window-configuration-change-hook))
|
||
|
|
||
|
(defun hide-mode-line-remove-hooks ()
|
||
|
"Internal function."
|
||
|
(interactive)
|
||
|
(remove-hook 'minibuffer-setup-hook
|
||
|
'hide-mode-line-minibuffer-setup-hook)
|
||
|
(remove-hook 'minibuffer-exit-hook
|
||
|
'hide-mode-line-minibuffer-exit-hook)
|
||
|
(remove-hook 'after-make-frame-functions
|
||
|
'hide-mode-line-make-frame-function)
|
||
|
(remove-hook 'delete-frame-functions
|
||
|
'hide-mode-line-delete-frame-function)
|
||
|
(remove-hook 'window-configuration-change-hook
|
||
|
'hide-mode-line-window-configuration-change-hook))
|
||
|
|
||
|
;;;###autoload
|
||
|
(defun hide-mode-line ()
|
||
|
"Toggle the hide-mode-line functionality."
|
||
|
(interactive)
|
||
|
(if (functionp 'window-tree)
|
||
|
(progn
|
||
|
(if hide-mode-line
|
||
|
(hide-mode-line-remove-hooks)
|
||
|
(hide-mode-line-add-hooks))
|
||
|
(setq hide-mode-line (not hide-mode-line))
|
||
|
(hide-mode-line-update))
|
||
|
(error (concat "Your Emacs does not provide the window-tree function. "
|
||
|
"Please upgrade to GNU Emacs 22 "
|
||
|
"or to some other version of Emacs that provides it."))))
|
||
|
|
||
|
(provide 'hide-mode-line)
|
||
|
|
||
|
;;; hide-mode-line.el ends here
|
||
|
|