#+TITLE: My Literate GNU Emacs Config #+AUTHOR: Marius Peter #+DATE: <2020-07-23 Thu> #+EMAIL: blendoit@gmail.com #+STARTUP: showall customtime #+SETUPFILE: ~/.emacs.d/templates/documents/general.org #+INCLUDE: ~/.emacs.d/templates/documents/general.org_title #+LATEX: \begin{abstract} GNU Emacs is most often used as a text editor. The utmost level of customization is afforded by enabling the user to rewrite \textit{any} part of the source code and observe the editor's modified behaviour in real time. Since its inception in 1984, GNU Emacs has grown to be much more than a full-featured, high-productivity text editor---new \textit{modes} have been written to interact with hundreds of file formats, including \texttt{.txt}, \texttt{.pdf}, \texttt{.jpg}, \texttt{.csv}, and \texttt{.zip} just to name a few. This configuration file itself was written in \textit{Org mode}, a collection of functions enabling the harmonious mixing of code and comments in view of publication: this is the endgame of \textit{literate programming}. #+LATEX: \end{abstract} * Introduction The following sections were laid out very deliberately. When we start Emacs, Emacs Lisp source code blocks contained in this document are evaluated sequentially---our editing environment is constructed in real time as we execute the blocks in order. For instance, we only begin loading packages once we ensured ~use-package~ is working properly. Customizing Emacs goes far, far beyond this document---feel free to experiment and discover. - ~C-h f~ describe function - ~C-h v~ describe variable - ~C-h k~ describe key These three commands will attempt to describe the element currently under our cursor, however you can start typing to search for another symbol. * TODO First-time setup Spacemacs-like dialog for default settings. #+NAME: first-setup # #+BEGIN_SRC emacs-lisp # ;; Prompt enterprise or personal install. Create file in .emacs.d/ on Linux, # ;; AppData/ on Windows. Ask user for details and preferred bindings. # # ; Check if .emacs.d exists # # ; If it does, warn user # # ; Copy init-bootstrap.el from USB to where operating systems expects init.el # # ;; (defun blendoit/first-time-setup-windows-nt () # ;; "Execute the first-time setup on MS Windows. # ;; If no `.emacs.d/' config exists on local system, copy # ;; init-bootstrap.el to `~.emacs.d/'." # ;; (interactive) # ;; (find-file "~/.emacs.d/blendoit/blendoit-init.org")) # # ;; (cond ((string-equal system-type "windows-nt")blendoit/first-time-setup-windows-nt) # ;; ((string-equal system-type "gnu/linux") blendoit/first-time-setup-linux)) # #+END_SRC ** File system paths In this subsection, we tell Emacs about relevant paths to resources. On my MS Windows machine, I add the path to Portable Git.[fn::Download from https://git-scm.com/download/win] #+BEGIN_SRC emacs-lisp (when (string-equal system-type "windows-nt") (add-to-list 'exec-path "C:/Users/marius.peter/PortableGit/bin/")) #+END_SRC * Early setup ** Garbage collection First, we increase the RAM threshold beyond which the garbage collector is activated. #+NAME: garbage-collection #+BEGIN_SRC emacs-lisp (setq gc-cons-threshold 100000000) #+END_SRC ** Profiling --- start We start the profiler now , and will interrupt it in Section [[Profiling --- stop]]. We will then present profiling report in Section [[Profiling --- report]]. #+NAME: profiler-start #+BEGIN_SRC emacs-lisp ; (profiler-start) #+END_SRC ** Emacs client Makes opening emacs faster for following instances. #+NAME: emacs-client #+BEGIN_SRC emacs-lisp ; (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*"))) #+END_SRC ** Custom file Load settings created automatically by GNU Emacs Custom. (For example, any clickable option/toggle is saved here.) Useful for fooling around with M-x customize-group . user-emacs-directory #+NAME: custom-file-location #+BEGIN_SRC emacs-lisp (setq custom-file (concat user-emacs-directory "init-custom.el")) (load custom-file) #+END_SRC ** Customization shortcuts We begin by defining a user shortcut to this very file. We load this as early as possible, this facilitates debugging. #+NAME: shortcut-config #+BEGIN_SRC emacs-lisp (defun my/find-literate-config () "Jump to this very file." (interactive) (find-file my/literate-config)) (global-set-key (kbd "C-c c") 'my/find-literate-config) #+END_SRC Now, different shortcuts for other customization actions: #+NAME: shortcuts-customization #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-c v") 'customize-variable) (global-set-key (kbd "C-c f") 'customize-face) #+END_SRC ** Backups Backups are so important that they should be described right after the shortcut to this file. #+BEGIN_SRC emacs-lisp (setq backup-directory-alist `((".*" . ,temporary-file-directory)) auto-save-file-name-transforms `((".*" ,temporary-file-directory t)) backup-by-copying t ; Don't delink hardlinks version-control t ; Use version numbers on backups delete-old-versions t ; Automatically delete excess backups kept-new-versions 20 ; how many of the newest versions to keep kept-old-versions 5 ; and how many of the old ) #+END_SRC ** Initial and default frames We set the dimensions of the inital and default frames. #+BEGIN_SRC emacs-lisp (add-to-list 'default-frame-alist '(width . 100)) (add-to-list 'default-frame-alist '(height . 50)) (add-to-list 'initial-frame-alist '(width . 100)) (add-to-list 'initial-frame-alist '(height . 50)) #+END_SRC *** GNU/Linux These settings affect the first and subsequent frames spawned by Emacs in GNU/Linux. Frame transparency increases when focus is lost. #+BEGIN_SRC emacs-lisp (when (and (display-graphic-p) (string-equal system-type "gnu/linux")) (set-frame-parameter (selected-frame) 'alpha '(90 . 50)) (add-to-list 'default-frame-alist '(alpha . (90 . 50)))) #+END_SRC ** Secrets The code contained in the =secrets.org= file is loaded by Emacs, but not rendered in this PDF for the sake of privacy. It contains individually identifying information such as names and e-mail addresses, which are used to populate Org templates (Section [[~org-mode~]]). You need to create this =secrets.org= file, as it is ignored by =git= by default. #+BEGIN_SRC emacs-lisp (org-babel-load-file "~/.emacs.d/blendoit/secrets.org") #+END_SRC * Global key bindings The following bindings strive to further enhance CUA mode.[fn::Common User Access. This is a term coined by IBM which has influenced user navigation cues on all modern desktop OSes. From IBM's CUA, we get the =Ctrl-v= and =Ctrl-v= keyboard shortcuts.] #+BEGIN_SRC emacs-lisp (cua-mode) #+END_SRC ** Keyboard navigation #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-`") 'delete-other-windows) #+END_SRC *** Saving a file #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-s") 'save-buffer) #+END_SRC *** Opening a file #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-o") 'find-file) #+END_SRC *** Opening a recently visited file #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-r") 'counsel-recentf) #+END_SRC *** Locating a file #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-c l") 'counsel-locate) #+END_SRC *** Closing window and quitting Emacs #+BEGIN_SRC emacs-lisp (defun my/delete-window-or-previous-buffer () "Delete window; if sole window, previous buffer." (interactive) (if (> (length (window-list)) 1) (delete-window) (previous-buffer))) #+END_SRC The following bindings lead to more natural exit behaviors. #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-w") 'my/delete-window-or-previous-buffer) (global-set-key (kbd "C-q") 'save-buffers-kill-terminal) #+END_SRC ** Mouse zoom The typical binding on both GNU/Linux and MS Windows is adequate here: ~C-=~ to zoom in, ~C--~ to zoom out. It seems that starting with Emacs 27.1, Control + mousewheel works. #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C--") 'text-scale-decrease) (global-set-key (kbd "C-=") 'text-scale-increase) (global-set-key (kbd "C-+") 'text-scale-increase) #+END_SRC * Packages Packages are collections of =.el= files providing added functionality to Emacs. ** Meta How do we bootstrap packages? First, let's figure out: 1. Where we get our packages from 2. How we upgrade packages 3. How we ensure our required packages are installed *** Package archives List of package archives. #+NAME: package-archives #+BEGIN_SRC emacs-lisp (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t) (package-initialize) #+END_SRC *** TODO Convenient package update One-function rollup of upgradeable package tagging, download and lazy install. #+BEGIN_SRC emacs-lisp #+END_SRC *** ~use-package~ We ensure =use-package= is installed, as well as all packages described in this configuration file. #+BEGIN_SRC emacs-lisp (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package) (eval-when-compile (require 'use-package))) (setq use-package-always-ensure t) (require 'use-package) (require 'bind-key) #+END_SRC ** ~org-mode~ Phew, I can finally introduce Org mode! I am so *excited*. Org mode replaces aword processor, a presentation creator, and a spreadsheet editor. IMHO, the spreadsheet ability captures more than 80% use cases wherein one wishes to include a table in a text document destined for physical publication. (It is clear that Excel spreadsheets are /not/ destined for physical publication---simply attempt to print an Excel spreadsheet with the default settings.) In my opinion, Org mode matches all /useful/ features of the Microsoft Office suite 1-to-1. What follows are customizations designed to make Org mode behave more like Microsoft Word. The end goal is, once again, to draw as many new users to Emacs as possible! *** Basic customization Org base directory is in user home on GNU/Linux, or in =AppData= in MS Windows. #+NAME: org-basic #+BEGIN_SRC emacs-lisp (setq org-directory (concat user-emacs-directory "~/org")) #+END_SRC First, we hide markup symbols for *bold*, /italic/, _underlined_ and +strikethrough+ text, and ensure our document appears indented upon loading:[fn::It /appears/ indented, but the underlying plaintext file does not contain tab characters!] For the time being, I will in fact display emphasis markers, because hiding them corrupts tables. #+NAME: org-basic #+BEGIN_SRC emacs-lisp (setq org-hide-emphasis-markers nil) (setq org-startup-indented t) #+END_SRC *** Languages executable in smart documents The following languages can be written inside =SRC= blocks, in view of being executed by the Org Babel backend. #+BEGIN_SRC emacs-lisp (setq org-babel-load-languages '((shell . t) (python . t) (plantuml . t) (emacs-lisp . t) (awk . t) (ledger . t) (gnuplot . t) (latex . t))) #+END_SRC *** Prevent or warn on invisible edits #+BEGIN_SRC emacs-lisp (setq org-catch-invisible-edits t) #+END_SRC *** Agenda The agenda displays a chronological list of headings across all agenda files for which the heading or body contain a matching =org-time-stamp=.[fn::An =org-time-stamp= can be inserted with ~C-c .~ (period)] #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-c a") 'org-agenda-list) (defun my/find-diary-file () "Load `org-agenda-diary-file'." (interactive) (find-file org-agenda-diary-file)) (global-set-key (kbd "C-c d") 'my/find-diary-file) #+END_SRC *** Timestamps More literary timestamps are exported to LaTeX using the following custom format: #+BEGIN_SRC emacs-lisp (setq org-time-stamp-custom-formats '("%d %b, %Y (%a)" . "%d %b, %Y (%a), at %H:%M")) #+END_SRC *** LaTeX export We'll be compiling our documents with LuaTeX. This will afford us some future-proofing, since it was designated as the successor to pdfTeX by the latter's creators. First, we define the command executed when an Org file is exported to LaTeX. We'll use =latexmk=, the Perl script which automagically runs binaries related to LaTeX in the correct order and the right amount of times. Options and why we need them: - ~-shell-excape~ :: required by minted to color source blocks - ~-pdflatex=lualatex~ :: we use lualatex to generate our PDF - ~-interaction=nonstopmode~ :: go as far as possible without prompting user for input #+BEGIN_SRC emacs-lisp (setq org-latex-pdf-process '("latexmk -pdf -f \ -pdflatex=lualatex -shell-escape \ -interaction=nonstopmode -outdir=%o %f")) #+END_SRC We customize the format for org time stamps to make them appear monospaced in our exported LaTeX documents. This makes them visually distinguishable from body text. #+BEGIN_SRC emacs-lisp (setq org-latex-active-timestamp-format "\\texttt{%s}") (setq org-latex-inactive-timestamp-format "\\texttt{%s}") #+END_SRC The following packages are loaded for every time we export to LaTeX. #+BEGIN_SRC emacs-lisp (setq org-latex-packages-alist '(("AUTO" "polyglossia" t ("xelatex" "lualatex")) ("AUTO" "babel" t ("pdflatex")) ("" "booktabs" t ("pdflatex")) ("table,svgnames" "xcolor" t ("pdflatex")))) #+END_SRC Little bonus for GNU/Linux users: syntax highlighting for source code blocks in LaTeX exports. #+BEGIN_SRC emacs-lisp (when (string-equal system-type "gnu/linux") (add-to-list 'org-latex-packages-alist '("AUTO" "minted" t ("pdflatex" "lualatex"))) (setq org-latex-listings 'minted) (setq org-latex-minted-options '(("style" "friendly") ()))) #+END_SRC Now, we set the files to be deleted when a LaTeX \rightarrow PDF compilation occurs. We only care about two files, in the end: the Org mode file for edition, and the PDF for distribution. #+BEGIN_SRC emacs-lisp (setq org-latex-logfiles-extensions '("aux" "bcf" "blg" "fdb_latexmk" "fls" "figlist" "idx" "log" "nav" "out" "ptc" "run.xml" "snm" "toc" "vrb" "xdv" "tex" "lot" "lof")) #+END_SRC By default, Org agenda inserts diary entries as the first under the selected date. It is preferable to insert entries in the order that they were recorded, i.e. chronologically. #+BEGIN_SRC emacs-lisp (setq org-agenda-insert-diary-strategy 'date-tree-last) #+END_SRC What follows are the document class structures that can be exported in LaTeX. #+BEGIN_SRC emacs-lisp (setq org-latex-classes '(("article" "\\documentclass[11pt]{article}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("report" "\\documentclass[11pt]{report}" ("\\part{%s}" . "\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) ("book" "\\documentclass[12pt]{book}" ("\\part{%s}" . "\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) ("book-blendoit" "\\documentclass[12pt]{book}" ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection*{%s}" . "\\subsection*{%s}") ("\\subsubsection*{%s}" . "\\subsubsection*{%s}")))) #+END_SRC By default, body text can immediately follow the table of contents. It is however cleaner to separate table of contents with the rest of the work. #+BEGIN_SRC emacs-lisp (setq org-latex-toc-command "\\tableofcontents\\clearpage") #+END_SRC The following makes =TODO= items appear red and =CLOSED= items appear green in Org's LaTeX exports. Very stylish, much flair! *** Export This creates a shorter binding for the most common Org export: Org \rightarrow LaTeX \rightarrow PDF. #+BEGIN_SRC emacs-lisp (defun my/org-quick-export () "Org export to PDF and open. This basically reimplements `C-c C-e C-a l o'." (interactive) (org-open-file (org-latex-export-to-pdf))) (global-set-key (kbd "C-c e") 'my/org-quick-export) #+END_SRC ** TODO ~evil-mode~ Forgive me, for I have sinned. This is the 2^{nd} most significant customization after ~org-mode~. Enabling ~evil-mode~ completely changes editing keys.[fn::For more information on =vi= keybindings, visit [[https://hea-www.harvard.edu/~fine/Tech/vi.html]].] #+BEGIN_SRC emacs-lisp (use-package evil) ; (setq evil-toggle-key "C-c d") ; devil... ; (evil-mode 1) #+END_SRC ** Spelling, completion, and snippets The following customizations open the doors to vastly increased typing speed and accuracy. *** ~flycheck~ Syntax highlighting for Emacs. #+NAME: flycheck #+BEGIN_SRC emacs-lisp (use-package flycheck) (global-flycheck-mode) #+END_SRC *** TODO ~flyspell~ #+NAME: flyspell #+BEGIN_SRC emacs-lisp (use-package flyspell) (add-hook 'text-mode-hook 'flyspell-mode) #+END_SRC *** Insert template from keyword Thanks to yasnippet, we can type certain keywords, press =TAB=, and this will automatically insert a text snippet. We may then navigate through the snippet by using =TAB= (next field) and =SHIFT-TAB= (previous field). For instance: Typing =src= then pressing =TAB= will expand the keyword to the following text: : #+BEGIN_SRC emacs-lisp : : #+END_SRC We notice that emacs-lisp is highlighted---this is the first modifiable field. #+NAME: yasnippet #+BEGIN_SRC emacs-lisp (use-package yasnippet) (yas-global-mode 1) #+END_SRC *** Complete anything interactively #+NAME: company #+BEGIN_SRC emacs-lisp ; (add-hook 'after-init-hook 'global-company-mode) #+END_SRC *** Delete all consecutive whitespaces #+NAME: company #+BEGIN_SRC emacs-lisp (use-package hungry-delete :init (hungry-delete-mode)) #+END_SRC ** Utilities *** Versioning of files Wonderful Git porcelain for Emacs. Enables the administration of a Git repository in a pain-free way. #+BEGIN_SRC emacs-lisp (use-package magit :bind ("C-c g" . magit-status)) #+END_SRC *** Navigate between projects This enables us to better manage our =.git= projects. #+BEGIN_SRC emacs-lisp (use-package projectile :bind ("C-c p" . 'projectile-command-map) :init (projectile-mode 1) (setq projectile-completion-system 'ivy)) #+END_SRC *** Display keyboard shortcuts on screen #+BEGIN_SRC emacs-lisp (use-package which-key :init (which-key-mode)) #+END_SRC *** Jump to symbol's definition #+BEGIN_SRC emacs-lisp (use-package dumb-jump) (add-hook 'xref-backend-functions #'dumb-jump-xref-activate) #+END_SRC *** Graphical representation of file history #+BEGIN_SRC emacs-lisp (use-package undo-tree) (global-undo-tree-mode) #+END_SRC *** Auto-completion framework #+BEGIN_SRC emacs-lisp (use-package ivy :config (setq ivy-use-virtual-buffers t ivy-count-format "%d/%d " enable-recursive-minibuffers t)) (ivy-mode t) #+END_SRC **** Smartly suggesting interactive search matches Wonderful counsellor! #+BEGIN_SRC emacs-lisp (use-package counsel :bind ("M-x" . counsel-M-x) :config (counsel-mode t)) (global-set-key (kbd "C-f") 'counsel-grep-or-swiper) #+END_SRC **** Searching for items #+BEGIN_SRC emacs-lisp (use-package swiper :bind (("C-f" . counsel-grep-or-swiper))) #+END_SRC ** File formats *** =csv= and Excel #+BEGIN_SRC emacs-lisp (use-package csv-mode) #+END_SRC *** Interacting with PDFs Org mode shines particularly when exporting to PDF---Org files can reliably be shared and exported to PDF in a reproducible fashion. #+BEGIN_SRC emacs-lisp (use-package pdf-tools) ;; (pdf-tools-install) #+END_SRC *** Accounting Ledger is a creation of John Wiegley's. It enables double-entry accounting in a simple plaintext format, and reliable verification of account balances through time.[fn::For more information, visit https://www.ledger-cli.org/.] #+BEGIN_SRC emacs-lisp (use-package ledger-mode :bind ("C-c r" . ledger-report) ("C-c C" . ledger-mode-clean-buffer)) #+END_SRC These reports can be generated within Emacs. It is quite useful to pipe their output to an automated ``smart document''. #+BEGIN_SRC emacs-lisp (setq ledger-reports '(("bal" "%(binary) -f %(ledger-file) bal") ("bal-USD" "%(binary) -f %(ledger-file) bal --exchange USD") ("reg" "%(binary) -f %(ledger-file) reg") ("net-worth" "%(binary) -f %(ledger-file) bal ^Assets ^Liabilities --exchange USD") ("net-income" "%(binary) -f %(ledger-file) bal ^Income ^Expenses --exchange USD --depth 2 --invert") ("payee" "%(binary) -f %(ledger-file) reg @%(payee)") ("account" "%(binary) -f %(ledger-file) reg %(account)") ("budget" "%(binary) -f %(ledger-file) budget --exchange USD"))) #+END_SRC *** Plotting & charting #+BEGIN_SRC emacs-lisp (use-package gnuplot) #+END_SRC ** Cosmetics *** Start page We replace the standard welcome screen with our own. #+BEGIN_SRC emacs-lisp (setq inhibit-startup-message t) (use-package dashboard :config (dashboard-setup-startup-hook) (setq dashboard-startup-banner (concat user-emacs-directory "img/Safran_logo.svg")) (setq dashboard-items '((recents . 5) (projects . 5))) (setq dashboard-banner-logo-title "A modern professional text editor.")) #+END_SRC *** Mode line #+NAME: powerline #+BEGIN_SRC emacs-lisp (use-package powerline) #+END_SRC *** TODO Sidebar Get inspiration from ~ibuffer-sidebar~ and create a better sidebar. #+BEGIN_SRC emacs-lisp ;; (load-file) #+END_SRC *** Better parentheses #+BEGIN_SRC emacs-lisp (use-package rainbow-delimiters :config (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)) (electric-pair-mode) (show-paren-mode 1) #+END_SRC *** Colored keywords for those colors This highlights hexadecimal numbers which look like colors, in that same color. #+BEGIN_SRC emacs-lisp (use-package rainbow-mode :init (add-hook 'prog-mode-hook 'rainbow-mode)) #+END_SRC * Editing preferences These customizations enhance editor usability. They are not brought about ** Editor *** Coding standards This is just a better default. Don't @ me. #+BEGIN_SRC emacs-lisp (setq c-default-style "linux" c-basic-offset 4) #+END_SRC *** Recent files The keybinding for opening a recently visited file is described in paragraph [[Opening a recently visited file]]. #+BEGIN_SRC emacs-lisp (recentf-mode 1) (setq recentf-max-menu-items 25) (setq recentf-max-saved-items 25) (run-at-time nil (* 5 60) 'recentf-save-list) #+END_SRC ** Frame *** Clean up menus Originally, I wished to inhibit certain entries in the GUI menus. Not worth the effort at this time. #+BEGIN_SRC emacs-lisp (menu-bar-mode -1) (tool-bar-mode -1) #+END_SRC *** Dividers This ensures users can resize windows using the GUI. It also creates a useful separation between the bottom of the frame and the echo area. #+BEGIN_SRC emacs-lisp (menu-bar-bottom-and-right-window-divider) #+END_SRC *** TODO Header & mode line Complete mode line rewrite. Might require new package. Top of the buffer is more intuitive for buffer info, bottom is more intuitive for buffer action. This is pretty much a gutted out powerline. **** Header line #+BEGIN_SRC emacs-lisp (setq header-line-format "%b") #+END_SRC **** Mode line #+BEGIN_SRC emacs-lisp (setq mode-line-format nil) #+END_SRC ** Window ** Buffer Save cursor location in visited buffer after closing it or Emacs. #+BEGIN_SRC emacs-lisp (save-place-mode 1) #+END_SRC *** Column filling A line of text is considered ``filled'' when it reaches 79 characters in length. #+BEGIN_SRC emacs-lisp (setq-default fill-column 79) #+END_SRC Automatically break lines longer than =fill-column=. #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook 'turn-on-auto-fill) #+END_SRC ** Minibuffer We replace the longer ~yes-or-no-p~ questions with more convenient ~y-or-n-p~. #+BEGIN_SRC emacs-lisp (defalias 'yes-or-no-p 'y-or-n-p) #+END_SRC Disable minibuffer scroll bar. #+BEGIN_SRC emacs-lisp (set-window-scroll-bars (minibuffer-window) nil nil) #+END_SRC * Themes Without a carefully designed theme, our editor could become unusable. Thus, we describe two themes that were developed purposefully and iteratively. #+BEGIN_SRC emacs-lisp (setq custom-theme-directory (concat user-emacs-directory "themes/")) (load-theme 'blendoit-light) ; (load-theme 'blendoit-dark) #+END_SRC ** My light and dark themes A highly legible unambiguous and thoughtful theme. *** Colors The default face is a black foreground on a white background, this matches MS Word. We are striving for a simple, intuitive color scheme. Most of the visual cues derived from color are identical in both light and dark themes (Table [[theme-color-1]]). #+NAME: theme-color-1 #+CAPTION[Light and dark themes' colors]: Light and dark themes' colors. #+ATTR_LATEX: :booktabs t | Color | ~blendoit-light~ | ~blendoit-dark~ | |---------------------------------+---------------------------------+--------------------| | Black | default text | default background | | Lighter shades | lesser headers | /n/a/ | | White | default background | default text | | Darker shades | /n/a/ | lesser headers | | \color{Red} Red | negative | /same/ | | \color{Tomato} Tomato | timestamp `TODO' | /same/ | | \color{Green} Green | positive | /same/ | | \color{ForestGreen} ForestGreen | timestamp `DONE' | /same/ | | \color{Blue} Blue | interactable content; links | /same/ | | \color{SteelBlue} SteelBlue | anything Org mode; anchor color | /same/ | | \color{DeepSkyBlue} DeepSkyBlue | ~highlight~ | /same/ | | \color{DodgerBlue} DodgerBlue | ~isearch~ | /same/ | | \color{Purple} Purple | | | *** Cursors In order to imitate other modern text editors, we resort to a blinking bar cursor. We choose red, the most captivating color, because the cursor is arguably the region on our screen: 1. most often looked at; 2. most often searched when lost. In files containing only ~fixed-pitch~ fonts (i.e. files containing only code), the cursor becomes a high-visibility box. In files containing a mix of ~variable-pitch~ and ~fixed-pitch~ fonts, the cursor is a more MS Word-like bar. #+BEGIN_SRC emacs-lisp (setq-default cursor-type 'bar) #+END_SRC *** Faces - ~default~: Hack - Legible, modern monospace font - Strict, sharp, uncompromising - ~fixed-pitch~: Hack - ~variable-pitch~: Liberation Sans - Libre alternative to Arial - ~org-block~: Hermit - Slightly wider than Hack - More opinionated shapes - Very legible parentheses **** ~variable-pitch-mode~ We use ~variable-pitch-mode~ for appropriate modes. #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook 'variable-pitch-mode) (add-hook 'info-mode-hook 'variable-pitch-mode) #+END_SRC **** TODO Default font size Make default font size larger on displays of which the resolution is greater than =1920x1080=. #+BEGIN_SRC emacs-lisp #+END_SRC ** TODO ~minimal~ * Late setup At this point, our editor is almost ready to run. Phew! All that's left to do is to interrupt our profiling activities, and smartly store the result of our profiling. ** Profiling --- stop #+BEGIN_SRC emacs-lisp ;; (profiler-stop) #+END_SRC ** Profiling --- report #+BEGIN_SRC emacs-lisp ;; (profiler-report) #+END_SRC * Conclusion In this configuration file, we described a series of customization steps taken to make Emacs more palatable to modern IDE users.