;;; appearance.el --- Configure appearance. -*- lexical-binding: t; -*- ;;; Commentary: ;; * Helpful visualizations. ;; * Colors and theme. ;; * Icon font. ;; * Modeline stuff. ;;; Code: (require 'basics/package-management) (require 'basics/global-variables) (use-package emacs :straight (:type built-in) :demand t ;; If 2 files have the same name, append directory name after the filename. :custom ((uniquify-after-kill-buffer-p t) (uniquify-buffer-name-style 'post-forward) (uniquify-strip-common-suffix t)) :config (progn (defun my/set-default-fonts () "Set the default font and the emoji font." (when (member "Source Code Pro" (font-family-list)) ; Default. (set-frame-font "Source Code Pro-10" t t)) (when (member "Noto Color Emoji" (font-family-list)) ; Emojis. (set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend))) (tool-bar-mode -1) ; Hide toolbar. (menu-bar-mode -1) ; Hide menu bar. (when (fboundp #'set-scroll-bar-mode) (set-scroll-bar-mode 'right)) (add-to-list 'default-frame-alist '(scroll-bar-width . 8)) (my/set-default-fonts) ;; (show-paren-mode t) ; Visualize matching parens. (setq frame-title-format ; Show filename in frame title. '(multiple-frames "%b" ("" invocation-name "@" system-name " – " buffer-file-truename))))) ;; Highlight current line. (use-package hl-line :straight (:type built-in) :demand t :config (global-hl-line-mode t)) ;; Icon font (required by doom and others). (use-package all-the-icons :demand t :init (defun my/font-installed-p (font-name) "Check if font with FONT-NAME is available." (if (find-font (font-spec :name font-name)) t nil)) ;; Install fonts if we have a GUI and the font is not already installed. ;; See . :config (when (and (display-graphic-p) (not (my/font-installed-p "all-the-icons"))) (all-the-icons-install-fonts t))) (use-package doom-themes :demand t :after (all-the-icons) :custom ((doom-themes-treemacs-theme "doom-colors") (doom-themes-treemacs-enable-variable-pitch nil)) :config (progn (defvar my/run-fix-theme t) (defun my/fix-theme () "Fix some colors, needed the for the first frame after server start." (when my/run-fix-theme (set-face-background 'hl-line "#140f50") (set-face-background 'region "#340f50") (when (display-graphic-p) (set-face-background 'scroll-bar (face-background 'default)) (set-face-foreground 'scroll-bar (face-foreground 'shadow))) (when (fboundp #'my/ruler-set-colors) (my/ruler-set-colors)) (when (fboundp #'my/volatile-highlights-reset-color) (my/volatile-highlights-reset-color)) (my/set-default-fonts) (when (display-graphic-p) (setq my/run-fix-theme nil)) (when (fboundp #'my/hl-paren-set-faces) (my/hl-paren-set-faces)))) (load-theme 'doom-outrun-electric t) (my/fix-theme) (doom-themes-visual-bell-config) ; Flash modeline on error. ;; No icons in TUI, see ;; (doom-themes-treemacs-config) ;; Write a minimal theme to file, to load it in early-init.el. (unless (string= (face-background 'default) "unspecified-bg") (let ((minimal-theme)) (setq minimal-theme (concat "(set-face-background 'default \"" (face-background 'default) "\")\n" "(set-face-foreground 'default \"" (face-foreground 'default) "\")\n" "(menu-bar-mode -1)\n" "(when (display-graphic-p)\n" " (tool-bar-mode -1))\n")) (with-temp-file (expand-file-name "early-theme.el" user-emacs-directory) (insert minimal-theme)))) (defun my/treemacs-reset-fringe () "Make fringe in treemacs visible again." (set-window-fringes (selected-window) 8)) (advice-add #'doom-themes-hide-fringes-maybe :after #'my/treemacs-reset-fringe)) :hook (server-after-make-frame . my/fix-theme)) ;; Neat modeline. (use-package doom-modeline :after (all-the-icons hl-line) :init (column-number-mode t) ; Show column number. :custom ((doom-modeline-minor-modes t) ; Show minor modes. (doom-modeline-buffer-file-name-style 'truncate-all) (mode-line-percent-position nil) ; Don't display percentage. (doom-modeline-buffer-state-icon nil)) ; Don't display save icon. :hook ((after-init . doom-modeline-mode) ;; (server-after-make-frame . (lambda () (customize-set-variable 'doom-modeline-icon (display-graphic-p)))))) ;; Show line numbers on the left side of the buffer. (use-package display-line-numbers :straight (:type built-in) :demand t :if (>= emacs-major-version 26) :config (progn (defun my/disable-line-numbers () (display-line-numbers-mode -1)) (global-display-line-numbers-mode))) ;; Visualize and transform whitespace. (use-package whitespace :after (company doom-themes) :functions (my/on-off-whitespace-before-company) :diminish whitespace-mode :custom (whitespace-line-column nil) ; Set to fill-column. :config (progn (delete 'newline-mark whitespace-style) ; Don't paint $ at eol. (delete 'lines whitespace-style) ; Don't mark whole long lines. (delete 'space-mark whitespace-style) ; Don't show dots. (when (< emacs-major-version 27) ; Mark end of too long lines. (add-to-list 'whitespace-style 'lines-tail)) ;; Workaround to not show dots in popup menus. (defvar-local my/ws-enabled nil) (defun my/whitespace-mode-off () (setq-local my/ws-enabled whitespace-mode) (when my/ws-enabled (whitespace-mode -1))) (defun my/whitespace-mode-on () (when my/ws-enabled (whitespace-mode t))) ;; company: (defun my/on-off-whitespace-before-company (command) (when (string= "show" command) (my/whitespace-mode-off)) (when (string= "hide" command) (my/whitespace-mode-on))) (advice-add 'company-call-frontends :before #'my/on-off-whitespace-before-company) ;; popup: (defadvice popup-create (before my/popup-suspend-ws activate) "Suspend whitespace-mode while popups are visible." (my/whitespace-mode-off)) (defadvice popup-delete (after my/popup-restore-ws activate) "Restore whitespace-mode when all popups have closed." (my/whitespace-mode-on)) (if (display-graphic-p) (custom-set-faces '(whitespace-line ((t (:inherit whitespace-line :weight normal :foreground nil :background nil :box (:line-width 1 :color "dark red")))))) (custom-set-faces ; else '(whitespace-line ((t (:inherit whitespace-line :background nil :underline t)))))) ;; Workaround for ;; , fixed ;; in 28.1. (defun my/ws-load-local-vars-first () "Loads fill-column before enabling whitespace-mode." ;; We don't use 'lines-tail in Emacs >= 27. (when (< emacs-major-version 27) (hack-local-variables)) (whitespace-mode)) (defun my/ws-maybe-cleanup () "Run `whitespace-cleanup' if `my/reformat-save' is t." (when my/reformat-save (whitespace-cleanup)))) :bind ("C-c w" . whitespace-mode) :hook ((prog-mode . my/ws-load-local-vars-first) (conf-mode . my/ws-load-local-vars-first) (text-mode . my/ws-load-local-vars-first))) (use-package highlight-parentheses :after (whitespace) :demand t :diminish (highlight-parentheses-mode) :custom ((highlight-parentheses-colors nil) (highlight-parentheses-background-colors nil)) :config (progn(global-highlight-parentheses-mode) (defun my/hl-paren-set-faces () "Faces have to be set after the first frame is created." (customize-set-variable 'highlight-parentheses-attributes `((:weight bold :background ,(face-foreground 'whitespace-space)) (:weight ultrabold))))) :hook (minibuffer-setup . highlight-parentheses-minibuffer-setup)) (provide 'basics/appearance) ;;; appearance.el ends here