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).
Module | Function |
---|---|
Packages | Package management. |
Aesthetics | UI and theme. |
Plugins | Larger scale packages. |
Mode Specific | Settings specific to a mode. |
Enhancements | Plug-and-play enhancements. |
Manage my package settings.
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/")))
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))
Mostly aesthetics and quality of life changes.
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)
Enable auto revert mode to auto-refresh when files have changed on disk.
(global-auto-revert-mode t)
Install base16-theme
and enable gruvbox dark pale.
(use-package base16-theme
:ensure t
:config
(load-theme 'base16-gruvbox-dark-pale t))
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)
Install fcitx support.
(use-package fcitx
:ensure t
:init
(fcitx-aggressive-setup)
(setq fcitx-use-dbus t))
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
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))
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)))))
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)
Enable line highlighting.
(global-hl-line-mode t)
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)
Enable line wrapping by default.
(global-visual-line-mode t)
Use spaces for indenting.
(setq-default indent-tabs-mode nil)
For those that uses tab, set width to 4.
(setq-default tab-width 4)
Highlight matching parenthesis.
(show-paren-mode t)
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 upon saving.
(add-hook 'before-save-hook 'delete-trailing-whitespace)
Save *~
backups in $(pwd)/.bak
.
(setq backup-directory-alist
'(("." . ".bak"))
)
(setq column-number-mode t)
(use-package sublimity
:ensure t
:config
(require 'sublimity-scroll)
(require 'sublimity-map)
(sublimity-global-mode))
(use-package smooth-scrolling
:ensure t
:config (smooth-scrolling-mode 1))
Hide menu, scrollbar and toolbars.
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
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)
Fills up gap in the border when tiling Emacs to half-screen.
(setq frame-resize-pixelwise t)
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)
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.
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.
(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 with magit
and projectile
.
(setq magit-completing-read-function 'ivy-completing-read)
(setq projectile-completion-system 'ivy)
Stolen from Admiral Akber’s config.
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)
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 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)
Above defaults overides such as M-x
these are custom bindings.
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 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)
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 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)
Auto completion of everything with nice backends.
Install company
and enable it globally.
(use-package company
:ensure t
:init (global-company-mode))
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)
Flush annotation on candidates to the right.
(setq company-tooltip-align-annotations t)
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))
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))
: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)))))
Install company-math
and add it to company-backends
.
Enable unicode symbol backend globally.
(use-package company-math
:ensure t)
;; :init (add-to-list 'company-backends
;; '(company-math-symbols-unicode)))
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)
Install company-anaconda
and add it to company-backends
.
(use-package company-anaconda
:ensure t
:init (add-to-list 'company-backends
'company-anaconda))
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 completion via company-lsp
. lsp-mode
will add the appropriate backend.
(use-package company-lsp
:ensure t)
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))))
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 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.
Install flycheck
.
(use-package flycheck
:ensure t
:init (global-flycheck-mode))
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"))))
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 various parameters for the checker.
(custom-set-variables
'(flycheck-googlelint-verbose "5")
'(flycheck-googlelint-filter "-legal/copyright,-whitespace/braces")
'(flycheck-googlelint-linelength "80"))
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 is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates.
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))
yasnippet-snippets
is a collection of snippets for many langulages.
(use-package yasnippet-snippets
:ensure t)
Settings specific to a mode or defines a new mode that often specializes Emacs for a certain programming language.
auctex
is an extensible package for writing and formatting TEX files
in GNU Emacs.
Need to use defer
as auctex.el
does not actually provide auctex
feature.
(use-package auctex
:defer t
:ensure t)
Enable auctex
to automatically parse buffer information.
(setq TeX-parse-self t)
(setq TeX-auto-save t)
(setq TeX-save-query nil)
Let auctex
figure out the master file for TeX document spread over many files.
(setq-default TeX-master nil)
Spell checking with flyspell
.
(add-hook 'LaTeX-mode-hook 'flyspell-mode)
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. This allows macro insertion following `
.
Not exactly useful since we already have company
.
(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
Insert braces after _
or ^
.
(setq TeX-electric-sub-and-superscript t)
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’s C/C++ style for c-mode.
(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))
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))
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))
Use Google’s C++ style.
(custom-set-variables '(clang-format-style "file"))
Add highlighting for doxygen blocks.
(use-package highlight-doxygen
:ensure t
:init
(add-hook 'c-mode-common-hook 'highlight-doxygen-mode))
Syntax highlighting and indention for CMakeLists.txt
.
(use-package cmake-mode
:ensure t)
Eldoc for CMake.
(use-package eldoc-cmake
:ensure t
:hook (cmake-mode . eldoc-cmake-enable))
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))
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))
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)
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
.
(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 via lsp-ui
.
(use-package lsp-ui
:ensure t
:init
(add-hook 'lsp-mode-hook 'lsp-ui-mode)
(setq lsp-ui-flycheck-enable t))
Remember to set $GOPATH
environment variable and add $GOPATH/bin
to $PATH
.
(use-package go-mode
:ensure t
:init
(add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode))
(add-hook 'before-save-hook 'gofmt-before-save))
Helpful code analysis tool, requires golang.org/x/tools/cmd/guru.
(use-package go-guru
:ensure t)
Official major mode for julia
. This is required as a dependency for ess-julia-mode
.
(use-package julia-mode
:ensure t)
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))
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
specific settings.
Allows the use of “a.” or “b)” in ordered lists.
(setq org-list-allow-alphabetical t)
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)
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
Do not collapse the links.
(org-toggle-link-display)
Do not change text indention when promoting/demoting subtrees.
(setq org-adapt-indentation nil)
Automatically enable truncated lines when starting org-mode
.
(setq-default org-startup-truncated t)
Disable auto-fill-mode
when in org-mode
.
(add-hook 'org-mode-hook 'turn-off-auto-fill)
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)
Don’t allow editing of folded regions
(setq org-catch-invisible-edits 'error)
Parent tasks should not be marked DONE until all subtasks are marked as DONE.
(setq org-enforce-todo-dependencies t)
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)))
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")
Spell checking with flyspell-mode
. Would need to install dictionary lib like aspell
in base system.
(add-hook 'org-mode-hook 'flyspell-mode)
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)))))
Do not export validation link.
(setq org-html-validation-link nil)
An Org exporter backend that exports Org to Hugo-compatible Markdown (Blackfriday) and generates the front-matter (in TOML or YAML format).
Enable ox-hugo
as an option for exporting.
(use-package ox-hugo
:ensure t
:init (with-eval-after-load 'ox (require 'ox-hugo)))
Wrap key bindings in <kbd>
.
(setq org-hugo-use-code-for-kbd t)
This is another exporter for org-mode that translates Org-mode file to various other formats via Pandoc.
(use-package ox-pandoc
:ensure t)
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"))))))
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"))
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)
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))
Use svg
for supporting SVGs. Requires inkscape
to be installed.
(add-to-list 'org-latex-packages-alist '("" "svg" nil))
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"))
Enhancements to python-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))
Use black
to auto format python buffers on save.
(use-package blacken
:ensure t
:init
(add-hook 'python-mode-hook 'blacken-mode))
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)))
Use yapf
to auto format python buffers on save.
(use-package yapfify
:ensure t
:init
(add-hook 'python-mode-hook 'yapf-mode))
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))
By default flycheck
only runs one available python checker.
(flycheck-add-next-checker 'python-flake8 'python-pylint)
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))
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")
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
.
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)))
A minor mode for cargo
, the package manager for rust.
(use-package cargo
:ensure t
:init
(add-hook 'rust-mode-hook 'cargo-minor-mode))
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)))
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))
(use-package zig-mode
:ensure t)
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.
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)))
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))
An extensible Emacs startup screen showing you what’s most important.
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.
(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))
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))
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))
Set items to display:
(setq dashboard-items '((recents . 10)
(bookmarks . 5)
(projects . 8)
(agenda . 5)
; (registers . 5)
(configs)
(init-time)))
Convert buffer text and decorations to HTML by htmlize-buffer
so
that people can see what I see.
(use-package htmlize
:ensure t)
Use ibuffer
instead of list-buffer
.
(global-set-key (kbd "C-x C-b") 'ibuffer)
(autoload 'ibuffer "ibuffer" "List buffers." t)
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))
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 support for git-annex
.
(use-package magit-annex
:ensure t)
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).
Install projectile
.
(use-package projectile
:ensure t
:init
(projectile-mode +1))
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))