Subject: [PATCH] New command 'toggle-mode-line-visibility'
From: Elijah Gabe Pérez <[email-masked]>
To: [email-masked]
Date: Mon, 23 Jun 2025 13:20:44 -0600
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

This new command allows toggle the mode line visibility in the current
buffer.

The mode line keeps hidden from each major mode change, avoiding having
to run this command many times.

This is based/inspired by `hide-mode-line-mode` (from MELPA), but unlike
latter one, this is a rewrite which uses a command instead a minor mode
and I'm interested in including this in Emacs :^).

From a3c36ce32da275a6213e28a8feb3abe1b27ba87a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Mon, 23 Jun 2025 12:50:28 -0600
Subject: [PATCH] New command 'toggle-mode-line-visibility'

This new command allows toggle the mode line visibility in the
current buffer.  (Bug#)

* etc/NEWS: Announce changes.
* lisp/bindings.el (toggle-mode-line--buf-state): New buffer
local variable.
(toggle-mode-line-visibility): New command.
(disable-mode-line): New function.
---
 etc/NEWS         |  8 ++++++++
 lisp/bindings.el | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 6f3d28d0e03..c9de3feae63 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -346,6 +346,14 @@ This option allows changing or removing the delimiters shown around
 the major mode and list of minor modes in the mode line.  The default
 retains the existing behavior of inserting parentheses.
 
+---
+*** New command 'toggle-mode-line-visibility'.
+This command toggles the mode line visibility in current buffer, if the
+current buffer displays a mode line, this will temporally hide it until
+'toggle-mode-line-visibility' is called again.  Otherwise, if the
+current buffer does not have a mode line by default, this will display
+one.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 8b021a05ce2..6c7d47dcd4a 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -56,6 +56,52 @@ mode-line-widen
     (widen)
     (force-mode-line-update)))
 
+;; Variable used by `toggle-mode-line-visibility' for
+;; store mode-line value in current buffer.
+(defvar-local toggle-mode-line--buf-state)
+
+(defun toggle-mode-line-visibility (&optional hide-only)
+  "Toggle mode line visibility in current buffer.
+If current buffer displays a mode line, temporally hide it until
+`toggle-mode-line-visibility' is called again.  Otherwise, display one
+if the buffer does not have a mode line by default.
+
+The mode line is hidden from every major mode change in current buffer.
+
+If HIDE-ONLY is non-nil, only hide the mode-line."
+  (interactive "^P")
+  (if mode-line-format
+      (progn
+        ;; Hook to prevent the mode line from being displayed again at
+        ;; each change of major mode.
+        (add-hook 'after-change-major-mode-hook #'disable-mode-line nil t)
+        (setq toggle-mode-line--buf-state
+              (buffer-local-set-state mode-line-format nil)))
+
+    (unless hide-only
+      (remove-hook 'after-change-major-mode-hook #'disable-mode-line t)
+      (setq toggle-mode-line--buf-state
+            (buffer-local-restore-state toggle-mode-line--buf-state))
+
+      ;; Display a mode line if buffer does not have one by default.
+      (unless mode-line-format
+        (setq-local mode-line-format (default-value 'mode-line-format)))
+
+      ;; Update mode line.
+      (when (called-interactively-p 'any)
+        (force-mode-line-update)))))
+
+;; NOTE: This function is intended to be used in hooks.
+(defun disable-mode-line ()
+  "Hide the mode-line in current buffer.
+The mode line is hidden from every major mode change in current buffer.
+
+See `toggle-mode-line-visibility'."
+  (toggle-mode-line-visibility 'hide))
+
+(put 'toggle-mode-line--buf-state 'permanent-local t)
+(put 'disable-mode-line 'permanent-local-hook t)
+
 (defvar mode-line-input-method-map
   (let ((map (make-sparse-keymap)))
     (define-key map [mode-line mouse-2]
-- 
2.49.0

-- 
                                          - E.G via GNU Emacs and Org.