diff --git a/center-content.el b/center-content.el index ff83931..c9434cb 100644 --- a/center-content.el +++ b/center-content.el @@ -2,29 +2,21 @@ ;;; 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. +;; This package provides a minor mode `center-content-mode` that centers the content +;; of the current buffer both horizontally and vertically. It calculates the necessary +;; margins and applies them using overlays. 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--horizontal-overlay nil + "Overlay used 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--vertical-overlay nil + "Overlay used to add top margin for vertical centering.") (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)) @@ -32,15 +24,14 @@ (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)) + (window-end window))))) + (/ (max 0 (- window-width content-width)) 2))) (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))) + (let* ((window (selected-window)) + (window-height (window-pixel-height window)) + (content-height (cdr (window-text-pixel-size window))) (margin (/ (max 0 (- window-height content-height)) 2))) margin)) @@ -49,35 +40,38 @@ (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 + (let ((horizontal-overlay (make-overlay (point-min) (point-max)))) + (overlay-put horizontal-overlay 'line-prefix + (propertize " " 'display `(space :width (,left-margin)))) + (setq center-content--horizontal-overlay horizontal-overlay)) + ;; Apply vertical centering using a before-string overlay + (let ((overlay (make-overlay (point-min) (point-min)))) + (overlay-put overlay 'before-string + (propertize "\n" 'display `(space :height (,top-margin)))) + ;; Set low priority to avoid interfering with line-prefix + (overlay-put overlay 'priority -50) + (setq center-content--vertical-overlay overlay)) + ;; Save and hide the mode line (setq center-content--original-mode-line-format mode-line-format) - ;; Hide the mode line - (setq mode-line-format nil))) + (setq mode-line-format nil) + ;; Force redisplay + (force-mode-line-update) + (redisplay))) (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) + (when (overlayp center-content--horizontal-overlay) + (delete-overlay center-content--horizontal-overlay) + (setq center-content--horizontal-overlay nil)) + ;; Remove vertical centering overlay + (when (overlayp center-content--vertical-overlay) + (delete-overlay center-content--vertical-overlay) + (setq center-content--vertical-overlay 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 redisplay (force-mode-line-update) (redisplay)) @@ -85,7 +79,7 @@ (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 +When enabled, the 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