Skip to content

Commit

Permalink
[Core] Remove manual icon background color setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander-Miller committed Sep 30, 2023
1 parent d94bbda commit f4795c7
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 224 deletions.
5 changes: 1 addition & 4 deletions src/elisp/treemacs-core-utils.el
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@

(treemacs-import-functions-from "treemacs-visuals"
treemacs-pulse-on-success
treemacs--tear-down-icon-highlight
treemacs--forget-previously-follow-tag-btn
treemacs--forget-last-highlight)
treemacs--forget-previously-follow-tag-btn)

(treemacs-import-functions-from "treemacs-async"
treemacs--git-status-process
Expand Down Expand Up @@ -1083,7 +1081,6 @@ Will be added to `treemacs-ignored-file-predicates' on Macs."
(treemacs--popup-window)
(with-current-buffer lv-buffer (setf window-size-fixed t)))
(treemacs--popup-window))
(treemacs--forget-last-highlight)
(setq-local treemacs--in-this-buffer t))

(define-inline treemacs--parent (path)
Expand Down
11 changes: 6 additions & 5 deletions src/elisp/treemacs-fringe-indicator.el
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@
`(left-fringe ,treemacs--fringe-indicator-bitmap treemacs-fringe-indicator-face))
"The `before-string' property value used by the fringe indicator overlay.")

(define-inline treemacs--move-fringe-indicator-to-point ()
(defun treemacs--move-fringe-indicator-to-point ()
"Move the fringe indicator to the position of point."
(inline-quote
(when treemacs--fringe-indicator-overlay
(-let [pabol (line-beginning-position)]
(move-overlay treemacs--fringe-indicator-overlay pabol (1+ pabol))))))
(when treemacs--fringe-indicator-overlay
(-let [pabol (line-beginning-position)]
(move-overlay treemacs--fringe-indicator-overlay pabol (1+ pabol)))))

