hamacs/ha-display.org
Howard Abrams ccb49d5a58 Tangle all configuration files to my elisp directory
Haven't really needed this, as I have a function to load the org file
as Emacs Lisp code directly, but this can be a little helpful for debugging.
2023-07-05 10:22:18 -07:00

415 lines
17 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: Emacs Graphical Display Configuration
#+AUTHOR: Howard X. Abrams
#+DATE: 2020-09-10
A literate programming file to configure the Emacs UI.
#+begin_src emacs-lisp :exports none
;;; ha-display --- Emacs UI configuration. -*- lexical-binding: t; -*-
;;
;; © 2020-2023 Howard X. Abrams
;; Licensed under a Creative Commons Attribution 4.0 International License.
;; See http://creativecommons.org/licenses/by/4.0/
;;
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams>
;; 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
And lets make this Emacs look more like a fancy IDE with [[https://github.com/domtronn/all-the-icons.el][all-the-icons]]:
#+begin_src emacs-lisp
(use-package all-the-icons
:if (display-graphic-p))
#+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
* Find the Bloody Cursor
Large screen, lots of windows, so where is the cursor? While I used to use =hl-line+=, I found that the prolific [[https://protesilaos.com/][Protesilaos Stavrou]] [[https://protesilaos.com/codelog/2022-03-14-emacs-pulsar-demo/][introduced his Pulsar project]] is just what I need. Specifically, I might /loose the cursor/ and need to have it highlighted (using ~F6~), but also, this automatically highlights the cursor line with specific /actions/ , like changing windows.
#+begin_src emacs-lisp
(use-package pulsar
:straight (:host github :repo "protesilaos/pulsar")
:custom
(pulsar-pulse-functions '(recenter-top-bottom
move-to-window-line-top-bottom
reposition-window
bookmark-jump
other-window
delete-window
delete-other-windows
aw-delete-window
forward-page
backward-page
scroll-up-command
scroll-down-command
evil-window-right
evil-window-left
evil-window-up
evil-window-down
aw-move-window
aw-swap-window
aw-copy-window
aw-split-window-vert
aw-split-window-horz
aw-split-window-fair
ha-new-window
winum-select-window-1
winum-select-window-2
winum-select-window-3
winum-select-window-4
winum-select-window-5
winum-select-window-6
winum-select-window-7
winum-select-window-8
winum-select-window-9
winner-undo
winner-redo
tab-new
tab-close
tab-next
org-next-visible-heading
org-previous-visible-heading
org-forward-heading-same-level
org-backward-heading-same-level
outline-backward-same-level
outline-forward-same-level
outline-next-visible-heading
outline-previous-visible-heading
outline-up-heading))
(pulsar-face 'pulsar-magenta)
(pulsar-delay 0.055)
:bind ("<f6>" . pulsar-pulse-line))
#+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")
(set-face-attribute 'mode-line nil :background "black")
(set-face-attribute 'mode-line-inactive nil :background "#444444"))
#+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")
(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
(add-to-list 'initial-frame-alist '(fullscreen . maximized))
#+end_src
But when capturing, I subsequently open smaller frames that shouldnt be /odd looking/:
#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))
#+end_src
Now that Im using v29 of Emacs, I can /un-decorate/ the non-full-sized frames:
#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(undecorated-round . t))
#+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/:
#+begin_example
| Similarities | Regular |
|--------------+----------------------------|
| ()[]{}<>«»‹› | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
| 6bB8& | abcdefghijklmnopqrstuvwxyz |
| 0ODdoaoOQGC | 0123456789 |
| I1tilIJL | ~!@#$%^&*+ |
| !¡ij | `'"‘’“”.,;:… |
| 5$§SsS5 | ()[]{}—-_=<>/\ |
| 17ZzZ2 | ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ |
| 9gqpG6 | αβγδεζηθικλμνξοπρστυφχψω |
| hnmMN | |
| uvvwWuuwvy | |
| x×X | |
| .,·°% | |
| ¡!¿? | |
| :; | |
| `''"‘’“” | |
| —-~≈=≠+*_ | |
| …⋯ | |
| ... | |
#+end_example
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 <stdio.h> // <= 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:
#+begin_src emacs-lisp
(defvar ha-fixed-font
(when window-system
(or
(seq-first
(seq-filter (lambda (font) (when (x-list-fonts font) font))
'("CaskaydiaCove Nerd Font" ; finally found it
"Cascadia Code PL" ; funky font with litagures and a dotted 0
"Hack Nerd Font" ; clean font, but no litagures!?
"FiraCode Nerd Font" ; has litagures
"Cousine Nerd Font"
"Iosevka Nerd Font"
"Iosevka"
"FantasqueSansMono Nerd Font"
"Monoid Nerd Font"
"Hasklig"
"Source Code Pro")))
"monospaced"))
"My fixed width font based on what I have installed.")
#+end_src
I probably don't need to have such a ranking system, as chances are good I have them all installed.
#+begin_src emacs-lisp
(defvar ha-variable-font
(when window-system
(or
(seq-first
(seq-filter (lambda (font) (when (x-list-fonts font) font))
'("Literata" ; Clean, readable with litagures
"XCharter" ; https://fontesk.com/xcharter-typeface/
"Charter"
; Interesting idea: "Iosevka Comfy Motion Duo"
"Serif")))
(warn "Cannot find a Serif Font. Install Source Sans Pro."))))
(defvar ha-variable-header-font
(when window-system
(or
(seq-first
(seq-filter (lambda (font) (when (x-list-fonts font) font))
'("Overpass" "Source Sans Pro"
"Lucida Grande" "Verdana"
"Sans Serif")))
(warn "Cannot find a Sans Serif Font. Install Source Sans Pro."))))
#+end_src
Simple function that gives me the font information based on the size I need. Recently updated after reading [[https://protesilaos.com/codelog/2020-09-05-emacs-note-mixed-font-heights/][this essay]], as I wanted my =fixed-pitch= to scale along with my =variable-pitch= font.
#+begin_src emacs-lisp
(defun ha-set-favorite-font-size (size)
"Set the default font size as well as equalize the fixed and variable fonts."
(let ((fav-font (format "%s-%d" ha-fixed-font size)))
(set-face-attribute 'default nil :font fav-font)
(set-face-attribute 'fixed-pitch nil :family ha-fixed-font :inherit 'default :height 1.0)
(set-face-attribute 'variable-pitch nil :family ha-variable-font :inherit 'default :height 1.2)))
#+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 18))
(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)
#+end_src
* Emojis, Icons and Whatnot
Display these two symbols as one:
#+begin_src emacs-lisp
(add-hook 'text-mode-hook (lambda ()
(dolist (pair '(("!?" . "")
("->" . ?→)
("<-" . ?←)
("=>" . ?⇒)))
(push pair prettify-symbols-alist))))
#+end_src
And turn the prettifier on:
#+begin_src emacs-lisp
(global-prettify-symbols-mode 1)
#+end_src
In Emacs 28.1, we have better Unicode 14 support. Which means, we need to install [[https://github.com/googlefonts/noto-emoji][Noto Color Emoji]]. My systems, seems to work fine, but Im leaving this code here in case I have issues, as I might use what Apple supplies when on a Mac (thanks [[http://xahlee.info/emacs/emacs/emacs_list_and_set_font.html][Xah Lee]]):
#+begin_src emacs-lisp
;; set font for symbols
(set-fontset-font t 'symbol
(cond
((string-equal system-type "darwin")
(cond
((member "Apple Symbols" (font-family-list)) "Apple Symbols")))
((string-equal system-type "gnu/linux")
(cond
((member "Symbola" (font-family-list)) "Symbola")))))
;; set font for emoji (should come after setting symbols)
(set-fontset-font t 'emoji
(cond
((member "Apple Color Emoji" (font-family-list)) "Apple Color Emoji")
((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
((member "Symbola" (font-family-list)) "Symbola")))
#+end_src
Test this out: 😄 😱 😸 👸 👽 🙋
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
We'll start using that instead, but setting this [[file:ha-programming.org::*Ligatures][over here]] in the programming section.
* Technical Artifacts :noexport:
Let's =provide= a name so we can =require= this file:
#+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 ~/.emacs.d/elisp/ha-display.el
#+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