diff --git a/center-content.el b/center-content.el index c9434cb..d739a42 100644 --- a/center-content.el +++ b/center-content.el @@ -2,21 +2,23 @@ ;;; Commentary: -;; 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. +;; This package provides a minor mode `center-content-mode' that centers the +;; content of the current buffer both horizontally and vertically. ;;; Code: (defvar-local center-content--horizontal-overlay nil "Overlay used to add left margin for horizontal centering.") -(defvar-local center-content--vertical-overlay nil - "Overlay used to add top margin for vertical 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.") +(defvar-local center-content--header-line-face-remap-cookie nil + "Cookie for the face remapping of `header-line`.") + (defun center-content--calculate-left-margin () "Calculate the left margin needed to center the content horizontally." (let* ((window (selected-window)) @@ -24,33 +26,36 @@ (content-width (car (window-text-pixel-size window (window-start window) - (window-end window))))) - (/ (max 0 (- window-width content-width)) 2))) + (window-end window t)))) + (column-width (string-pixel-width " "))) + (/ (max 0 (- window-width content-width)) (* 2 column-width)))) (defun center-content--calculate-top-margin () "Calculate the top margin needed to center the content vertically." (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)) + (content-height (cdr (window-text-pixel-size + window + (window-start window) + (window-end window t))))) + (/ (max 0 (- window-height content-height)) (* 2 (frame-char-height))))) (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 ((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)) + (let ((overlay (make-overlay (point-min) (point-max)))) + (overlay-put overlay 'line-prefix + (propertize " " 'display `(space :width ,left-margin))) + (setq center-content--horizontal-overlay overlay)) + ;; Apply vertical centering using header-line-format + ;; Save and remap the header-line face to match the default face + (setq center-content--original-header-line-format header-line-format) + (setq center-content--header-line-face-remap-cookie + (face-remap-add-relative 'header-line 'default)) + (setq header-line-format + (propertize " " 'display `(height ,top-margin))) ;; Save and hide the mode line (setq center-content--original-mode-line-format mode-line-format) (setq mode-line-format nil) @@ -64,13 +69,16 @@ (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 header-line face remapping + (when center-content--header-line-face-remap-cookie + (face-remap-remove-relative center-content--header-line-face-remap-cookie) + (setq center-content--header-line-face-remap-cookie nil)) + ;; Restore the header-line-format + (setq header-line-format center-content--original-header-line-format) + (setq center-content--original-mode-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) + (setq center-content--original-header-line-format nil) ;; Force redisplay (force-mode-line-update) (redisplay))