From bf66b90b9aea61799c089e91ceec3ce237195f3a Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Fri, 2 Dec 2022 09:54:22 +0200 Subject: [PATCH] Fix the width of margins for icons in outline-minor-mode (bug#59719) * doc/lispref/display.texi (Icons): Add :width spec. * lisp/emacs-lisp/icons.el (icons--create): Handle :width as well. * lisp/outline.el (outline--margin-width, outline-margin-width): New variables. (outline-open-in-margins, outline-close-in-margins) (outline-close-rtl-in-margins): Don't inherit from parents. Use `:width font' instead of `:height 10'. (outline-minor-mode): Calculate the number of columns for margins to fit the icons. --- doc/lispref/display.texi | 6 ++++++ lisp/emacs-lisp/icons.el | 4 ++++ lisp/outline.el | 41 ++++++++++++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 60955fd3195..9d929950a7e 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -7124,6 +7124,12 @@ This is only valid for @code{image} icons, and can be either a number (which specifies the height in pixels), or the symbol @code{line}, which will use the default line height in the currently selected window. + +@item :width +This is only valid for @code{image} icons, and can be either a number +(which specifies the width in pixels), or the symbol @code{font}, +which will use the width in pixels of the current buffer’s default +face font. @end table @var{doc} should be a doc string. diff --git a/lisp/emacs-lisp/icons.el b/lisp/emacs-lisp/icons.el index 86c44830308..8ba6d97ea00 100644 --- a/lisp/emacs-lisp/icons.el +++ b/lisp/emacs-lisp/icons.el @@ -202,6 +202,10 @@ present if the icon is represented by an image." (list :height (if (eq height 'line) (window-default-line-height) height))) + (if-let ((width (plist-get keywords :width))) + (list :width (if (eq width 'font) + (default-font-width) + width))) '(:scale 1) (if-let ((rotation (plist-get keywords :rotation))) (list :rotation rotation)) diff --git a/lisp/outline.el b/lisp/outline.el index 86ac19aa415..2c3f9798ec4 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -318,6 +318,12 @@ don't modify the buffer." (defvar-local outline--use-rtl nil "Non-nil when direction of clickable buttons is right-to-left.") +(defvar-local outline--margin-width nil + "Current margin width.") + +(defvar-local outline-margin-width nil + "Default margin width.") + (define-icon outline-open nil '((image "outline-open.svg" "outline-open.pbm" :height (0.8 . em)) (emoji "🔽") @@ -344,24 +350,24 @@ don't modify the buffer." "Right-to-left icon used for buttons in closed outline sections." :version "29.1") -(define-icon outline-open-in-margins outline-open - '((image "outline-open.svg" "outline-open.pbm" :height 10) +(define-icon outline-open-in-margins nil + '((image "outline-open.svg" "outline-open.pbm" :width font) (emoji "🔽") (symbol "▼") (text "v")) "Icon used for buttons for opened sections in margins." :version "29.1") -(define-icon outline-close-in-margins outline-close - '((image "outline-open.svg" "outline-open.pbm" :height 10 :rotation -90) +(define-icon outline-close-in-margins nil + '((image "outline-open.svg" "outline-open.pbm" :width font :rotation -90) (emoji "▶️") (symbol "▶") (text ">")) "Icon used for buttons for closed sections in margins." :version "29.1") -(define-icon outline-close-rtl-in-margins outline-close-rtl - '((image "outline-open.svg" "outline-open.pbm" :height 10 :rotation 90) +(define-icon outline-close-rtl-in-margins nil + '((image "outline-open.svg" "outline-open.pbm" :width font :rotation 90) (emoji "◀️") (symbol "◀") (text "<")) @@ -528,9 +534,22 @@ See the command `outline-mode' for more information on this mode." (when (and (eq outline-minor-mode-use-buttons 'in-margins) (> 1 (if outline--use-rtl right-margin-width left-margin-width))) + (setq outline--margin-width + (or outline-margin-width + (ceiling + (/ (seq-max + (seq-map #'string-pixel-width + (seq-map #'icon-string + `(outline-open-in-margins + ,(if outline--use-rtl + 'outline-close-rtl-in-margins + 'outline-close-in-margins))))) + (* (default-font-width) 1.0))))) (if outline--use-rtl - (setq-local right-margin-width (1+ right-margin-width)) - (setq-local left-margin-width (1+ left-margin-width))) + (setq-local right-margin-width (+ right-margin-width + outline--margin-width)) + (setq-local left-margin-width (+ left-margin-width + outline--margin-width))) (setq-local fringes-outside-margins t) ;; Force display of margins (when (eq (current-buffer) (window-buffer)) @@ -566,8 +585,10 @@ See the command `outline-mode' for more information on this mode." (< 0 (if outline--use-rtl right-margin-width left-margin-width))) (if outline--use-rtl - (setq-local right-margin-width (1- right-margin-width)) - (setq-local left-margin-width (1- left-margin-width))) + (setq-local right-margin-width (- right-margin-width + outline--margin-width)) + (setq-local left-margin-width (- left-margin-width + outline--margin-width))) (setq-local fringes-outside-margins nil) ;; Force removal of margins (when (eq (current-buffer) (window-buffer)) -- 2.39.2