(defun treemacs--enable-fringe-indicator ()
"Enabled the fringe indicator in the current buffer."
Expand Down Expand Up @@ -78,6 +77,7 @@ WINDOW is the treemacs window that has just been focused or unfocused."
"Tear down `treemacs-fringe-indicator-mode'."
(treemacs-run-in-all-derived-buffers
(treemacs--disable-fringe-indicator)
(advice-remove #'hl-line-highlight #'treemacs--move-fringe-indicator-to-point)
(remove-hook 'window-selection-change-functions
#'treemacs--show-fringe-indicator-only-when-focused
:local)))
Expand Down Expand Up @@ -120,6 +120,7 @@ fringe indicator when the treemacs window is selected."
(setf treemacs-fringe-indicator-mode arg)
(treemacs-run-in-all-derived-buffers
(treemacs--enable-fringe-indicator)
(advice-add #'hl-line-highlight :after #'treemacs--move-fringe-indicator-to-point)
(when (memq arg '(t only-when-focused))
(add-hook 'window-selection-change-functions
#'treemacs--show-fringe-indicator-only-when-focused
Expand Down
118 changes: 19 additions & 99 deletions src/elisp/treemacs-icons.el
Original file line number Diff line number Diff line change
Expand Up @@ -36,42 +36,6 @@
(require 'inline)
(require 'treemacs-macros))

;; An explanation for the what and why of the icon highlighting code below:
;; Using png images in treemacs has one annoying visual flaw: they overwrite the overlay
;; used by hl-line, such that the line marked by hl-line will always show a 22x22 pixel
;; gap wherever treemacs places an icon, regardess of transparency.
;; Using xpm instead of png images is one way to work around this, but it degrades icon
;; quality to an unacceptable degree. Another way is to directly change images' :background
;; property. The backgrounds colours are derived from the current theme with `treemacs--setup-icon-highlight'
;; and saved in `treemacs--selected-icon-background' and `treemacs--not-selected-icon-background'.
;; Every icon string stores two images with the proper :background values in its properties
;; 'img-selected and 'img-unselected. The 'display property of the icon in the current line
;; is then highlighted, and the previously highlighted icon unhighlighted, by advising
;; `hl-line-highlight'. The last displayed icon is saved as a button marker in `treemacs--last-highlight'.
;; Since it is a marker in the treemacs buffer it is important for it to be reset whenever it might
;; become invalid.

(eval-and-compile
(defvar treemacs--not-selected-icon-background
(pcase (face-attribute 'default :background nil t)
((or 'unspecified 'unspecified-bg "unspecified" "unspecified-bg")
(unless (or noninteractive (boundp 'treemacs-no-load-time-warnings))
(message "[Treemacs] Warning: coudn't find default background colour for icons, falling back on #2d2d31."))
"#2d2d31" )
(other other)))
"Background for non-selected icons.")

(eval-and-compile
(defvar treemacs--selected-icon-background
(-let [bg (face-attribute 'hl-line :background nil t)]
(if (member bg '(unspecified unspecified-b "unspecified" "unspecified-bg"))
(prog1 treemacs--not-selected-icon-background
(unless (or noninteractive (boundp 'treemacs-no-load-time-warnings))
(message "[Treemacs] Warning: couldn't find hl-line-mode's background color for icons, falling back on %s."
treemacs--not-selected-icon-background)))
bg)))
"Background for selected icons.")

(define-inline treemacs--set-img-property (image property value)
"Set IMAGE's PROPERTY to VALUE."
;; the emacs26 code where this is copied from says it's for internal
Expand Down Expand Up @@ -116,35 +80,6 @@ account."
(plist-get it :background)
(face-attribute ,face :background nil t)))))

(defun treemacs--setup-icon-background-colors (&rest _)
"Align icon backgrounds with current Emacs theme.
Fetch the current Emacs theme's background & hl-line colours and inject them
into the gui icons of every theme in `treemacs--themes'.
Also called as advice after `enable-theme', hence the ignored argument."
(let* ((default-background (or (face-background 'treemacs-window-background-face)
(face-background 'default)))
(hl-line-background (or (face-background 'treemacs-hl-line-face)
(face-background 'hl-line)))
(test-icon (treemacs-get-icon-value 'dir-open))
(icon-background (treemacs--get-img-property (get-text-property 0 'img-unselected test-icon) :background))
(icon-hl-background (treemacs--get-img-property (get-text-property 0 'img-selected test-icon) :background)))
(when (memq default-background '(unspecified-bg unspecified))
(treemacs-log-failure "Current theme fails to specify default background color, falling back on #2d2d31")
(setq default-background "#2d2d31"))
;; make sure we only change all the icons' colors when we have to
(unless (and (string= default-background icon-background)
(string= hl-line-background icon-hl-background))
(setf treemacs--selected-icon-background hl-line-background
treemacs--not-selected-icon-background default-background)
(dolist (theme treemacs--themes)
(treemacs--maphash (treemacs-theme->gui-icons theme) (_ icon)
(treemacs--set-img-property
(get-text-property 0 'img-selected icon)
:background treemacs--selected-icon-background)
(treemacs--set-img-property
(get-text-property 0 'img-unselected icon)
:background treemacs--not-selected-icon-background))))))

(define-inline treemacs--is-image-creation-impossible? ()
"Will return non-nil when Emacs is unable to create images.
In this scenario (usually caused by running Emacs without a graphical
Expand Down Expand Up @@ -194,28 +129,31 @@ Necessary since root icons are not rectangular."
(s-starts-with? "root-" file-path))
(treemacs--root-icon-size-adjust width height))
(if (and (integerp treemacs--icon-size) (image-type-available-p 'imagemagick))
(create-image file-path 'imagemagick nil :ascent 'center :width width :height height)
(create-image
file-path 'imagemagick nil
:ascent 'center
:width width
:height height
:mask 'heuristic)
(create-image
file-path
(intern (treemacs--file-extension (treemacs--filename file-path)))
nil
:ascent 'center :width width :height height))))
:ascent 'center
:width width
:height height
:mask 'heuristic))))

(defun treemacs--create-icon-strings (file fallback)
"Create propertized icon strings for a given FILE image and TUI FALLBACK."
(let ((tui-icon fallback)
(gui-icon
(if (treemacs--is-image-creation-impossible?)
fallback
(let* ((img-selected (treemacs--create-image file))
(img-unselected (copy-sequence img-selected)))
(nconc img-selected `(:background treemacs--selected-icon-background))
(nconc img-unselected `(:background treemacs--not-selected-icon-background))
(concat (propertize " "
'display img-unselected
'img-selected img-selected
'img-unselected img-unselected)
" ")))))
(concat (propertize
" "
'display (treemacs--create-image file))
" "))))
(cons gui-icon tui-icon)))

(defmacro treemacs--splice-icon (icon)
Expand Down Expand Up @@ -551,17 +489,14 @@ png are changed."
(treemacs-log-failure "Icons cannot be resized without image transforms or imagemagick support.")
(setq treemacs--icon-size size)
(treemacs--maphash (treemacs-theme->gui-icons treemacs--current-theme) (_ icon)
(let ((display (get-text-property 0 'display icon))
(img-selected (get-text-property 0 'img-selected icon))
(img-unselected (get-text-property 0 'img-unselected icon))
(width treemacs--icon-size)
(height treemacs--icon-size))
(let ((display (get-text-property 0 'display icon))
(width treemacs--icon-size)
(height treemacs--icon-size))
(when (eq 'image (car-safe display))
(when (s-ends-with? "root.png" (plist-get (cdr display) :file))
(treemacs--root-icon-size-adjust width height))
(dolist (property (list display img-selected img-unselected))
(plist-put (cdr property) :height height)
(plist-put (cdr property) :width width)))))))
(plist-put (cdr display) :height height)
(plist-put (cdr display) :width width))))))

(defun treemacs--select-icon-set ()
"Select the right set of icons for the current buffer.
Expand Down Expand Up @@ -637,21 +572,6 @@ be assigned which treemacs icon, for example
(substring extension 1)
icon))))

(defun treemacs-realign-icon-colors ()
"Make sure icons' colours fit in with current faces.
You can call this when you notice that some icons' background colour being
different than the background of the treemacs buffer, or that the icon
background does not fit in with the hl-line overlay.
This function should only be necessary when you *manually* change either
`treemacs-window-background-face' or `treemacs-hl-line-face' (e.g. using
`set-face-background'). Loading of new themes if handled automatically."
(interactive)
(--when-let (treemacs-get-local-buffer)
(with-current-buffer it
(treemacs--setup-icon-background-colors))))

(treemacs-only-during-init
(treemacs-load-theme "Default"))

Expand Down
4 changes: 0 additions & 4 deletions src/elisp/treemacs-interface.el
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,6 @@ For slower scrolling see `treemacs-previous-line-other-window'"
(treemacs-return-if (string-equal old-name new-name)
(treemacs-pulse-on-failure "The new name is the same as the old name."))
(setf (treemacs-project->name project) new-name)
(treemacs--forget-last-highlight)
;; after renaming, delete and redisplay the project
(goto-char (treemacs-button-end project-btn))
(delete-region (line-beginning-position) (line-end-position))
Expand Down Expand Up @@ -907,7 +906,6 @@ With a prefix ARG also forget about all the nodes opened in the project."
(treemacs-pulse-on-failure "There is nothing to close here.")
(-let [btn (treemacs-project->position project)]
(when (treemacs-is-node-expanded? btn)
(treemacs--forget-last-highlight)
(goto-char btn)
(treemacs--collapse-root-node btn arg)
(treemacs--maybe-recenter 'on-distance)))
Expand All @@ -920,7 +918,6 @@ With a prefix ARG remember which nodes were expanded."
(-when-let (buffer (treemacs-get-local-buffer))
(with-current-buffer buffer
(save-excursion
(treemacs--forget-last-highlight)
(dolist (project (treemacs-workspace->projects (treemacs-current-workspace)))
(-when-let (pos (treemacs-project->position project))
(when (eq 'root-node-open (treemacs-button-get pos :state))
Expand Down Expand Up @@ -1123,7 +1120,6 @@ Prefix ARG will be passed on to the closing function
(-if-let* ((btn (treemacs-current-button))
(parent (button-get btn :parent)))
(progn
(treemacs--forget-last-highlight)
(goto-char parent)
(treemacs-toggle-node arg)
(treemacs--evade-image))
Expand Down
2 changes: 0 additions & 2 deletions src/elisp/treemacs-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,6 @@ Will simply return `treemacs--eldoc-msg'."

(treemacs--build-indentation-cache 6)
(treemacs--select-icon-set)
(treemacs--setup-icon-highlight)
(treemacs--setup-icon-background-colors)
(treemacs--setup-mode-line)
(treemacs--reset-dom))

Expand Down
4 changes: 0 additions & 4 deletions src/elisp/treemacs-scope.el
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
(treemacs-import-functions-from "treemacs-filewatch-mode"
treemacs--stop-filewatch-for-current-buffer)

(treemacs-import-functions-from "treemacs-visuals"
treemacs--tear-down-icon-highlight)

(treemacs-import-functions-from "treemacs-interface"
treemacs-quit
treemacs-select-window)
Expand Down Expand Up @@ -180,7 +177,6 @@ NEW-SCOPE-TYPE: T: treemacs-scope"

(defun treemacs--on-buffer-kill ()
"Cleanup to run when a treemacs buffer is killed."
(treemacs--tear-down-icon-highlight)
(when (eq t treemacs--in-this-buffer)
;; stop watch must come first since we need a reference to the killed buffer
;; to remove it from the filewatch list
Expand Down
66 changes: 1 addition & 65 deletions src/elisp/treemacs-visuals.el
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@
(treemacs-import-functions-from "treemacs-icons"
treemacs-get-icon-value)

(defvar-local treemacs--last-highlight nil
"The last button treemacs has highlighted.")

(defvar-local treemacs--indentation-string-cache-key nil
"Cache key for `treemacs--indentation-string-cache.")
(defvar-local treemacs--indentation-string-cache (vector)
Expand All @@ -54,71 +51,10 @@
Used to save the values of `treemacs-indentation' and
`treemacs-indentation-string'.")

(define-inline treemacs--forget-last-highlight ()
"Set `treemacs--last-highlight' to nil."
(inline-quote (setq treemacs--last-highlight nil)))

(defun treemacs--setup-icon-highlight ()
"Make sure treemacs icons background aligns with hi-line's."
(advice-add #'hl-line-highlight :after #'treemacs--update-icon-selection)
(advice-add #'enable-theme :after #'treemacs--setup-icon-background-colors)
(advice-add #'disable-theme :after #'treemacs--setup-icon-background-colors))

(defun treemacs--tear-down-icon-highlight ()
"Tear down highlighting advice when no treemacs buffer exists anymore."
(treemacs--forget-last-highlight)
(unless (or treemacs--scope-storage
(--any (buffer-local-value 'treemacs--in-this-buffer it)
(buffer-list)))
(advice-remove #'hl-line-highlight #'treemacs--update-icon-selection)
(advice-remove #'enable-theme #'treemacs--setup-icon-background-colors)
(advice-remove #'disable-theme #'treemacs--setup-icon-background-colors)))

(defun treemacs--update-icon-selection ()
"Highlight current icon, un-highlight `treemacs--last-highlight'."
(when treemacs--in-this-buffer
(condition-case e
(progn
(when treemacs-fringe-indicator-mode
(treemacs--move-fringe-indicator-to-point))
(-when-let (btn (treemacs-current-button))
(let* ((pos (max (line-beginning-position) (- (treemacs-button-start btn) 2)))
(img-selected (get-text-property pos 'img-selected)))
(treemacs-with-writable-buffer
(when (and treemacs--last-highlight
(> (point-max) treemacs--last-highlight))
(let* ((last-pos (- (treemacs-button-start treemacs--last-highlight) 2))
(img-unselected (get-text-property last-pos 'img-unselected)))
(put-text-property last-pos (1+ last-pos) 'display img-unselected)))
(when img-selected
(put-text-property pos (1+ pos) 'display img-selected)
(setq treemacs--last-highlight btn))))))
(error
(treemacs-log-err "Error on highlight, this shouldn't happen: %s" e)))))

(defun treemacs--pulse-png-advice (&rest _)
"Make sure icons' background are pulsed alongside the entire line."
(when (eq 'treemacs-mode major-mode)
(treemacs-with-writable-buffer
(-when-let (btn (treemacs-current-button))
(let* ((start (max (line-beginning-position) (- (treemacs-button-start btn) 2)))
(end (1+ start))
(img (get-text-property start 'display))
(cp (copy-sequence img)))
;; Icons may not always be images, as extensions may use text and e.g.
;; all-the-icons font icons as the icon.
(when (eq (car-safe cp) 'image)
(treemacs--set-img-property cp :background
(face-attribute
(overlay-get pulse-momentary-overlay 'face)
:background nil t))
(put-text-property start end 'display cp)))))))

(defun treemacs--do-pulse (face)
"Visually pulse current line using FACE."
(pulse-momentary-highlight-one-line (point) face)
(advice-add 'pulse-momentary-unhighlight :after #'hl-line-highlight)
(advice-add 'pulse-lighten-highlight :after #'treemacs--pulse-png-advice))
(advice-add 'pulse-momentary-unhighlight :after #'hl-line-highlight))

(defsubst treemacs-pulse-on-success (&rest log-args)
"Pulse current line with `treemacs-on-success-pulse-face'.
Expand Down
4 changes: 0 additions & 4 deletions src/elisp/treemacs-workspaces.el
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
treemacs--maybe-load-workspaces)

(treemacs-import-functions-from "treemacs-visuals"
treemacs--forget-last-highlight
treemacs-pulse-on-failure)

(treemacs-import-functions-from "treemacs-async"
Expand Down Expand Up @@ -288,7 +287,6 @@ Does not preserve the current position in the buffer."
(when (treemacs-project->is-expanded? self)
(let ((root-btn (treemacs-project->position self)))
(goto-char root-btn)
(treemacs--forget-last-highlight)
(funcall (alist-get (treemacs-button-get root-btn :state)
treemacs-TAB-actions-config))
(unless (treemacs-project->is-unreadable? self)
Expand Down Expand Up @@ -610,7 +608,6 @@ Return values may be as follows:
(if (equal (point-min) prev-project-pos)
(goto-char next-project-pos)
(goto-char prev-project-pos)))
(treemacs--forget-last-highlight)
(treemacs--invalidate-buffer-project-cache)
(--when-let (treemacs-get-local-window)
(with-selected-window it
Expand Down Expand Up @@ -765,7 +762,6 @@ PROJECT: Project Struct"
(ht-remove! treemacs-dom (treemacs-project->path project-in-buffer))
(setf projects-in-buffer (delete project-in-buffer projects-in-buffer))))
(treemacs-with-writable-buffer
(treemacs--forget-last-highlight)
(treemacs--reset-dom)
;; delete everything's that's visible and render it again - the order of projects could
;; have been changed
Expand Down
Loading

0 comments on commit f4795c7

Please sign in to comment.