From 194631b978d426da81b55f143b3029acbd1bf98d Mon Sep 17 00:00:00 2001 From: larstvei Date: Sat, 14 Sep 2024 02:39:20 +0200 Subject: [PATCH] initial commit with odd header line behavior --- center-content.el | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 center-content.el diff --git a/center-content.el b/center-content.el new file mode 100644 index 0000000..ff83931 --- /dev/null +++ b/center-content.el @@ -0,0 +1,100 @@ +;;; center-content.el --- Center buffer content horizontally and vertically -*- lexical-binding: t; -*- + +;;; Commentary: + +;; This package provides a minor mode `center-content-mode` that centers the visible content +;; of the current buffer both horizontally and vertically. It calculates the necessary margins +;; and applies them using overlays and header line adjustments. The mode line is hidden to +;; provide a clean appearance. + +;;; Code: + +(defvar-local center-content--horiz-overlay nil + "Overlay used by `center-content-mode` to add left margin for horizontal centering.") + +(defvar-local center-content--original-header-line-format nil + "Stores the original `header-line-format` to restore upon disabling.") + +(defvar-local center-content--original-mode-line-format nil + "Stores the original `mode-line-format` to restore upon disabling.") + +(defface center-content-header-line + `((t (:inherit default + :background ,(face-background 'default nil t) + :foreground ,(face-foreground 'default nil t)))) + "Face for the header line in `center-content-mode`." + :group 'center-content) + +(defun center-content--calculate-left-margin () + "Calculate the left margin needed to center the content horizontally." + (let* ((window (selected-window)) + (window-width (window-pixel-width window)) + (content-width (car (window-text-pixel-size + window + (window-start window) + (window-end window)))) + (space-width (string-pixel-width " ")) + (margin (/ (max 0 (- window-width content-width)) (* 2 space-width)))) + margin)) + +(defun center-content--calculate-top-margin () + "Calculate the top margin needed to center the content vertically." + (let* ((window-height (window-pixel-height)) + (content-height (cdr (window-text-pixel-size))) + (margin (/ (max 0 (- window-height content-height)) 2))) + margin)) + +(defun center-content--enable () + "Enable horizontal and vertical centering of content." + (let ((left-margin (center-content--calculate-left-margin)) + (top-margin (center-content--calculate-top-margin))) + ;; Apply horizontal centering using overlay + (let ((horiz-overlay (make-overlay (point-min) (point-max)))) + (overlay-put horiz-overlay 'line-prefix + (propertize " " 'display `(space :width ,left-margin))) + (setq center-content--horiz-overlay horiz-overlay)) + ;; Save the original header-line-format + (setq center-content--original-header-line-format header-line-format) + ;; Apply vertical centering using header-line-format with custom face + (setq header-line-format + (propertize " " + 'display `(height ,(max 0 (/ top-margin (frame-char-height)))) + 'face 'center-content-header-line)) + ;; Save the original mode-line-format + (setq center-content--original-mode-line-format mode-line-format) + ;; Hide the mode line + (setq mode-line-format nil))) + +(defun center-content--disable () + "Disable centering of content." + ;; Remove horizontal centering overlay + (when (overlayp center-content--horiz-overlay) + (delete-overlay center-content--horiz-overlay) + (setq center-content--horiz-overlay nil)) + ;; Restore the original header-line-format + (setq header-line-format center-content--original-header-line-format) + (setq center-content--original-header-line-format nil) + ;; Restore the original mode-line-format + (setq mode-line-format center-content--original-mode-line-format) + (setq center-content--original-mode-line-format nil) + ;; Force redisplay to remove any lingering effects + (force-mode-line-update) + (redisplay)) + +;;;###autoload +(define-minor-mode center-content-mode + "Toggle horizontal and vertical centering of buffer content. + +When enabled, the visible content of the buffer is centered both +horizontally and vertically within the window. The mode line is +hidden for a clean appearance." + :init-value nil + :global nil + :lighter nil ;; Remove the lighter to keep the mode line clean + (if center-content-mode + (center-content--enable) + (center-content--disable))) + +(provide 'center-content) + +;;; center-content.el ends here