#+TITLE: Emacs Graphical Display Configuration #+AUTHOR: Howard X. Abrams #+DATE: 2020-09-10 #+FILETAGS: :emacs: A literate programming file to configure the Emacs UI. # *Note:* After each change, /tangle it/ to the source destination with ~C-c C-v t~. #+BEGIN_SRC emacs-lisp :exports none ;;; ha-display.org --- A literate programming file to configure the Emacs UI. -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2020 Howard X. Abrams ;; ;; Author: Howard X. Abrams ;; Maintainer: Howard X. Abrams ;; Created: September 10, 2020 ;; ;; This file is not part of GNU Emacs. ;; ;; *NB:* Do not edit this file. Instead, edit the original literate file at: ;; ~/other/hamacs/ha-display.org ;; Using `find-file-at-point', and tangle the file to recreate this one . ;; ;;; Code: #+END_SRC * Dashboard The [[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] project makes a nicer startup screen. #+BEGIN_SRC emacs-lisp (use-package dashboard :init (defun ha-dashboard-version () (let ((smaller-version (replace-regexp-in-string (rx " (" (zero-or-more any) eol) "" (emacs-version)))) (string-replace "\n" "" smaller-version))) (setq dashboard-banner-logo-title (format "Emacs %s ⸺ %s" (if (and (fboundp 'native-comp-available-p) (native-comp-available-p)) "with Native Compilation" "") (ha-dashboard-version)) dashboard-startup-banner "~/other/hamacs/support/levitating-gnu.png" dashboard-center-content t dashboard-set-init-info t dashboard-projects-switch-function 'projectile-persp-switch-project dashboard-items '((projects . 5) ;; (agenda . 5) (bookmarks . 5))) :config (dashboard-setup-startup-hook) (setq dashboard-footer-messages (list (ha--dad-joke)))) #+END_SRC * Mode Line Let's install and load some of packages from the [[https://github.com/hlissner/doom-emacs][Doom Emacs]] project, like [[https://github.com/seagle0128/doom-modeline][doom-modeline]] and maybe the themes: #+BEGIN_SRC emacs-lisp (use-package doom-modeline :init (setq doom-modeline-minor-modes nil doom-modeline-buffer-encoding nil doom-modeline-percent-position nil) :config (doom-modeline-mode +1)) (use-package doom-themes) #+END_SRC * Themes One does get used to a particular collection of colors. Mine is Tomorrow: #+BEGIN_SRC emacs-lisp (use-package color-theme-sanityinc-tomorrow) #+END_SRC Most of the time, Emacs is on my desk is a darkened room, so I choose the dark theme: #+BEGIN_SRC emacs-lisp (defun laptop-inside () (interactive) (load-theme 'sanityinc-tomorrow-night t) (set-face-attribute 'region nil :background "#000096") ;; font-lock-comment-face #8a8b8a (set-face-attribute 'mode-line nil :background "black") (set-face-attribute 'mode-line-inactive nil :background "#333333")) #+END_SRC But, when feeling adventurous, I /sometimes/ take my laptop outside: #+BEGIN_SRC emacs-lisp (defun laptop-in-the-sun () (interactive) (load-theme 'sanityinc-tomorrow-day t) (set-face-attribute 'region nil :background "orange1") ;; font-lock-comment-face #8a8b8a (set-face-attribute 'mode-line nil :background "#cccccc") (set-face-attribute 'mode-line-inactive nil :background "#888888")) #+END_SRC Oh, and turn off the line highlighting: #+BEGIN_SRC emacs-lisp (global-hl-line-mode -1) #+END_SRC And of course, the default is /inside/ where it is dark and safe: #+BEGIN_SRC emacs-lisp (laptop-inside) #+END_SRC * Full Size Frame Taken from [[https://emacsredux.com/blog/2020/12/04/maximize-the-emacs-frame-on-startup/][this essay]], I figured I would start the initial frame automatically in fullscreen, but not any subsequent frames (as this could be part of the capturing system). #+BEGIN_SRC emacs-lisp :tangle no (add-to-list 'initial-frame-alist '(fullscreen . maximized)) #+END_SRC * Font Configuration Am I ever really ever satisfied with any font? I regularly change my font based on the monospace du jour... [[http://blogs.adobe.com/typblography/2012/09/source-code-pro.html][Source Code Pro]] is attractive, and has been a staple on every programmers' screen. However, we all want ligatures, [[https://github.com/i-tu/Hasklig][Hasklig]] is a nice font that is thinner and easier to read than [[https://github.com/tonsky/FiraCode][Fira]], but [[https://typeof.net/Iosevka/][Iosevka]] seems to have it all. Oh, Microsoft just gave us [[https://docs.microsoft.com/en-us/windows/terminal/cascadia-code][Cascadia]] and that seems shiny. However, the [[https://github.com/ryanoasis/nerd-fonts][Nerd Font project]] adds the ligatures as well as all the other niceties to a font. ** Choosing a Font I stole the following idea from [[https://protesilaos.com/dotemacs/#h:9035a1ed-e988-4731-89a5-0d9e302c3dea][Protesilaos Stavrou's dotfile configuration]], and the following should minimally be /readable/: | Similarities | Regular | |--------------+----------------------------| | ()[]{}<>«»‹› | ABCDEFGHIJKLMNOPQRSTUVWXYZ | | 6bB8& | abcdefghijklmnopqrstuvwxyz | | 0ODdoaoOQGC | 0123456789 | | I1tilIJL | ~!@#$%^&*+ | | !¡ij | `'"‘’“”.,;:… | | 5$§SsS5 | ()[]{}—-_=<>/\ | | 17ZzZ2 | ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ | | 9gqpG6 | αβγδεζηθικλμνξοπρστυφχψω | | hnmMN | | | uvvwWuuwvy | | | x×X | #include // <= quickly. | | .,·°% | int main(int argc, char **argv) { | | ¡!¿? | long il1[]={1-2/3.4,5+6==7/8}; | | :; | int OxFaced=0xBAD||"[{(CQUINE"; | | `''"‘’“” | unsigned O0,l1,Z2,S5,G6,B8__XY; | | —-~≈=≠+*_ | printf("@$Hamburgefo%c`",'\n'); | | …⋯ | return ~7&8^9?0:l1|!"j->k+=*w"; | | ... | | The following is from [[https://source-foundry.github.io/Hack/font-specimen.html][Hack's website]]: #+BEGIN_SRC c // The four boxing wizards jump #include // <= quickly. int main(int argc, char **argv) { long il1[]={1-2/3.4,5+6==7/8}; int OxFaced=0xBAD||"[{(CQUINE"; unsigned O0,l1,Z2,S5,G6,B8__XY; printf("@$Hamburgefo%c`",'\n'); return ~7&8^9?0:l1|!"j->k+=*w"; } #+END_SRC To install a font, I use the following command on my Mac: #+BEGIN_SRC sh brew tap homebrew/cask-fonts brew install --cask font-hack-nerd-font #+END_SRC ** Specifying a Font My /current/ favorite font is actually the top list of fonts that may be installed on my system (they usually are): #+BEGIN_SRC emacs-lisp (defvar ha-fixed-font (when window-system (cond ((x-list-fonts "Hack Nerd Font") "Hack Nerd Font") ((x-list-fonts "Cousine Nerd Font") "Cousine Nerd Font") ((x-list-fonts "Iosevka Nerd Font") "Iosevka Nerd Font") ((x-list-fonts "Iosevka") "Iosevka") ((x-list-fonts "FantasqueSansMono Nerd Font") "FantasqueSansMono Nerd Font") ((x-list-fonts "Monoid Nerd Font") "Monoid Nerd Font") ((x-list-fonts "Hasklig") "Hasklig") ((x-list-fonts "Cascadia Code PL") "Cascadia Code PL") ((x-list-fonts "Source Code Pro") "Source Code Pro") ((x-list-fonts "Anonymous Pro") "Anonymous Pro") (t "monospaced"))) "My fixed width font based on what is installed, `nil' if not defined.") #+END_SRC Force something as well: #+BEGIN_SRC emacs-lisp :tangle no (setq ha-fixed-font "Hack Nerd Font") #+END_SRC I probably don't need to have such a ranking system, as chances are really good that I'll have all of them installed. Still. #+BEGIN_SRC emacs-lisp (defvar ha-variable-font (when window-system (cond ((x-list-fonts "Overpass") "Overpass") ((x-list-fonts "Source Sans Pro") "Source Sans Pro") ((x-list-fonts "Lucida Grande") "Lucida Grande") ((x-list-fonts "Verdana") "Verdana") ((x-family-fonts "Sans Serif") "Sans Serif") (nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro.")))) "My variable width font available to org-mode files and whatnot.") #+END_SRC Simple function that gives me the font information based on the size I need. This calls =set-frame-font=, but also sets the monospaced font for org code blocks. #+BEGIN_SRC emacs-lisp (defun ha-set-favorite-font-size (size) (let ((fav-font (format "%s-%d" ha-fixed-font size))) (set-frame-font fav-font nil t) ;; When using variable-pitch in org, we need to specifically set the ;; fixed-pitch as my default fixed-pitched font. (custom-theme-set-faces 'user `(variable-pitch ((t (:family ,ha-variable-font :slant normal :weight normal :height 1.1 :width normal)))) `(fixed-pitch ((t (:family ,ha-fixed-font :slant normal :weight normal :height 1.0 :width normal))))))) #+END_SRC Define /interactive/ functions to quickly adjusting the font size based on my computing scenario: #+BEGIN_SRC emacs-lisp (defun ha-mac-monitor-fontsize () "Quickly set reset my font size when I connect my laptop to a monitor on a Mac." (interactive) (ha-set-favorite-font-size 13)) (defun ha-linux-monitor-fontsize () "Quickly set reset my font size when I connect my laptop to a monitor on Linux." (interactive) (ha-set-favorite-font-size 12)) (defun ha-mac-laptop-fontsize () "Quickly set reset my font size when I disconnect my laptop to a monitor from a Mac." (interactive) (ha-set-favorite-font-size 32)) (defun ha-linux-laptop-fontsize () "Quickly set reset my font size when I disconnect my laptop to a monitor from Linux." (interactive) (ha-set-favorite-font-size 14)) (defun ha-imac-fontsize () "Quickly set reset my font size when I am on my iMac." (interactive) (ha-set-favorite-font-size 16)) #+END_SRC Which font to choose? #+BEGIN_SRC emacs-lisp (defun font-monitor-size-default () "Set the default size according to my preference." (interactive) (cond ((eq system-type 'gnu/linux) (ha-linux-monitor-fontsize)) ((s-starts-with? "imac" system-name) (ha-imac-fontsize)) (t (ha-mac-monitor-fontsize)))) (defun font-laptop-size-default () "Set the default size according to my preference." (interactive) (if (eq system-type 'gnu/linux) (ha-linux-laptop-fontsize) (ha-mac-laptop-fontsize))) (font-monitor-size-default) #+END_SRC ** Zooming or Increasing Font Size Do we want to increase the size of font in a single window (using =text-scale-increase=), or globally (using my new =font-size-increase=)? Increase or decrease the set size of the face: #+BEGIN_SRC emacs-lisp (defun font-size-adjust (delta) "Adjust the current frame's font size. DELTA would be something like 1 or -1." (interactive "nFont size difference: ") (when (null delta) (setq delta 1)) (let* ((font-family (face-attribute 'default :font)) (font-size (font-get font-family :size)) (new-size (+ delta font-size))) (ha-set-favorite-font-size new-size))) (defun font-size-increase () "Increase the `default' font size of all frames." (interactive) (font-size-adjust 1)) (defun font-size-decrease () "Decrease the `default' font size of all frames." (interactive) (font-size-adjust -1)) #+END_SRC And some keybindings to call them: #+BEGIN_SRC emacs-lisp (global-set-key (kbd "s-+") 'font-size-increase) (global-set-key (kbd "s-=") 'font-size-increase) (global-set-key (kbd "s--") 'font-size-decrease) (global-set-key (kbd "s-0") 'font-size-monitor-default) (global-set-key (kbd "s-9") 'font-size-laptop-default) #+END_SRC * Icons and Whatnot Not use what I'm doing with the [[https://github.com/domtronn/all-the-icons.el][all-the-icons]] package, but the Doom Modeline uses much of this. #+BEGIN_SRC emacs-lisp (use-package all-the-icons) #+END_SRC *Note:* Install everything with the function, =all-the-icons-install-fonts=. * Ligatures Seems like getting ligatures to work in Emacs has been a Holy Grail. On Mac, I've used special builds that have hacks, but now with Emacs 27 and Harfbuzz, I should be able to get --> to look like it should. #+BEGIN_SRC emacs-lisp :tangle no (setq prettify-symbols-unprettify-at-point 'right-edge) (global-prettify-symbols-mode +1) (prettify-symbols-mode +1) #+END_SRC Note, in Doom, is appears we have a =ligatures= module. We'll start using that instead, but changing it in [[file:general-programming.org][general-programming]] file. * Technical Artifacts :noexport: Let's provide a name so that the file can be required: #+BEGIN_SRC emacs-lisp :exports none (provide 'ha-display) ;;; ha-display.el ends here #+END_SRC Before you can build this on a new system, make sure that you put the cursor over any of these properties, and hit: ~C-c C-c~ #+DESCRIPTION: A literate programming file to configure the Emacs UI. #+PROPERTY: header-args:sh :tangle no #+PROPERTY: header-args:emacs-lisp :tangle yes #+PROPERTY: header-args :results none :eval no-export :comments no :mkdirp yes #+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil #+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js