Terror Emacs

home · config file · how to · screenshots · download · contact


Table of Contents

Preamble

We configure the lexical-binding.

;;; init.el -*- lexical-binding: t; -*-

And we will use the GPLv3 license or higher.

;;-----------------------------------------------------------------------;;
;;                           TERROR EMACS                                ;;
;;         A simple Emacs setup for the terror of academic life          ;;
;;                                                                       ;;
;; This program is free software: you can redistribute it and/or modify  ;;
;; it under the terms of the GNU General Public License as published by  ;;
;; the Free Software Foundation, either version 3 of the License, or     ;;
;; any later version.                                                    ;;
;;                                                                       ;;
;; This program is distributed in the hope that it will be useful,       ;;
;; but WITHOUT ANY WARRANTY; without even the implied warranty of        ;;
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         ;;
;; GNU General Public License for more details.                          ;;
;;                                                                       ;;
;; You should have received a copy of the GNU General Public License     ;;
;; along with this program.  If not, see <http://www.gnu.org/licenses/>. ;;
;;-----------------------------------------------------------------------;;

The behaviour of the garbage collector is momentarily changed to improve start-up time.

(setq gc-cons-threshold (* 50 1000 1000))

Optionally, we add our personal data (they don't have to be real).

(setq user-full-name "DELM"
      user-mail-address "dlmayhem@riseup.net")

General configuration

In this section we will configure the general appearance and behaviour of our editor. Here, for example, you can activate or deactivate toolbars, line numbers, font type and size, etc.

(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(set-fringe-mode 4)
(global-visual-line-mode 1)
(global-auto-revert-mode 1)
(global-hl-line-mode 1)
(set-face-font 'default "JetBrainsMono 12")
(set-face-font 'variable-pitch "JetBrainsMono 12")
(fset 'yes-or-no-p 'y-or-n-p)
(delete-selection-mode 1)
(column-number-mode)
(dolist (mode '(c-mode-hook
                emacs-lisp-mode-hook
                sh-mode-hook
                shell-mode-hook
                python-mode-hook
                LaTeX-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode t))))
(setq-default cursor-in-non-selected-windows nil
              frame-title-format '("%f [%m]"))
(setq default-fill-column 100
      make-backup-files nil
      inhibit-startup-message t
      use-dialog-box nil
      tramp-default-method "ssh"
      custom-file "~/.emacs.d/custom.el"
      global-auto-revert-non-file-buffers t
      large-file-warning-threshold nil)
(load custom-file)

Sources

These are the sources from which the packages required for Terror Emacs will be automatically downloaded, as well as those that you may want to add in the future. Also, we add use-package, which helps us to keep a clean, efficient, tidy and easy to read configuration file.

(require 'package)

(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("nongnu" . "https://elpa.nongnu.org/nongnu/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))

(unless (package-installed-p 'use-package)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

Miscellaneous

Next, we set up a minimalist ecosystem consisting of a vertical completion UI (vertico), marginal notes with useful information (marginalia), a practical context menu (embark), fuzzy searches (orderless) and an autocompletion system (corfu).

(use-package vertico
  :ensure t
  :init
  (vertico-mode))

(use-package savehist
  :init
  (savehist-mode))

(use-package marginalia
  :after vertico
  :ensure t
  :init
  (marginalia-mode)
  :custom
  (marginalia-align 'right))

(use-package embark
  :ensure t
  :bind (("C-." . embark-act)
         ("C-;" . embark-dwim)
         ("C-h B" . embark-bindings))
  :init
  (setq prefix-help-command #'embark-prefix-help-command)
  :config
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

(use-package orderless
  :ensure t
  :after vertico
  :custom
  (completion-styles '(orderless)))

(use-package corfu
  :custom
  (corfu-auto t)
  (corfu-separator ?\s)
  :init
  (global-corfu-mode))

(use-package corfu-terminal
  :config
  (unless (display-graphic-p)
    (corfu-terminal-mode +1)))

We will use some Doom Emacs tools on the visual side: doom-themes is a very polished collection of colour schemes to suit all tastes; solaire-mode assigns slightly different background colours to different buffers depending on their content, which helps to maintain focus; doom-modeline is a clean and elegant mode line, showing only the most relevant information.

(use-package doom-themes
  :if window-system
  :init
  (load-theme 'doom-wilmersdorf t))

(use-package solaire-mode
  :hook (after-init . solaire-global-mode))

(use-package doom-modeline
  :init
  (doom-modeline-mode 1)
  :custom
  (doom-modeline-height 15))

Some elegant icons.

(use-package all-the-icons
  :if (display-graphic-p))

The citar package uses the ecosystem mentioned at the beginning of this section to provide a simple way to insert bibliographic references that works perfectly well in LaTeX, org, markdown, etc.

(use-package citar
  :bind ("C-c b" . citar-insert-citation)
  :custom
  (citar-bibliography '("~/Documentos/refs.bib"))
  (org-cite-global-bibliography '("~/Documentos/refs.bib")))

There are times when we can't remember the gigantic number of key combinations in our editor. That's when we rely to which-key, which shows us all the shortcuts available in the context in which we invoke it.

(use-package which-key
  :defer 0
  :config
  (which-key-mode)
  (setq which-key-idle-delay 0.3))

Everything we need to work with git is just a couple of keystrokes away: magit needs no further introduction.

(use-package magit
  :bind ("C-x g" . magit-status))

The following packages help us when using parentheses (if you work with any Lisp you will understand). smartparens automatically completes the pair of parentheses, quotation marks and other symbols that usually go together; rainbow-delimiters shows each pair of parentheses with a distinctive colour, and paren highlights the corresponding pair when we place the cursor over a beginning or ending.

(use-package smartparens
  :hook (prog-mode . smartparens-mode))

(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

(use-package paren
  :config
  (show-paren-mode 1))

The rainbow-mode shows the hexadecimal codes with their respective associated colour, very useful for working with web content and configuration files.

(use-package rainbow-mode
  :defer t
  :hook (org-mode
         emacs-lisp-mode
         web-mode
         c-mode))

The following tools are useful when working on creating web content. simple-httpd is a web server in Emacs, and htmlize allows code snippets to be exported to html while retaining syntax highlighting and other features.

(use-package simple-httpd
  :ensure t)

(use-package htmlize
  :ensure t)

The writeroom-mode mode is very useful when writing long text or code, as it removes all distractions by putting Emacs in full screen mode and centring the text.

(use-package writeroom-mode 
  :bind ("C-c d" . writeroom-mode)
  :config
  (advice-add 'text-scale-adjust :after
              #'visual-fill-column-adjust))

To create templates we will use YASnippet. You can add your own in the directory you specify. A few are included in Terror Emacs, but you can install Andrea Crotti's amazing collection from MELPA.

(use-package yasnippet
  :config
  (setq yas-snippet-dirs '("~/.emacs.d/snippets"))
  (yas-global-mode 1))

Finally, lorem-ipsum allows us to insert random text in Latin, useful for showing examples in presentations or similar stuff.

(use-package lorem-ipsum)

Documents

This is a basic configuration of PDF Tools, a powerful PDF reader. The installation of the package, however, has already been done manually1.

(pdf-loader-install)

(use-package pdf-view-restore
  :after pdf-tools
  :config
  (add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode))

To read e-books in epub format we will use nov.el.

(use-package nov
  :defer t
  :mode ("\\.epub\\'" . nov-mode))

RSS

As a news reader we use elfeed. We can add sources directly in the elfeed.org file placed in the main directory. Terror Emacs includes some sample sources, but you can of course remove them.

(use-package elfeed
  :no-require t
  :bind ("C-x w" . elfeed))

(use-package elfeed-org
  :ensure t
  :after elfeed 
  :config
  (elfeed-org)
  (setq rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org")))

In addition, we will use the very useful arXiv-mode, which will allow us to search and download papers from arXiv very easily.

(use-package arxiv-mode
  :ensure t
  :bind ("C-x x" . arxiv-search)
  :config
  (setq arxiv-default-download-folder "~/Documentos/"))

Org Mode

The ultimate Emacs feature. This is where the magic happens. Let's start with the basic configuration.

(use-package org
  :commands (org-capture org-agenda)
  :bind (("C-c l" . org-store-link)
         ("C-c a" . org-agenda)
         ("C-c c" . org-capture))
  :hook (org-mode . smartparens-mode)
  :config
  (setq org-agenda-files '("~/.agenda.org")
        org-ellipsis " ▾"
        org-fontify-quote-and-verse-blocks t
        org-log-done 'time
        org-capture-bookmark nil
        org-html-validation-link nil
        org-startup-indented t
        org-startup-folded nil)

Some templates for org-agenda.

(setq org-capture-templates
      '(("w" "Weás por hacer" entry (file+headline "~/.agenda.org" "Pendientes")
         "* TODO %?\n%u\n%a\n")
        ("e" "Eventos" entry (file+headline "~/.agenda.org" "Eventos")
         "* EVENT %?\n%T")
        ("f" "Fechas límite" entry (file+headline "~/.agenda.org" "Plazos")
         "* TODO %?\nDEADLINE: %t")
        ("h" "Tareas habituales" entry (file+headline "~/.agenda.org" "Hábitos")
         "* %?\n%T")
        ("d" "Diario" entry (file+datetree "~/Proyectos/org/notas.org")
         "* %?\n%U\n" :clock-in t :clock-resume t)
        ("n" "Notas" entry (file+headline "~/Proyectos/org/notas.org" "Notas")
         "* %?\n%t" :clock-in t :clock-resume t)))

(setq org-todo-keywords
      '((sequence
         "TODO(t)"
         "EVENT(e)"
         "WAIT(w)"
         "CANCELLED(c)"
         "DONE(d)")))

Now we specify the languages we will use with org-babel. The list of available languages can be found here.

(org-babel-do-load-languages
 'org-babel-load-languages
 '((C . t)
   (java . t)
   (python . t)
   (shell . t)
   (latex . t)
   (latex-as-png . t)))
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images)
(setq org-confirm-babel-evaluate nil))

A default configuration for Org-roam, a wonderful knowledge management system based on the Zettelkasten method.

(use-package org-roam
  :ensure t
  :init
  (setq org-roam-v2-ack t)
  :custom
  (org-roam-directory (file-truename "~/Proyectos/org/roam"))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n g" . org-roam-graph)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n c" . org-roam-capture)
         ("C-c n j" . org-roam-dailies-capture-today))
  :config
  (org-roam-setup)
  (require 'org-roam-protocol))

The ox-twbs package allows us to export an org file to a clean and elegant html; ob-latex-as-png speaks for itself: it exports the TeX code of an org file to a png image.

(use-package ox-twbs
  :after org)

(use-package ob-latex-as-png
  :after org)

The following packages are aesthetic, and we will use them to make our presentations look cleaner and neater.

(use-package org-bullets
  :no-require t
  :custom
  (org-bullets-bullet-list '("◉" "●" "○" "●" "○" "●")))

(use-package hide-lines)

And for presentations we will use Org Tree Slide.

(defun terror/slide-setup ()
  (global-hl-line-mode -1)
  (setq org-hide-emphasis-markers t)
  (org-bullets-mode 1)
  (setq text-scale-mode-amount 3)
  (text-scale-mode 1)
  (set-frame-parameter (selected-frame)
                       'internal-border-width 50)
  (org-display-inline-images)
  (toggle-frame-fullscreen)
  (hide-lines-matching "#\\+begin")
  (hide-lines-matching "#\\+end"))

(defun terror/slide-end ()
  (global-hl-line-mode 1)
  (setq org-hide-emphasis-markers nil)
  (org-bullets-mode -1)
  (text-scale-mode -1)
  (set-frame-parameter (selected-frame)
                       'internal-border-width 0)
  (toggle-frame-fullscreen)
  (hide-lines-show-all))

(use-package org-tree-slide
  :after org
  :bind ("C-c p" . org-tree-slide-mode)
  :hook ((org-tree-slide-play . terror/slide-setup)
         (org-tree-slide-stop . terror/slide-end))
  :config
  (setq org-tree-slide-slide-in-effect nil
        org-image-actual-width nil
        org-tree-slide-header t
        org-tree-slide-breadcrumbs " > "
        org-tree-slide-activate-message "Let's begin..."
        org-tree-slide-deactivate-message "The end :)"))

LaTeX

This LaTeX setup is quite simple thanks to AUCTeX. However, we need an installation of some LaTeX version on our machine. This can be done using your favourite package manager. In the case of Debian GNU/Linux, for example: # apt install texlive-full

(use-package latex
  :ensure auctex
  :defer t
  :init
  (server-force-delete)
  :custom
  (TeX-source-correlate-mode t)
  (TeX-source-correlate-start-server t)
  :config
  (setq TeX-view-program-selection '((output-pdf "PDF Tools")))
  (add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer))

Markdown

I don't have much to say. I don't use it, but a basic configuration is provided anyway.

(use-package markdown-mode
  :ensure t
  :commands (markdown-mode gfm-mode)
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode)))

LilyPond

GNU LilyPond is an excellent plain-text system for music notation, allowing us to create sheet music or tablature, from simple to very complex.

(use-package lilypond-mode
  :defer t
  :load-path "var/lisp/lilypond-mode"
  :config
  (setq auto-mode-alist
        (cons '("\\.ly$" . LilyPond-mode) auto-mode-alist))
  (add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))
  (setq LilyPond-command-alist '(("LilyPond" "lilypond %s" "%s" "%l" "View")
                                 ("2PS" "lilypond -f ps %s" "%s" "%p" "ViewPS")
                                 ("Book" "lilypond-book %x" "%x" "%l" "LaTeX")
                                 ("LaTeX" "latex '\\nonstopmode\\input %l'" "%l" "%d" "ViewDVI")
                                 ("View" "open %f")
                                 ("ViewPDF" "open %f")
                                 ("ViewPS" "gv --watch %p")
                                 ("Midi" "")
                                 ("MidiAll" ""))))

Dired

Finally, we configure the powerful directory editor, dired. With it, we can browse and modify directories, visit and manipulate files, etc. With dired-open we can also open files with an external application by specifying the extension and the program to use.

(use-package dired
  :ensure nil
  :defer 1
  :config
  (setq dired-recursive-copies 'always
        dired-listing-switches "--group-directories-first -alh"))

(use-package dired-hide-dotfiles
  :after dired
  :hook (dired-mode . dired-hide-dotfiles-mode)
  :config
  (define-key dired-mode-map "." #'dired-hide-dotfiles-mode))

(use-package dired-open
  :after dired
  :config
  (setq dired-open-extensions '(("mp3" . "mpv")
                                ("mp4" . "mpv")
                                ("mkv" . "mpv")
                                ("png" . "sxiv")
                                ("gif" . "sxiv")
                                ("jpg" . "sxiv")
                                ("jpeg" . "sxiv"))))

Statistics

The final lines show us at Emacs startup how long it takes to start (for Vim users who live in a hurry it seems to be important)…

(add-hook 'emacs-startup-hook
          (lambda ()
            (message "Emacs ready in %s with %d garbage collections."
                     (format "%.2f seconds"
                             (float-time
                              (time-subtract after-init-time before-init-time)))
                     gcs-done)))

…and returns garbage collection to normal.

(setq gc-cons-threshold (* 2 1000 1000))

We have reached the end of the Terror Emacs configuration.

;;; Happy hacking! ;;;

Footnotes:

1

For now we will install PDF Tools from the Debian GNU/Linux repositories (or the repo of your favourite distro) due to conflicts with use-package.


Emacs 27.1 (Org mode 9.3)