Skip to content

My emacs configuration, done in a literate programming fashion using org-mode.

Notifications You must be signed in to change notification settings

shimmy1996/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

My Emacs Config

This is my humble collection of Emacs config, modeled after simplemacs, documented in an hopefully understandable manner. I went from using multiple .org files back to a single one because org-mode is fantastic and my config is not too complicated for a single file to handle (yet).

ModuleFunction
PackagesPackage management.
AestheticsUI and theme.
PluginsLarger scale packages.
Mode SpecificSettings specific to a mode.
EnhancementsPlug-and-play enhancements.

Packages

Manage my package settings.

Package Repositories

Initialize Emacs Package Manager and add repositories.

(package-initialize)
(require 'package)
(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                    (not (gnutls-available-p))))
       (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
      (add-to-list 'package-archives (cons "melpa" url) t))
(when (< emacs-major-version 24)
  ;; For important compatibility libraries like cl-lib
  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))

Setup use-package

Bootstrap use-package so that package requirements can be handled in separate sections.

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

Aesthetics

Mostly aesthetics and quality of life changes.

80 Character Limit

Set fill-column to 80 characters.

(setq-default fill-column 80)

Highlight portions of line over 80 characters in prog-mode.

(require 'whitespace)
(setq whitespace-line-column 80)
(setq whitespace-style '(face empty tabs lines-tail trailing))
(add-hook 'prog-mode-hook 'whitespace-mode)

Auto Detect File Changes

Enable auto revert mode to auto-refresh when files have changed on disk.

(global-auto-revert-mode t)

Color Themes

Install base16-theme and enable gruvbox dark pale.

(use-package base16-theme
  :ensure t
  :config
  (load-theme 'base16-gruvbox-dark-pale t))

Customize Settings in Separate File

Save customized settings in a separate file than init.el. Create the customization file if none found.

(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(unless (file-exists-p custom-file)
  (write-region "" "" custom-file))
(load custom-file)

Fcitx

Install fcitx support.

(use-package fcitx
  :ensure t
  :init
  (fcitx-aggressive-setup)
  (setq fcitx-use-dbus t))

Daemon Support

If using Emacs daemon with systemd, remember to add to the .service file:

Environment="LC_CTYPE=zh_CN.UTF-8" "XMODIFIERS=@im=fcitx"

It would also help to change the default command for emacs into:

emacsclient -c -a emacs

Font Settings

Default Fonts

Specify font settings.

(defvar user/cjk-font "Noto Sans CJK SC"
  "Default font for CJK characters.")

(defvar user/latin-font "Iosevka Term SS09"
  "Default font for Latin characters.")

(defvar user/unicode-font "Symbola"
  "Default font for Unicode characters, including emojis.")

(defvar user/font-size 17
  "Default font size in px.")

(defvar user/standard-fontset
  (create-fontset-from-fontset-spec standard-fontset-spec)
  "Standard fontset for user.")

;; Ensure user/standard-fontset gets used for new frames.
(add-to-list 'default-frame-alist (cons 'font user/standard-fontset))
(add-to-list 'initial-frame-alist (cons 'font user/standard-fontset))

CJK Font Scaling

Ensure CJK fonts scales correctly to twice the width of mono-space half-width characters. I tried to add something similar for Unicode fonts, but found that they don’t have uniform width anyways (not to mention that not all of them are full-width), rendering this method useless.

I think CJK fonts have less granular sizing controls, i.e. the actual glyph size of size 16 and size 17 are in fact the same and only starts actually increasing after we hit size 18.

(defvar user/cjk-font-scale
  '((16 . 1.0)
    (17 . 1.1)
    (18 . 1.0))
  "Scaling factor to use for cjk font of given size.")

;; Specify scaling factor for CJK font.
(setq face-font-rescale-alist
      (list (cons user/cjk-font
                  (cdr (assoc user/font-size user/cjk-font-scale)))))

Fontset with CJK and Unicode Fallback

To ensure fontset gets correctly configured, I simply created one from scratch. This is because emacsclient seems to have a different dynamic when creating startup-fontset and no other method guarantees consistent behavior between emacs and emacsclient.

Use C-u C-x = to examine the font used for a specific character and use describe-fontset to check if our changes went through.

;; Enable font customization for charset 'symbols, which contains puncuation
;; marks, emoji, etc.
(setq use-default-font-for-symbols nil)

(defun user/set-font ()
  "Set Unicode, Latin and CJK font for user/standard-fontset."
  ;; Unicode font.
  (set-fontset-font user/standard-fontset 'unicode
                    (font-spec :family user/unicode-font)
                    nil 'prepend)
  ;; Latin font.
  ;; Only specify size here to allow text-scale-adjust work on other fonts.
  (set-fontset-font user/standard-fontset 'latin
                    (font-spec :family user/latin-font :size user/font-size)
                    nil 'prepend)
  ;; CJK font.
  (dolist (charset '(kana han cjk-misc hangul kanbun bopomofo))
    (set-fontset-font user/standard-fontset charset
                      (font-spec :family user/cjk-font)
                      nil 'prepend))
  ;; Special settings for certain CJK puncuation marks.
  ;; These are full-width characters but by default uses half-width glyphs.
  (dolist (charset '((#x2018 . #x2019)    ;; Curly single quotes "‘’"
                     (#x201c . #x201d)))  ;; Curly double quotes "“”"
    (set-fontset-font user/standard-fontset charset
                      (font-spec :family user/cjk-font)
                      nil 'prepend)))

;; Apply changes.
(user/set-font)
;; For emacsclient.
(add-hook 'before-make-frame-hook #'user/set-font)

Line Highlighting

Enable line highlighting.

(global-hl-line-mode t)

Line Numbering

Use display-line-numbers instead of linum. Enable relative line numbering, and set minimum width to 3.

(setq-default display-line-numbers-type (quote relative))
(setq-default display-line-numbers-width 3)
(global-display-line-numbers-mode)

Line Wrapping

Enable line wrapping by default.

(global-visual-line-mode t)

No Tabs

Use spaces for indenting.

(setq-default indent-tabs-mode nil)

For those that uses tab, set width to 4.

(setq-default tab-width 4)

Parenthesis Highlighting

Highlight matching parenthesis.

(show-paren-mode t)

Rainbow Delimiters

rainbow-delimiters is a “rainbow parentheses”-like mode which highlights delimiters such as parentheses, brackets or braces according to their depth.

Install rainbow-delimiters and enable it for prog-mode.

(use-package rainbow-delimiters
  :ensure t
  :init (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))

Remove Trailing Whitespace

Remove trailing whitespace upon saving.

(add-hook 'before-save-hook 'delete-trailing-whitespace)

Save Backups Elsewhere

Save *~ backups in $(pwd)/.bak.

(setq backup-directory-alist
      '(("." . ".bak"))
      )

Show Column Number

(setq column-number-mode t)

Smooth Scrolling

Sublimity

(use-package sublimity
  :ensure t
  :config
  (require 'sublimity-scroll)
  (require 'sublimity-map)
  (sublimity-global-mode))

Smooth

(use-package smooth-scrolling
  :ensure t
  :config (smooth-scrolling-mode 1))

UI Settings

*bars

Hide menu, scrollbar and toolbars.

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

New Frame Scrollbar

Remove scrollbar for any new frames as well, useful for emacsclient.

(defun user/disable-scroll-bars (frame)
  (modify-frame-parameters frame
                           '((vertical-scroll-bars . nil)
                             (horizontal-scroll-bars . nil))))
(add-hook 'after-make-frame-functions 'user/disable-scroll-bars)

Half screen fix

Fills up gap in the border when tiling Emacs to half-screen.

(setq frame-resize-pixelwise t)

Zoom In

Use mouse wheel to adjust zoom level.

(global-set-key [C-mouse-4] 'text-scale-increase)
(global-set-key [C-mouse-5] 'text-scale-decrease)

Plugins

Larger scale packages that either requires more configuration, or fundamentally changes how Emacs behave. Because these package configurations is a lot more complex and may be spread out, any subtree that depends on packages in this section will have a tag to mark the dependency.

Ivy

Flexible, simple tools for minibuffer completion in Emacs.

Ivy, a generic completion mechanism for Emacs. Counsel, a collection of Ivy-enhanced versions of common Emacs commands. Swiper, an Ivy-enhanced alternative to isearch.

Installation

(use-package ivy
  :ensure t
  :init
  (setq enable-recursive-minibuffers t)
  (ivy-mode 1)
  :config
  ;; Show recents and bookmarks in find-file.
  (setq ivy-use-virtual-buffers t)
  ;; Use Enter to navigate into the directory, not open it with dired.
  (define-key ivy-minibuffer-map (kbd "C-m") 'ivy-alt-done)
  ;; Use C-l to go back one level.
  (define-key ivy-minibuffer-map (kbd "C-l") 'ivy-backward-delete-char)
  :bind
  (("C-c C-r" . ivy-resume)))
(use-package counsel
  :ensure t
  :bind
  (("M-x"     . counsel-M-x)
   ("M-y"     . counsel-yank-pop)
   ("C-c c f" . counsel-git)
   ("C-c c s" . counsel-git-grep)
   ("C-x C-f" . counsel-find-file)
   ("C-x r b" . counsel-bookmark)
   ("C-h a"   . counsel-apropos)
   ("C-h f"   . counsel-describe-function)
   ("C-h v"   . counsel-describe-variable)
   ("C-h l"   . counsel-find-library)
   ("C-h b"   . counsel-descbinds)
   ("C-h i"   . counsel-info-lookup-symbol)
   ("<f2> u"  . counsel-unicode-char)))
(use-package swiper
  :ensure t
  :bind
  (("C-s"     . swiper)))

Integration

Integration with magit and projectile.

(setq magit-completing-read-function 'ivy-completing-read)
(setq projectile-completion-system 'ivy)

Helm

Stolen from Admiral Akber’s config.

Install

Helm is incredible, it really supercharges emacs. It’s a framework for incremental searching / completion / narrowing down options. Sounds simple, and it is in application, and it’s so worth it.

Web: https://emacs-helm.github.io/helm/ Git: https://github.com/emacs-helm/helm

(use-package helm
  :ensure t
  :init (helm-mode t))
(require 'helm-config)

Visual customization

I want helm to automatically resize and appear in the current buffer only.

(setq helm-autoresize-mode 1)
(setq helm-split-window-in-side-p t)

Fuzzy matching

Fuzzy matching works most of the time, it does seem to have the issue of only matching forward i.e. “machine snow” will not match with “snow machine”.

It does make it a lot easier to search through Emacs functions though as you only need to remember one part of the function name.

;; Enable Fuzzy Matching
(setq helm-recentf-fuzzy-match       t
      helm-buffers-fuzzy-matching    t
      helm-recentf-fuzzy-match       t
      helm-buffers-fuzzy-matching    t
      helm-locate-fuzzy-match        t
      helm-apropos-fuzzy-match       t
      helm-lisp-fuzzy-completion     t
      helm-candidate-number-limit    250)

Keybindings

Above defaults overides such as M-x these are custom bindings.

Self help

The Emacs culture is to have great documentation with your functions, all searchable via apropos. Helm provides a nice interface to this, use it often.

(global-set-key (kbd "C-h a") 'helm-apropos)
(global-set-key (kbd "C-h i") 'helm-info-emacs)

Buffers and files

Buffers and files are an obvious case where helm is very useful.

(global-set-key (kbd "C-x b")   'helm-mini)
(global-set-key (kbd "C-x C-b") 'helm-buffers-list)
(global-set-key (kbd "M-x")     'helm-M-x)
(global-set-key (kbd "C-x C-f") 'helm-find-files)
(global-set-key (kbd "C-x C-r") 'helm-recentf)
(global-set-key (kbd "C-x r l") 'helm-filtered-bookmarks)

Advanced editing

Kill ring memory, grepping, etc, all gorgeous with helm.

(global-set-key (kbd "M-y")     'helm-show-kill-ring)
(global-set-key (kbd "C-x c g") 'helm-do-grep)
(global-set-key (kbd "C-x c o") 'helm-occur)

The overloaded tab key

The good ol’ TAB key is used for a lot, in this case I want to make sure that when used in helm that it completes in helm, not attempting to insert a snippet or something.

(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)

Also, the following makes sure that tab works when running in terminal mode:

(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)

This requires fixing the select other actions which IIRC is set to C-i by default.

(define-key helm-map (kbd "C-z") 'helm-select-action)

Company

Auto completion of everything with nice backends.

Installation

Install company and enable it globally.

(use-package company
  :ensure t
  :init (global-company-mode))

Tweaks

Adjust Delay

Set delay for auto-completion. 0 would be too extreme and wastes CPU clocks apparently.

(setq company-idle-delay 0.01)
(setq company-minimum-prefix-length 2)

Align Annotation

Flush annotation on candidates to the right.

(setq company-tooltip-align-annotations t)

Tooltip Documentation

Install dependency pos-tip.

(use-package pos-tip
  :ensure t)
(require 'pos-tip)

Install company-quickhelp and set delay, FG/BG colors, max lines.

(use-package company-quickhelp
  :ensure t
  :init
  (company-quickhelp-mode t)
  (setq company-quickhelp-delay 0.01)
  (setq company-quickhelp-color-background "#262626")
  (setq company-quickhelp-color-foreground "#ebdbb2")
  (setq company-quickhelp-max-lines 20)
  (setq company-quickhelp-use-propertized-text t))

Backend Configurations

company-auctex

Install company-auctex and add it to company-backends. This is for acutex macro completion. Adding backends is handled by company-auctex-init.

(use-package company-auctex
  :ensure t
  :init
  (company-auctex-init))
Workaround To Enable Completion in Org Mode
:config
(defun company-auctex-prefix (regexp)
  "Returns the prefix for matching given REGEXP in org-mode and latex-mode."
  (and (or (derived-mode-p 'latex-mode) (derived-mode-p 'org-mode))
       (when (looking-back regexp)
         (match-string-no-properties 1)))))

company-math

Install company-math and add it to company-backends.

Unicode Symbols

Enable unicode symbol backend globally.

(use-package company-math
  :ensure t)
;;  :init (add-to-list 'company-backends
;;                     '(company-math-symbols-unicode)))
Math Symbols

Enable math symbol backend only in TeX-mode and org-mode.

(defun user/company-math-init()
  (setq-local company-backends
              (append '((company-math-symbols-latex
                         ;;company-math-symbols-unicode
                         company-auctex-macros
                         company-auctex-symbols
                         company-auctex-environments))
                      company-backends)))

(add-hook 'TeX-mode-hook 'user/company-math-init)
(add-hook 'org-mode-hook 'user/company-math-init)

company-anaconda

Install company-anaconda and add it to company-backends.

(use-package company-anaconda
  :ensure t
  :init (add-to-list 'company-backends
                     'company-anaconda))

company-go

Auto complete for go. This relies on gocode to be installed using go get. Either install from github.com/mdempsky/gocode or github.com/stamblerre/gocode (supports go-modules).

(use-package company-go
  :ensure t
  :init (add-to-list 'company-backends
                     'company-go))

company-lsp

Company completion via company-lsp. lsp-mode will add the appropriate backend.

(use-package company-lsp
  :ensure t)

company-yasnippet

Add company-yasnippet backend for yasnippet key completion.

(defun user/enable-yas-for-backend (backend)
  "Add yasnippet support for specified BACKEND."
  (if (and (listp backend) (member 'company-yasnippet backend))
      backend
    (append (if (consp backend) backend (list backend))
            '(:with company-yasnippet))))

;; Enable for all company backends. Add to hook to prevent missed backends.
(add-hook 'yas-minor-mode-hook
          (lambda()
            (setq company-backends
                  (mapcar #'user/enable-yas-for-backend company-backends))))

yasnippet Conflict

Pressing tab with company mode conflicts with yasnippets, this is the only fix that I found that makes everything work as expected. Make sure this is placed after backend settings.

(defun user/check-expansion()
  (save-excursion
    (if (looking-at "\\_>") t
      (backward-char 1)
      (if (looking-at "\\.") t
        (backward-char 1)
        (if (looking-at "->") t nil)))))

(defun user/do-yas-expand()
  (let ((yas-fallback-behavior 'return-nil))
    (yas-expand)))

(defun user/tab-indent-or-complete()
  (interactive)
  (if (minibufferp)
      (minibuffer-complete)
    (if (or (not yas-minor-mode)
            (null (user/do-yas-expand)))
        (if (user/check-expansion)
            (company-complete-common)
          (indent-for-tab-command)))))

(global-set-key (kbd "TAB") 'user/tab-indent-or-complete)

Flycheck

Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs, intended as replacement for the older Flymake extension which is part of GNU Emacs.

Installation

Install flycheck.

(use-package flycheck
  :ensure t
  :init (global-flycheck-mode))

Set C++ Standard

Use c++20 as the C++ standard.

(add-hook 'c++-mode-hook
          (lambda () (progn
                       (setq flycheck-cppcheck-standards '("c++20"))
                       (setq flycheck-clang-language-standard "c++20")
                       (setq flycheck-gcc-language-standard "c++20"))))

Set Google C++ Syntax Checker

Install flycheck-google-cpplint

Add Google C++ Style checker for flycheck (Now deprecated, using local copy). On Arch Linux, if using AUR package cpplint, need to modify command in flycheck-google-cpplint.el to use cpplint instead of cppling.py.

(use-package flycheck-google-cpplint
  :load-path "local/flycheck-google-cpplint/"
  :config
  (eval-after-load 'flycheck
    '(progn
       (require 'flycheck-google-cpplint)
       ;; Add Google C++ Style checker.
       ;; In default, syntax checked by Clang and Cppcheck.
       ;; Use Google Checker after errors are cleared
       (flycheck-add-next-checker 'c/c++-cppcheck
                                  '(error . c/c++-googlelint)))))

Set Checker Parameters

Set various parameters for the checker.

(custom-set-variables
 '(flycheck-googlelint-verbose "5")
 '(flycheck-googlelint-filter "-legal/copyright,-whitespace/braces")
 '(flycheck-googlelint-linelength "80"))

Proselint

A linter for prose, checks grammar and style errors. Setting from here.

(flycheck-define-checker proselint
  "A linter for prose."
  :command ("proselint" source-inplace)
  :error-patterns
  ((warning line-start (file-name) ":" line ":" column ": "
            (id (one-or-more (not (any " "))))
            (message) line-end))
  :modes (text-mode markdown-mode gfm-mode org-mode))

(add-to-list 'flycheck-checkers 'proselint)

Yasnippet

YASnippet is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates.

Installation

Install yasnippet. Load yasnippet when yas-minor-mode is called and add the hook for yas-minor-mode for programming modes. Reload the snippets on start up.

(require 'cl)
(use-package yasnippet
  :ensure t
  :commands (yas-minor-mode)
  :init (yas-global-mode)
  :config (yas-reload-all))

Install yasnippet-snippets

yasnippet-snippets is a collection of snippets for many langulages.

(use-package yasnippet-snippets
  :ensure t)

Mode Specific

Settings specific to a mode or defines a new mode that often specializes Emacs for a certain programming language.

Auctex

auctex is an extensible package for writing and formatting TEX files in GNU Emacs.

Installation

Need to use defer as auctex.el does not actually provide auctex feature.

(use-package auctex
  :defer t
  :ensure t)

Automatic Parsing

Enable auctex to automatically parse buffer information.

(setq TeX-parse-self t)
(setq TeX-auto-save t)
(setq TeX-save-query nil)

Master File Detection

Let auctex figure out the master file for TeX document spread over many files.

(setq-default TeX-master nil)

Spell Checking

Spell checking with flyspell.

(add-hook 'LaTeX-mode-hook 'flyspell-mode)

Enable reftex

Turn on RefTeX Mode for all LaTeX files. This enables you to jump via table of contents. The key to invoke this is C-c =.

(add-hook 'LaTeX-mode-hook 'turn-on-reftex)   ; with AUCTeX LaTeX mode

Enable LaTeX-math-mode

Enable LaTeX Math mode. This allows macro insertion following `. Not exactly useful since we already have company.

(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)

Auto-complete Sub/Superscripts

Insert braces after _ or ^.

(setq TeX-electric-sub-and-superscript t)

C/C++-mode

Default Indention

Set default indention level to 4 and style to “linux”(do not indent braces).

(setq-default c-default-style "linux"
              c-basic-offset 4)

Google Style

Google’s C/C++ style for c-mode.

Installation

(use-package google-c-style
  :ensure t
  :init
  (add-hook 'c-mode-common-hook 'google-set-c-style)
  (add-hook 'c-mode-common-hook 'google-make-newline-indent))

Treat .h as C++

Identify .h files as C++ files instead of C. To enable c++-mode manually, type M-x c\+\+-mode.

(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

Clang-format

Installation

Install and set hot keys for formatting.

(use-package clang-format
  :ensure t
  :init
  (global-set-key (kbd "C-c i") 'clang-format-region)
  (global-set-key (kbd "C-c u") 'clang-format-buffer))

Set code style

Use Google’s C++ style.

(custom-set-variables '(clang-format-style "file"))

Doxygen Highlighting

Add highlighting for doxygen blocks.

(use-package highlight-doxygen
  :ensure t
  :init
  (add-hook 'c-mode-common-hook 'highlight-doxygen-mode))

CMake-mode

Syntax highlighting and indention for CMakeLists.txt.

(use-package cmake-mode
  :ensure t)

Eldoc Support

Eldoc for CMake.

(use-package eldoc-cmake
  :ensure t
  :hook (cmake-mode . eldoc-cmake-enable))

Extended syntax highlighting

Additional syntax highlighting for CMake. For some reason manual activation is still required.

(use-package cmake-font-lock
  :ensure t
  :init (autoload 'cmake-font-lock-activate "cmake-font-lock" nil t)
  :hook (cmake-mode . cmake-font-lock-activate))

ESS

Use ESS (Emacs Speaks Statistics) for R and Julia support.

(use-package ess
  :ensure t
  :config
  ;; Add latex symbol completion in julia buffer mode as well.
  (add-hook 'ess-julia-mode-hook
        (lambda()
          (add-hook 'completion-at-point-functions
                    'ess-julia-latexsub-completion nil 'local)))
  (add-hook 'ess-mode-hook
            (lambda () (ess-set-style 'RStudio)))
  (setq tab-always-indent 'complete))

Auto Format R Code

Use the styler R package to format buffer or region. Modeled after yapfify.

(defun user/r-format-call-bin (input-buffer output-buffer beginning end)
  "Format specified region in INPUT-BUFFER saving the output to OUTPUT-BUFFER.

BEGINNING and END specify region to format."
  (with-current-buffer input-buffer
    (write-region beginning end "r-format-temp.R"))
  (call-process "R" nil nil nil "-e"
                "library(styler);style_file(\"r-format-temp.R\")")
  (with-current-buffer output-buffer
    (insert-file-contents "r-format-temp.R" nil nil nil t))
  (with-current-buffer input-buffer
    (delete-region beginning end)
    (insert-buffer-substring output-buffer))
  (delete-file "r-format-temp.R"))

(defun user/r-format-region (beginning end)
  "Try to r-format the current region.

Output from R is stored in *r-format*."
  (interactive "r")
  (let* ((original-buffer (current-buffer))
         (original-point (point))  ; Because we are replacing text, save-excursion does not always work.
         (buffer-windows (get-buffer-window-list original-buffer nil t))
         (original-window-pos (mapcar 'window-start buffer-windows))
         (tmpbuf (generate-new-buffer "*r-format*"))
         (r-output (user/r-format-call-bin original-buffer tmpbuf beginning end)))
    (deactivate-mark)
    ;; Clean up tmpbuf
    (kill-buffer tmpbuf)
    ;; restore window to similar state
    (goto-char original-point)
    (mapcar* 'set-window-start buffer-windows original-window-pos)))

(defun user/r-format-buffer ()
  "Format whole buffer."
  (interactive)
  (user/r-format-region (point-min) (point-max)))

Auto format bindings for ess-r-mode. Need a keybinding as auto formatting doesn’t seem to work for org-mode src blocks.

(defun user/r-format-before-save ()
  "Runs r-format on current buffer if in ess-r-mode."
  (interactive)
  (when (eq major-mode 'ess-r-mode) (user/r-format-buffer)))

(add-hook 'ess-r-mode-hook
          (lambda () (local-set-key (kbd "C-c u") 'user/r-format-buffer)))

(add-hook 'before-save-hook 'user/r-format-before-save)

Lsp-mode

Use Language Server Protocol (LSP) for code completion, jump to definition, etc. Check list of language servers and install needed ones. Note that the Python language server also requires autopepe8 and pydocstyle.

Installation

(use-package lsp-mode
  :ensure t
  :init
  ;; (add-hook 'prog-mode-hook #'lsp)
  (setq lsp-prefer-flymake nil)
  :config
  (setq lsp-keymap-prefix "C-c p")
  (add-to-list 'lsp--formatting-indent-alist
               '(ess-r-mode . ess-indent-offset))
  :bind-keymap
  ("C-c p" . lsp-command-map))

Flycheck Integration

Flycheck integration via lsp-ui.

(use-package lsp-ui
  :ensure t
  :init
  (add-hook 'lsp-mode-hook 'lsp-ui-mode)
  (setq lsp-ui-flycheck-enable t))

Go-mode

Remember to set $GOPATH environment variable and add $GOPATH/bin to $PATH.

Go-mode

(use-package go-mode
  :ensure t
  :init
  (add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode))
  (add-hook 'before-save-hook 'gofmt-before-save))

go-guru

Helpful code analysis tool, requires golang.org/x/tools/cmd/guru.

(use-package go-guru
  :ensure t)

Julia-mode

Julia-mode

Official major mode for julia. This is required as a dependency for ess-julia-mode.

(use-package julia-mode
  :ensure t)

Flycheck Support

Flycheck support via flycheck-julia. This relies on Lint.jl, which doesn’t have a release yet for Julia 1.0. A work around is to give the repository URL to Pkg instead of the package name and fix 1.0 incompatibilities as they show up.

(use-package flycheck-julia
  :ensure t
  :init
  (add-hook 'ess-julia-mode-hook #'flycheck-julia-setup))

Better REPL

This is a minor mode for interacting with a Julia REPL running inside Emacs.

(use-package julia-repl
  :ensure t
  :init
  (with-eval-after-load 'julia-mode
    (add-hook 'flycheck-mode-hook #'flycheck-julia-setup)))

Org-mode

org-mode specific settings.

Allow Alphabetical Ordering

Allows the use of “a.” or “b)” in ordered lists.

(setq org-list-allow-alphabetical t)

Global Keybindings

Set up keybindings for global access.

(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cc" 'org-capture)
(global-set-key "\C-cb" 'org-switchb)

Formatting

Emphasis Boundary Regex

Allow non-ASCII characters (CJK characters for instance) to be boundaries for Org emphasis markers. This need to happen before org-mode is loaded.

(use-package org
  :init
  (setq org-emphasis-regexp-components
        (list (concat " \t('\"{"            "[:nonascii:]")  ;; prematch
              (concat "- \t.,:!?;'\")}\\["  "[:nonascii:]")  ;; postmatch
              " \t\r\n,\"'"                                  ;; border
              "."                                            ;; body-regexp
              1)))                                           ;; newline

Set Link Format

Do not collapse the links.

(org-toggle-link-display)

Subtree Indention

Do not change text indention when promoting/demoting subtrees.

(setq org-adapt-indentation nil)

Truncate Lines by Default

Automatically enable truncated lines when starting org-mode.

(setq-default org-startup-truncated t)

Turn Off auto-fill

Disable auto-fill-mode when in org-mode.

(add-hook 'org-mode-hook 'turn-off-auto-fill)

Display Inline Images

Display inline images for org-babel execution results.

(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
(add-hook 'org-mode-hook 'org-display-inline-images)

Protect Folded Regions

Don’t allow editing of folded regions

(setq org-catch-invisible-edits 'error)

Enforce TODO Dependencies

Parent tasks should not be marked DONE until all subtasks are marked as DONE.

(setq org-enforce-todo-dependencies t)

Highlight LaTeX Related Syntax

Non-nil means highlight LaTeX related syntax in the buffer. When non nil, the value should be a list containing any of the following symbols:

  • `latex’ Highlight LaTeX snippets and environments.
  • `script’ Highlight subscript and superscript.
  • `entities’ Highlight entities.
(eval-after-load 'org
  '(setf org-highlight-latex-and-related '(latex)))

Default Image Size

In LaTeX export, the default image size is width.9\linewidth=, which is way too large. Setting this to empty allows images to retain it’s original size.

(setq org-latex-image-default-width ".6\\linewidth")

Enable spell checking

Spell checking with flyspell-mode. Would need to install dictionary lib like aspell in base system.

(add-hook 'org-mode-hook 'flyspell-mode)

Enable Code Evaluation

Enable evaluation of various languages in org-mode.

(defvar user/org-babel-enabled-languages
  '(emacs-lisp
    python
    R
    org)
  "Extra languages user can execute in org-babel code blocks.")

(org-babel-do-load-languages
 'org-babel-load-languages
 (mapcar
  (lambda (arg) (cons arg t))
  user/org-babel-enabled-languages))

There is no need to confirm execution for these languages.

(defvar user/org-babel-no-confirm-languages
  '(emacs-lisp
    python
    R
    latex-macros
    org)
  "Languages that do not user confirmation to execute")

(setq org-confirm-babel-evaluate
      (lambda (lang body)
        (not (member lang
                     (mapcar (lambda (arg) (symbol-name arg))
                             user/org-babel-no-confirm-languages)))))

Exporter Backends

HTML

Do not export validation link.

(setq org-html-validation-link nil)

Markdown (Blackfriday)

An Org exporter backend that exports Org to Hugo-compatible Markdown (Blackfriday) and generates the front-matter (in TOML or YAML format).

Installation

Enable ox-hugo as an option for exporting.

(use-package ox-hugo
  :ensure t
  :init (with-eval-after-load 'ox (require 'ox-hugo)))
Export Key Bindings

Wrap key bindings in <kbd>.

(setq org-hugo-use-code-for-kbd t)

Pandoc

This is another exporter for org-mode that translates Org-mode file to various other formats via Pandoc.

Installation
(use-package ox-pandoc
  :ensure t)

Jupyter Notebook

Export backend for .ipynb. Package is not in MELPA yet, so using local copy. Repository is located here.

(use-package ox-ipynb
  :load-path "local/ox-ipynb/")

Quick and easy hack to get python source blocks to work.

(setq ox-ipynb-kernelspecs
      '((ipython . (kernelspec . ((display_name . "Python 3")
                                  (language . "python")
                                  (name . "python3"))))
        (python . (kernelspec . ((display_name . "Python 3")
                                 (language . "python")
                                 (name . "python3"))))
        (R . (kernelspec . ((display_name . "R")
                            (language . "R")
                            (name . "ir"))))
        (julia . (kernelspec . ((display_name . "Julia 0.6.0")
                                (language . "julia")
                                (name . "julia-0.6"))))))

(setq ox-ipynb-language-infos
      '((ipython . (language_info . ((codemirror_mode . ((name . ipython)
                                                         (version . 3)))
                                     (file_extension . ".py")
                                     (mimetype . "text/x-python")
                                     (name . "python")
                                     (nbconvert_exporter . "python")
                                     (pygments_lexer . "ipython3")
                                     (version . "3.5.2"))))
        (python . (language_info . ((codemirror_mode . ((name . ipython)
                                                        (version . 3)))
                                    (file_extension . ".py")
                                    (mimetype . "text/x-python")
                                    (name . "python")
                                    (nbconvert_exporter . "python")
                                    (pygments_lexer . "ipython3")
                                    (version . "3.5.2"))))
        (R . (language_info . ((codemirror_mode . "r")
                               (file_extension . ".r")
                               (mimetype . "text/x-r-source")
                               (name . "R")
                               (pygments_lexer . "r")
                               (version . "3.3.2"))))
        (julia . (language_info . ((codemirror_mode . "julia")
                                   (file_extension . ".jl")
                                   (mimetype . "text/x-julia")
                                   (name . "julia")
                                   (pygments_lexer . "julia")
                                   (version . "0.6.0"))))))

LaTeX

LaTeX Macros

Support LaTeX macros in both LaTeX and HTML/MathJax export. We do this by adding a dummy language to Babel. Idea comes form here.

(add-to-list 'org-src-lang-modes '("latex-macros" . latex))

(defvar org-babel-default-header-args:latex-macros
  '((:results . "raw")
    (:exports . "results")))

(defun user/prefix-all-lines (pre body)
  (with-temp-buffer
    (insert body)
    (string-insert-rectangle (point-min) (point-max) pre)
    (buffer-string)))

(defun org-babel-execute:latex-macros (body _params)
  (concat
   (user/prefix-all-lines "#+LATEX_HEADER: " body)
   "\n#+HTML_HEAD_EXTRA: <div style=\"display: none\"> \\(\n"
   (user/prefix-all-lines "#+HTML_HEAD_EXTRA: " body)
   "\n#+HTML_HEAD_EXTRA: \\)</div>\n"))
LaTeX Preview Scaling

Default size is a bit small. Also note that the fullpage package can cause preview images to become really tall. Use dvisvgm backend for clearer image.

(plist-put org-format-latex-options :scale 1.75)
(setq org-latex-create-formula-image-program 'dvisvgm)
Code Listing

Use minted for code listings. Relies on pygments for syntax highlighting.

(setq org-latex-listings 'minted)
(setq org-latex-minted-options
      '(("frame" "single")
        ("fontsize" "\\scriptsize")))
(add-to-list 'org-latex-packages-alist '("" "minted" nil))
SVG Support

Use svg for supporting SVGs. Requires inkscape to be installed.

(add-to-list 'org-latex-packages-alist '("" "svg" nil))
Shell Escape

This is required for minted and svg to work.

(setq org-latex-pdf-process
      '("%latex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"))

Python-mode

Enhancements to python-mode.

Anaconda Mode

Code navigation, documentation lookup and completion for Python.

(use-package anaconda-mode
  :ensure t
  :init
  (add-hook 'python-mode-hook 'anaconda-mode)
  (add-hook 'python-mode-hook 'anaconda-eldoc-mode))

Auto Format

black

Use black to auto format python buffers on save.

(use-package blacken
  :ensure t
  :init
  (add-hook 'python-mode-hook 'blacken-mode))

isort

Use isort to sort imports.

(use-package isortify
  :ensure t
  :init
  (add-hook 'python-mode-hook 'isortify-mode)
  (setq isortify-multi-line-output 3)
  (setq isortify-trailing-comma t)
  (setq isortify-line-width 88))

Use black-compatible settings as recommended here. Add missing variables to conform with black.

(defcustom isortify-force-grid-wrap nil
  "Force from imports to be grid wrapped regardless of line length, where the value given is the number of imports allowed before wrapping occurs.")

(defcustom isortify-use-parentheses nil
  "Tells isort to use parenthesis for line continuation instead of \ for lines over the allotted line length limit.")

(setq isortify-force-grid-wrap 0)
(setq isortify-use-parentheses t)

(defun isortify-call-args ()
  "Collect CLI arguments for isort process."
  (let (args)
    (when (string= "ipython" python-shell-interpreter)
      (push "--" args))
    (when isortify-multi-line-output
      (push "--multi-line" args)
      (push (number-to-string isortify-multi-line-output) args))
    (when isortify-trailing-comma
      (push "--trailing-comma" args))
    (when isortify-known-first-party
      (dolist (project isortify-known-first-party)
        (push "--project" args)
        (push project args)))
    (when isortify-known-third-party
      (dolist (thirdparty isortify-known-third-party)
        (push "--thirdparty" args)
        (push thirdparty args)))
    (when isortify-lines-after-imports
      (push "--lines-after-imports" args)
      (push (number-to-string isortify-lines-after-imports) args))
    (when isortify-line-width
      (push "--line-width" args)
      (push (number-to-string isortify-line-width) args))
    (when isortify-force-grid-wrap
      (push "--force-grid-wrap" args)
      (push (number-to-string isortify-force-grid-wrap) args))
    (when isortify-use-parentheses
      (push "--use-parentheses" args))
    (push "-" args)
    (reverse args)))

yapf

Use yapf to auto format python buffers on save.

(use-package yapfify
  :ensure t
  :init
  (add-hook 'python-mode-hook 'yapf-mode))

pep8

Use py-autopep8 to auto format python buffers on save.

(use-package py-autopep8
  :ensure t
  :init
  (add-hook 'python-mode-hook 'py-autopep8-enable-on-save))

Syntax Checking

Flycheck

By default flycheck only runs one available python checker.

(flycheck-add-next-checker 'python-flake8 'python-pylint)

pycheckers

By default flycheck only runs one available python checker. Use flycheck-pycheckers.

(use-package flycheck-pycheckers
  :ensure t
  :init
  (setq flycheck-pycheckers-checkers '(pylint flake8))
  (add-hook 'flycheck-mode-hook #'flycheck-pycheckers-setup))

Python Interpretor

Use ipython as default interpreter and disable feature warning.

(setq python-shell-interpreter "ipython"
      python-shell-interpreter-args "-i --simple-prompt"
      python-shell-prompt-detect-failure-warning nil)
(add-to-list 'python-shell-completion-native-disabled-interpreters
             "ipython")

Rust-mode

A compilation of settings for programming in rust. The recommended way to install rust is via rustup. Remember to use rustup add component to install rust-fmt, rust-src, and rls.

Rust-mode

Install rust-mode, use rust-fmt to format the code upon saving, and automatically enable rust-mode for *.rs files.

(use-package rust-mode
  :ensure t
  :init
  (setq rust-format-on-save t)
  (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode)))

Cargo Integration

A minor mode for cargo, the package manager for rust.

(use-package cargo
  :ensure t
  :init
  (add-hook 'rust-mode-hook 'cargo-minor-mode))

Flycheck Support

Better flycheck support via flycheck-rust.

(use-package flycheck-rust
  :ensure t
  :init
  (with-eval-after-load 'rust-mode
    (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)))

Racer

Code completion utility for rust. Provides company integration.

(use-package racer
  :ensure t
  :init
  (add-hook 'rust-mode-hook #'racer-mode)
  (add-hook 'rust-mode-hook #'eldoc-mode))

Zig-mode

(use-package zig-mode
  :ensure t)

Enhancements

Packages providing enhancements to Emacs interface. Mostly simple plug-and-play packages. Load enhancements in the end to prevent their dependencies getting loaded prior to their own customization.

Ace Window

Prepare for the age of multi-monitor and ultra-wide.

(use-package ace-window
  :ensure t
  :bind
  (("M-o" . ace-window))
  :init
  (setq aw-keys '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?0)))

Avy

Jump to visible text using a char-based decision tree, similar to ace-jump.

(use-package avy
  :ensure t
  :init
  (define-prefix-command 'user/avy-prefix)
  (global-set-key (kbd "C-:") 'user/avy-prefix)
  (define-key 'user/avy-prefix (kbd "c") 'avy-goto-char)
  (define-key 'user/avy-prefix (kbd "C") 'avy-goto-char-2)
  (define-key 'user/avy-prefix (kbd "t") 'avy-goto-char-timer)
  (define-key 'user/avy-prefix (kbd "s") 'avy-goto-char-in-line)
  (define-key 'user/avy-prefix (kbd "j") 'avy-goto-line-above)
  (define-key 'user/avy-prefix (kbd "k") 'avy-goto-line-below)
  (define-key 'user/avy-prefix (kbd "l") 'avy-goto-line)
  (define-key 'user/avy-prefix (kbd "w") 'avy-goto-word-0)
  (define-key 'user/avy-prefix (kbd "W") 'avy-goto-word-1)
  (define-key 'user/avy-prefix (kbd "o") 'avy-org-goto-heading-timer)
  (define-key 'user/avy-prefix (kbd "O") 'avy-org-refile-as-child))

Dashboard

An extensible Emacs startup screen showing you what’s most important.

Installation

Change default startup screen with dashboard. Customize initial-buffer-choice to affect new frames created by emacsclient. Also refresh dashboard to ensure customizations take effect.

(use-package dashboard
  :ensure t
  :config
  (dashboard-setup-startup-hook)
  (setq initial-buffer-choice (lambda()
                                (dashboard-refresh-buffer)
                                (get-buffer "*dashboard*"))))

Customize Banner and Logo

Customize banner and logo.

(defvar user/dashboard-banner-logo-titles
  '("42"
    "9 MORE SEASONS UNTIL I GET THAT DIPPING SZECHUAN SAUCE!"
    "Avocado + Maple Syrup = Dragon Fruit"
    "Eight-Megabytes-And-Constantly-Swapping"
    "Enter-Meta-Alt-Control-Shift"
    "Execute order 66."
    "Greetings from Emacs!"
    "POLYBIUS"
    "Project-iM@CS"
    "Supervillain Repair & Restoration"
    "This is fine."
    "Weak emperors mean strong viceroys."
    "Wissen ist Nacht!"
    "Wubba Lubba Dub-Dub!"))
(setq dashboard-banner-logo-title
      (elt user/dashboard-banner-logo-titles
           (random (length user/dashboard-banner-logo-titles))))
(setq dashboard-startup-banner
      (expand-file-name "static/sxs.png" user-emacs-directory))

Customize Widgets

dashboard-insert-configs

Create widget to display important config files. Use c to jump to this section.

(defvar user/config-file-list
  (mapcar (lambda (arg) (expand-file-name arg user-emacs-directory))
          '("README.org"
            "init.el"
            "static/math_macros.sty")))

(defun user/dashboard-insert-configs (list-size)
  "Add a list of config files."
  (dashboard-insert-section
   "Config Files:"
   user/config-file-list
   list-size
   "c"
   `(lambda (&rest ignore) (find-file-existing ,el))
   (abbreviate-file-name el)))

(add-to-list 'dashboard-item-generators '(configs . user/dashboard-insert-configs))

dashboard-insert-init-time

Display initialization time.

(defun user/dashboard-insert-init-time (list-size)
   "Displays Emacs init time."
   (insert (format "[Started Emacs in %s.]" (emacs-init-time))))

(add-to-list 'dashboard-item-generators '(init-time . user/dashboard-insert-init-time))

Apply All Widgets

Set items to display:

(setq dashboard-items '((recents  . 10)
                        (bookmarks . 5)
                        (projects . 8)
                        (agenda . 5)
;                        (registers . 5)
                        (configs)
                        (init-time)))

HTML Export

Convert buffer text and decorations to HTML by htmlize-buffer so that people can see what I see.

(use-package htmlize
  :ensure t)

Keybindings

IBuffer

Use ibuffer instead of list-buffer.

(global-set-key (kbd "C-x C-b") 'ibuffer)
(autoload 'ibuffer "ibuffer" "List buffers." t)

Keyfreq

Records command frequency. I am planning on adjusting my keyboard layout with this information.

(use-package keyfreq
  :ensure t
  :init
  (keyfreq-mode 1)
  (keyfreq-autosave-mode 1))

Magit

Install magit and bind magit-status to C-c g.

(use-package magit
  :ensure t
  :init
  (global-set-key (kbd "C-c g") 'magit-status))

Magit annex

Magit support for git-annex.

(use-package magit-annex
  :ensure t)

Projectile

Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies(when feasible).

Installation

Install projectile.

(use-package projectile
  :ensure t
  :init
  (projectile-mode +1))

Enable helm support

Since I use helm, I need to install additional support.

(use-package helm-projectile
  :ensure t
  :init
  (setq projectile-completion-system 'helm)
  (helm-projectile-on))

About

My emacs configuration, done in a literate programming fashion using org-mode.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published