Files
dots/files/init.org
2022-01-05 10:17:01 +01:00

25 KiB
Raw Blame History

#+TITLE:emacs configuration

Meta

init.el vs init.org

All changes to the configuration should be done in init.org, not in init.el. Any changes in the init.el will be overwritten by saving init.org. The init.el in this repo should not be tracked by git, and is replaced the first time Emacs is started (assuming it has been renamed to ~/.emacs.d).

To use the tangled init.el, I link it to ~/.emacs.d/init.el:

ln -s ~/dots/files/init.el ~/.emacs.d/init.el

This file replaces itself with the actual configuration at first run.

(require 'org)
(find-file (concat (getenv "HOME") "dots/files/init.org"))
(org-babel-tangle)
(load-file (concat (getenv "HOME") "dots/files/init.el"))

It tangles the org-file, so that this file is overwritten with the actual configuration.

There is no reason to track the init.el that is generated; by running the following command git will not bother tracking it:

git update-index --assume-unchanged init.el

If one wishes to make changes to the repo-version of init.el start tracking again with:

git update-index --no-assume-unchanged init.el

Startup

lexical-binding can improve speed.

;;; -*- lexical-binding: t -*-

Tangle

The init.el should (after the first run) mirror the source blocks in the init.org. We can use C-c C-v t to run org-babel-tangle, which extracts the code blocks from the current file into a source-specific file (in this case a .el-file).

To avoid doing this each time a change is made we can add a function to the after-save-hook ensuring to always tangle and byte-compile the org-document after changes.

(defun tangle-init ()
  (when (equal (buffer-file-name)
               (expand-file-name (concat (getenv "HOME") "/dots/files/init.org")))
    ;; Avoid running hooks when tangling.
    (let ((prog-mode-hook nil))
      (org-babel-tangle))))

(add-hook 'after-save-hook 'tangle-init)

Performance for start-up

A common optimization is to temporarily disable garbage collection during initialization. Here, we set the gc-cons-threshold to a ridiculously large number, and restore the default value after initialization.

(setq gc-cons-threshold most-positive-fixnum)
(add-hook 'emacs-startup-hook
  (lambda ()
    (setq gc-cons-threshold (* 32 1024 1024))))

Configuration

Performance

lsp-mode

Some optimization for lsp-mode

(setq read-process-output-max (* 3 1024 1024))

Scrolling

Disable bidirectional text scanning for a modest performance boost. I've set this to nil in the past, but the bidi-display-reordering's docs say that is an undefined state and suggest this to be just as good:

(setq-default bidi-display-reordering 'left-to-right
              bidi-paragraph-direction 'left-to-right)

Disabling the BPA makes redisplay faster, but might produce incorrect display reordering of bidirectional text with embedded parentheses and other bracket characters whose paired-bracket Unicode property is non-nil. Emacs 27+ only.

(setq bidi-inhibit-bpa t)

Reduce rendering/line scan work for Emacs by not rendering cursors or regions in non-focused windows.

(setq-default cursor-in-non-selected-windows nil)
(setq highlight-nonselected-windows nil)

Emacs "updates" its ui more often than it needs to, so slow it down slightly. Default is 0.5.

(setq idle-update-delay 1.0)

Introduced in Emacs HEAD (b2f8c9f), this inhibits fontification while receiving input, which should help a little with scrolling performance.

(setq redisplay-skip-fontification-on-input t)

General

Super general

Some defaults, which i forget the reason of using it.

(setq make-backup-files nil
      auto-mode-case-fold nil
      auto-save-default nil
      inhibit-startup-screen t
      tramp-default-method "ssh"
      initial-major-mode 'fundamental-mode
      initial-scratch-message nil
      fast-but-imprecise-scrolling t)

Auto revert

Automaticly revert doc-view-buffers when the file changes on disk.

(add-hook 'doc-view-mode-hook 'auto-revert-mode)

Short yes/no

Answering yes and no to each question from Emacs can be tedious, a single y or n will suffice.

(fset 'yes-or-no-p 'y-or-n-p)

Quit prompts

Make ESC quit prompts.

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Soft wrap

(global-visual-line-mode t)

straight.el (Packages)

(setq straight-check-for-modifications 'live)
(defvar bootstrap-version)

(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

Inhibit package.el from loading, as we don't need it.

(setq package-enable-at-startup nil)
(straight-use-package 'use-package)

Keybindings

leader key

general allows me to use key-binds with a leader key, just like vim.

(use-package general
  :straight t
  :init
  (general-create-definer vim-leader-def :prefix "SPC"))

which-key

Show me a cool completion bar at the bottom of the screen, with all possible keybindings.

(use-package which-key
  :straight t
  :init
  (which-key-mode)
  :diminish
  (which-key-mode)
  :config
  (setq which-key-idle-delay 1))

evil-mode

Forgive me, but I'm evil.

(use-package evil
  :straight t
  :bind
  (:map evil-motion-state-map
        ("C-y" . nil))
  (:map evil-insert-state-map
        ("C-y" . nil))
  :init
  ;; so C-z works for background
  (setq evil-toggle-key "C-~"
        evil-want-C-d-scroll t
        evil-want-C-u-scroll t
        evil-want-integration t
        evil-want-keybinding nil)
  :config
  (evil-mode))

(use-package evil-collection
  :straight t
  :after evil
  :config
  (evil-collection-init))

(use-package evil-matchit
  :straight t
  :after evil
  :config
  (global-evil-matchit-mode 1))

Appearance

Fonts

I mainly use these fonts:

  • JuliaMono as main mono-spaced
  • Noto Emoji to show emojis in emacs
  • Noto JP for japanese characters
(set-face-attribute 'default nil :font "JuliaMono" :height 110)
(set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)
(set-fontset-font t 'unicode "Noto Sans Mono CJK JP" nil 'append)

Bars

I don't need ugly ass bars.

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

Parenthesis

Show me the friend of my parenthesis.

(show-paren-mode t)
(setq show-paren-style 'paranthesis)

Line numbers

Show me relative line numbers, when in normal mode and absolute ones, when in insert mode.

(setq-default display-line-numbers 'relative
              display-line-numbers-widen t
              ;; this is the default
              display-line-numbers-current-absolute t)

;; Display absolute numbers, when in normal mode
(defun noct:relative ()
  (setq-local display-line-numbers 'relative))

(defun noct:absolute ()
  (setq-local display-line-numbers t))

(add-hook 'evil-insert-state-entry-hook #'noct:absolute)
(add-hook 'evil-insert-state-exit-hook #'noct:relative)

Theme

Setting my beloved ayu light theme with some icons.

(use-package doom-themes
  :straight (doom-themes :type git :host github :repo "hlissner/emacs-doom-themes"
                                :fork (:host github :repo "CramMK/emacs-doom-themes"))
  :config
  (setq doom-themes-enable-bold t
        doom-themes-enable-italic t)
  (load-theme 'doom-ayu-light t)
  (doom-themes-org-config)
  (doom-themes-treemacs-config))

Modeline

Use doom-modeline as a bar… together with icons and nyan cat!

(use-package doom-modeline
  :straight t
  :config
  (doom-modeline-mode 1)
  (setq doom-modeline-indent-info t
        doom-modeline-buffer-file-name-style 'file-name))

(use-package all-the-icons
  :straight t)

(use-package nyan-mode
  :straight t
  :init
  (nyan-mode)
  (nyan-start-animation)
  ;; (nyan-toggle-wavy-trail)
  :config
  (setq nyan-cat-face-number 4))

Inline colors

Show me color codes as colors! TODO: Disable this in c/c++ mode.

(use-package rainbow-mode
  :straight t
  :hook
  (prog-mode . rainbow-mode))

Whitespaces

Show me those pesky trailing whitespaces… I hate them. Kill them.

(global-whitespace-mode t)
(setq whitespace-style '(face trailing tabs tab-mark))
(add-hook 'before-save-hook 'whitespace-cleanup)

80 column indicator

I only need 80 columns on my 4K display.

(use-package fill-column-indicator
  :straight t
  :defer 1
  :diminish
  (fci-mode)
  :config
  (setq fci-rule-width 1
        fci-rule-column 80
        fci-rule-color "#A6CC70")
  :hook
  (prog-mode . fci-mode)
  (markdown-mode . fci-mode))

File bar

Sometimes I want to see all of my files.

(use-package treemacs
  :straight t
  :defer t
  :config
  (setq treemacs-follow-after-init t
        treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
        treemacs-width 50
        treemacs-project-follow-cleanup t
        treemacs-tag-follow-cleanup t
        treemacs-expand-after-init nil
        treemacs-recenter-after-file-follow t
        treemacs-recenter-after-tag-follow t
        treemacs-tag-follow-delay 1)
  (treemacs-follow-mode t)
  (treemacs-load-theme "Default")
  (dolist (face '(treemacs-root-face
                  treemacs-git-unmodified-face
                  treemacs-git-modified-face
                  treemacs-git-renamed-face
                  treemacs-git-ignored-face
                  treemacs-git-untracked-face
                  treemacs-git-added-face
                  treemacs-git-conflict-face
                  treemacs-directory-face
                  treemacs-directory-collapsed-face
                  treemacs-file-face
                  treemacs-tags-face))
    (set-face-attribute face nil :family "JuliaMono" :height 110))
  :bind
  (:map global-map
    ("C-x t t" . treemacs)))

;; C-c C-p -> projectile
;; C-c C-w -> workspace

(use-package treemacs-evil
  :after (treemacs evil)
  :straight t)

Mini buffers

ivy

Ivy - a generic completion frontend for Emacs. Swiper - isearch with an overview, and more. Oh, man!

(use-package ivy
  :straight t
  :diminish
  :bind (("C-s" . swiper)
         :map ivy-minibuffer-map
         ("TAB" . ivy-alt-done)
         ("C-l" . ivy-alt-done)
         ("C-j" . ivy-next-line)
         ("C-k" . ivy-previous-line)
         :map ivy-switch-buffer-map
         ("C-k" . ivy-previous-line)
         ("C-l" . ivy-done)
         ("C-d" . ivy-switch-buffer-kill)
         :map ivy-reverse-i-search-map
         ("C-k" . ivy-previous-line)
         ("C-d" . ivy-reverse-i-search-kill))
  :config
  (ivy-mode 1))

counsel

Spice up some of those old buffers.

(use-package counsel
  :straight t
  :bind (("M-x" . counsel-M-x)
         ("C-x b" . counsel-ibuffer)
         ("C-x C-f" . counsel-find-file)
         ("C-x C-g" . counsel-git)
         :map minibuffer-local-map
         ("C-r" . 'counsel-minibuffer-history)))

ORG MODE <3

Setup

TODO: split up this box

(use-package org
  :straight t
  ;; C-c C-t org rotate
  :general
  (vim-leader-def 'normal 'global
    "oci" 'org-clock-in
    "oco" 'org-clock-out
    "oa"  'org-agenda
    "oca" 'org-capture
    "oes" 'org-edit-src-code
    "oti" 'org-toggle-inline-images
    "odi" 'org-display-inline-images)
  :hook
  ;; dont make real spaces at the start
  (org-mode . (lambda () (electric-indent-local-mode -1)))
  ;; add virtual spaces
  (org-mode . org-indent-mode)
  :config
  (define-key evil-normal-state-map (kbd "TAB") 'org-cycle)
  (set-face-attribute 'org-document-title nil :weight 'bold :inherit 'default :height 250)
  (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.5)
        org-hidden-keywords '(title)  ; hide title
        org-startup-with-inline-images t
        org-image-actual-width nil  ; rescale inline images
        org-directory "~/org"
        org-agenda-files (quote ("~/org"))
        org-ellipsis " ⮷"
        ;; org-hide-emphasis-markers t  ; hide bold and underline markers
        org-todo-keywords '((sequence "TODO" "PROGRESS" "REVIEW" "|" "DONE"))
        org-todo-keyword-faces '(("TODO" . "#cc241d") ("PROGRESS" . "#a6cc70") ("REVIEW" . "#b16286") ("DONE" . "#abb0b6"))
        org-edit-src-content-indentation 0
        org-log-done nil  ; just mark DONE without a time stamp
        org-log-repeat nil
        org-agenda-start-on-weekday nil  ; my week starts on a monday
        calendar-week-start-day 1
        org-capture-templates
        (quote (("w" "Work" entry (file "~/org/work.org") "* TODO %?\n" :empty-lines-before 1)
                ("u" "University" entry (file "~/org/uni.org") "* TODO %?\n" :empty-lines-before 1)
                ("p" "Personal" entry (file "~/org/personal.org") "* TODO %?\n" :empty-lines-before 1)))
        org-latex-listings 'minted  ; export with code highlighting
        org-latex-packages-alist '(("" "minted"))
        org-latex-pdf-process
        '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

Inline code execution is the shit!

(org-babel-do-load-languages 'org-babel-load-languages '((python . t)
                                                         (shell . t)
                                                         (haskell . t)
                                                         (C . t)
                                                         (dot . t))))

(use-package sage-shell-mode
  :straight t)

(use-package ob-sagemath
  :straight t)

LaTeX Export

For some reason \alert is misinterpreted in LaTeX…

(defun mth/beamer-bold (contents backend info)
  (when (eq backend 'beamer)
    (replace-regexp-in-string "\\`\\\\[A-Za-z0-9]+" "\\\\textbf" contents)))

I also want some special export settings for my .org to .tex.

(use-package ox
  :after org
  :config
  (add-to-list 'org-export-filter-bold-functions 'mth/beamer-bold)
  (add-to-list 'org-latex-logfiles-extensions "tex")
  (setq org-latex-inputenc-alist '(("utf8" . "utf8x"))  ; export unicode as correct latex
        org-latex-default-packages-alist (cons '("mathletters" "ucs" nil) org-latex-default-packages-alist)))

Show me my math equations inline!

(use-package org-fragtog
  :straight t
  :hook
  (org-mode . org-fragtog-mode))

Who needs fancy online tooling anyway…

(use-package graphviz-dot-mode
  :straight t
  :hook
  (graphviz-dot-mode . (lambda () (set-input-method "math")))
  :config
  (setq graphviz-dot-indent-width 4))

Fancy

I want my org-bullets to look fancy, so I'm using some UTF8 chars. Use (setq inhibit-compacting-font-caches t), if performance is low.

(use-package org-superstar
  :straight t
  :after org
  :hook
  (org-mode . org-superstar-mode))

Also the default agenda looks a bit messy.

(use-package org-super-agenda
  :straight t
  :after org
  :config
  (setq org-super-agenda-groups '((:auto-group t)))
  (org-super-agenda-mode))

General programming tools

Indentation

Use some magic heuristics for indentation.

(use-package dtrt-indent
  :straight t
  :hook
  (prog-mode . dtrt-indent-mode)
  (text-mode . dtrt-indent-mode)
  (org-mode . dtrt-indent-mode)
  (markdown-mode . dtrt-indent-mode))

Auto pairs

Auto matching pairs are reaaaaally nice.

(use-package electric-pair
  :config
  (setq electric-pair-open-newline-between-pairs nil)
  :hook
  (prog-mode . electric-pair-mode)
  (text-mode . electric-pair-mode)
  (org-mode . electric-pair-mode)
  (markdown-mode . electric-pair-mode))

Git

magit aka most convenient git client, I've ever used.

(use-package magit
  :straight t
  :general
  (vim-leader-def 'normal 'global
    "gb" 'magit-branch
    "gc" 'magit-checkout
    "gc" 'magit-commit
    "gd" 'magit-diff
    "gg" 'counsel-git-grep
    "gi" 'magit-gitignore-in-topdir
    "gj" 'magit-blame
    "gl" 'magit-log
    "gp" 'magit-push
    "gs" 'magit-status
    "gu" 'magit-pull))

(use-package treemacs-magit
  :after (treemacs magit)
  :straight t)

Highlight todo's

Sometimes, a big red TODO is more intimidating than one with normal text color.

(use-package hl-todo
  :straight t
  :hook
  (prog-mode . hl-todo-mode)
  :config
  (defface hl-todo-TODO
    '((t :background "#cc241d" :foreground "#ffffff"))
    "TODO Face")
  (setq hl-todo-highlight-punctuation ":"
        hl-todo-color-background t
        hl-todo-keyword-faces '(("TODO"  . hl-todo-TODO)
                                ("XXX"   . hl-todo-TODO)
                                ("FIXME" . hl-todo-TODO))))

Code completion

completion

First of all, we need a backend for our completion and analysis.

(use-package company
  :straight t
  :hook
  (lsp-mode . company-mode)
  (prog-mode . company-mode)
  (LaTeX-mode . company-mode)
  (org-mode . company-mode)
  :custom
  (company-minimum-prefix-length 3)
  (company-idle-delay 0.5)
  :bind (:map company-active-map
              ("C-j" . company-select-next-or-abort)
              ("C-k" . company-select-previous-or-abort)
              ("C-l" . company-complete-selection)))

Then we can sprinkle in a fancy front-end for it.

(use-package company-box
  :straight t
  :config
  (setq company-box-doc-delay 2.0
        company-box-max-candidates 10)
  :hook
  (company-mode . company-box-mode))

snippets

completion

Here I use company to display snippet recommendations.

(defun company-mode/backend-with-yas (backend)
  (if (and (listp backend) (member 'company-yasnippet backend))
      backend
    (append (if (consp backend) backend (list backend))
            '(:with company-yasnippet))))

(defun company-mode/add-yasnippet ()
  (setq company-backends (mapcar #'company-mode/backend-with-yas company-backends)))
yasnippet
(use-package yasnippet
  :straight t
  :init
  :bind (:map yas-minor-mode-map
              ("C-y" . yas-expand))
  :hook
  (company-mode . yas-minor-mode)
  (company-mode . company-mode/add-yasnippet))

We also need the actual snippets.

(use-package yasnippet-snippets
  :straight (yasnippet-snippets :type git :host github :repo "AndreaCrotti/yasnippet-snippets"
                                :fork (:host github
                                             :repo "marcothms/yasnippet-snippets"))
  :after yasnippet)

LSP and projects

lsp-mode

lsp-mode is feature-richer than eglot, so I'm using this one.

(use-package lsp-mode :straight t
  :commands (lsp lsp-deferred)
  :init
  (setq lsp-keymap-prefix "C-l")
  :config
  (lsp-enable-which-key-integration t)
  (setq lsp-rust-server 'rust-analyzer
        lsp-auto-guess-root t
        lsp-idle-delay 1
        lsp-enable-file-watchers nil)
  :hook
  (rust-mode . lsp)
  (python-mode . lsp)
  (haskell-mode . lsp)
  (c++-mode . lsp))

In order for lsp-mode to work, it needs to compile code on the fly.

(use-package flycheck
  :straight t
  :after lsp)

tags

tags can be used to search for tagged entities, such as structs etc.

(use-package lsp-ivy
  :straight t
  :after lsp-mode
  :bind(:map lsp-mode-map ("C-l g a" . lsp-ivy-workspace-symbol)))

projects

(use-package projectile
  :straight t
  :after lsp
  :config
  (setq projectile-completion-system 'ivy)
  (projectile-mode +1))

language servers

rust
(use-package rust-mode
  :straight t
  :hook
  (rust-mode . prettify-symbols-mode)
  (rust-mode . (lambda ()
                 (push '("->" . ?→) prettify-symbols-alist)
                 (push '("=>" . ?⇒) prettify-symbols-alist)
                 (push '("!=" . ?≠) prettify-symbols-alist)
                 (push '("<=" . ?≤) prettify-symbols-alist)
                 (push '(">=" . ?≥) prettify-symbols-alist))))
haskell
(use-package haskell-mode
  :straight t
  :hook
  (haskell-mode . interactive-haskell-mode))

(use-package lsp-haskell
  :straight t
  :after lsp
  :hook
  (haskell-mode . lsp)
  (haskell-literate-mode . lsp))
python

Python's lsp has auto configuration for lsp-mode

Input methods

spelling

Sjoe my speling misttakes.

(use-package ispell
  :straight t
  :if (executable-find "hunspell")
  :config
  (setq ispell-program-name "hunspell"
        ispell-dictionary "de_DE,en_GB,en_US")
  (ispell-set-spellchecker-params)
  (ispell-hunspell-add-multi-dic "de_DE,en_GB,en_US")
  :hook
  (org-mode . flyspell-mode)
  (markdown-mode . flyspell-mode)
  (text-mode . flyspell-mode))

math

Who needs LaTeX when you can the power of unicode?

(use-package math-symbol-lists
  :straight t
  :config
  (quail-define-package "math" "UTF-8" "Ω" t)
  (quail-define-rules
   ; Equality and order
   ("<=" ?≤) (">=" ?≥) ("\\prec" ?≺) ("\\preceq" ?≼) ("\\succ" ?≻)
   ("\\succeq" ?≽)
   ("/=" ?≠) ("\\neq" ?≠) ("\\=n" ?≠)("\\equiv" ?≡) ("\\nequiv" ?≢)
   ("\\approx" ?≈) ("\\~~" ?≈) ("\\t=" ?≜) ("\\def=" ?≝)

   ; Set theory
   ("\\sub" ?⊆) ("\\subset" ?⊂) ("\\subseteq" ?⊆) ("\\in" ?∈)
   ("\\inn" ?∉) ("\\:" ?∈) ("\\cap" ?∩) ("\\inter" ?∩)
   ("\\cup" ?) ("\\uni" ?) ("\\emptyset" ?∅) ("\\empty" ?∅)
   ("\\times" ?×) ("\\x" ?×)

   ; Number stuff
   ("\\mid" ?) ("\\infty" ?∞) ("\\sqrt" ?√) ("\\Im" ?) ("\\Re" ?)

   ; Logic
   ("\\/" ?) ("\\and" ?∧) ("/\\" ?∧) ("\\or" ?) ("~" ) ("\neg" )
   ("|-" ?⊢) ("|-n" ?⊬) ("\\bot" ?⊥) ("\\top" ?)
   ("\\r" ?→) ("\\lr" ?↔)
   ("\\R" ?⇒) ("\\Lr" ?⇔)
   ("\\qed" ?∎)

   ; Predicate logic
   ("\\all" ?∀) ("\\ex" ?∃) ("\\exn" ?∄)

   ; functions
   ("\\to" ?→) ("\\mapsto" ?↦) ("\\circ" ?∘) ("\\comp" ?∘) ("\\integral" ?∫)
   ("\\fun" )

   ; Sets of numbers
   ("\\nat" ?) ("\\N" ?) ("\\int" ?) ("\\Z" ?) ("\\rat" ?) ("\\Q" ?)
   ("\\real" ?) ("\\R" ?) ("\\complex" ?) ("\\C" ?) ("\\prime" ?)
   ("\\P" ?)

   ; Complexity
   ("\\bigo" ?𝒪)

   ; Greek
   ("\\Ga" ?α) ("\\GA" ?Α) ("\\a" ?α)
   ("\\Gb" ) ("\\GB" ?Β) ("\\b" )
   ("\\Gg" ?γ) ("\\GG" ) ("\\g" ?γ) ("\\Gamma" )
   ("\\Gd" ) ("\\GD" ) ("\\delta" ) ("\\Delta" )
   ("\\Ge" ) ("\\GE" ?Ε) ("\\epsilon" )
   ("\\Gz" ) ("\\GZ" ?Ζ)
   ("\\Gh" ) ("\\Gh" ?Η) ("\\mu" )
   ("\\Gth" ) ("\\GTH" ) ("\\theta" ) ("\\Theta" )
   ("\\Gi" ?ι) ("\\GI" ?Ι) ("\\iota" ?ι)
   ("\\Gk" ) ("\\GK" ?Κ)
   ("\\Gl" ) ("\\GL" ) ("\\lam" )
   ("\\Gm" ) ("\\GM" Μ) ("\\mu" )
   ("\\Gx" ) ("\\GX" ) ("\\xi" ) ("\\Xi" )
   ("\\Gp" ) ("\\GP" ) ("\\pi" ) ("\\Pi" )
   ("\\Gr" ?ρ) ("\\GR" ?Ρ) ("\\rho" ?ρ)
   ("\\Gs" ?σ) ("\\GS" ) ("\\sig" ?σ) ("\\Sig" )
   ("\\Gt" ) ("\\GT" ?Τ) ("\\tau" )
   ("\\Gph" ) ("\\GPH" ) ("\\phi" ) ("\\Phi" )
   ("\\Gc" ) ("\\GC" ?Χ) ("\\chi" )
   ("\\Gp" ) ("\\GP" ) ("\\psi" )
   ("\\Go" ) ("\\GO" ) ("\\omega" ) ("\\Omega" )
  )
  (mapc (lambda (x)
          (if (cddr x)
              (quail-defrule (cadr x) (car (cddr x)))))
        (append math-symbol-list-superscripts
                math-symbol-list-subscripts)))