mirror of
https://github.com/correl/dotfiles.git
synced 2024-12-01 11:09:57 +00:00
1507 lines
46 KiB
Org Mode
1507 lines
46 KiB
Org Mode
#+TITLE: Emacs Configuration
|
||
#+STARTUP: indent
|
||
|
||
* Startup
|
||
** Disable the emacs startup screen.
|
||
#+HEADER: :noweb-ref startup
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq inhibit-startup-screen +1)
|
||
#+END_SRC
|
||
* Custom settings
|
||
Store options set via =customize-*= in a separate file (Emacs stores
|
||
them in =init.el= by default).
|
||
|
||
#+HEADER: :noweb-ref custom-settings
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq custom-file "~/.emacs.d/custom.el")
|
||
(if (file-exists-p custom-file)
|
||
(load custom-file))
|
||
|
||
(setf custom-safe-themes t)
|
||
#+END_SRC
|
||
* UI
|
||
** Highlight the current line
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(global-hl-line-mode +1)
|
||
#+END_SRC
|
||
** Powerline
|
||
Make the mode line prettier.
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package powerline
|
||
:ensure t
|
||
:config
|
||
|
||
(powerline-default-theme))
|
||
#+END_SRC
|
||
** Nyan-mode
|
||
Visualize the current position within the buffer in the modeline with nyancat!
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package nyan-mode
|
||
:ensure t
|
||
:config
|
||
(nyan-mode)
|
||
(nyan-start-animation))
|
||
#+END_SRC
|
||
** Display Time & Battery Status
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq display-time-24hr-format t)
|
||
(setq display-time-load-average-threshold 0.9)
|
||
(display-time-mode t)
|
||
|
||
(setq battery-mode-line-format
|
||
"[🔋%b%p%%%% (%t)]")
|
||
(display-battery-mode t)
|
||
#+END_SRC
|
||
** Theme
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package moe-theme
|
||
:ensure t
|
||
:config
|
||
|
||
(setq moe-theme-resize-markdown-title '(1.5 1.4 1.3 1.2 1.0 1.0))
|
||
(setq moe-theme-resize-org-title '(1.5 1.4 1.3 1.2 1.1 1.0 1.0 1.0 1.0))
|
||
(setq moe-theme-resize-rst-title '(1.5 1.4 1.3 1.2 1.1 1.0))
|
||
|
||
(setq moe-theme-highlight-buffer-id t)
|
||
(moe-theme-set-color 'cyan)
|
||
(powerline-moe-theme)
|
||
(moe-dark))
|
||
|
||
#+END_SRC
|
||
** Major mode icons
|
||
Display major-mode names as icons in the mode line when possible.
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package mode-icons
|
||
:ensure t
|
||
:defer 5
|
||
:config (mode-icons-mode))
|
||
#+END_SRC
|
||
** Which-Key
|
||
Display key binding completions after a delay.
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package which-key
|
||
:ensure t
|
||
:diminish which-key-mode
|
||
:config
|
||
(which-key-setup-side-window-right-bottom)
|
||
(which-key-mode))
|
||
#+END_SRC
|
||
** Helm
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package helm
|
||
:ensure t
|
||
:diminish helm-mode
|
||
:bind (("M-x" . helm-M-x)
|
||
("M-y" . helm-show-kill-ring)
|
||
("C-x b" . helm-mini)
|
||
("C-x C-b" . helm-buffers-list)
|
||
("C-x C-f" . helm-find-files)
|
||
("C-x C-r" . helm-recentf)
|
||
("C-x c o" . helm-occur))
|
||
:config (progn
|
||
(require 'helm-config)
|
||
(helm-mode 1)
|
||
(add-hook 'eshell-mode-hook
|
||
(lambda ()
|
||
(define-key eshell-mode-map (kbd "TAB") 'helm-esh-pcomplete)
|
||
(define-key eshell-mode-map (kbd "C-c C-l") 'helm-eshell-history)))))
|
||
#+END_SRC
|
||
*** helm-descbinds
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package helm-descbinds
|
||
:ensure t
|
||
:bind (("C-h b" . helm-descbinds)
|
||
("C-h w" . helm-descbinds)))
|
||
#+END_SRC
|
||
*** helm-ag
|
||
Helm search plugin for [[Ag%20(The%20Silver%20Searcher)][Ag (The Silver Searcher)]]
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package helm-ag
|
||
:ensure t
|
||
:commands (helm-ag))
|
||
#+END_SRC
|
||
*** helm-flyspell
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(use-package helm-flyspell
|
||
:ensure t
|
||
:commands helm-flyspell-correct
|
||
:init (eval-after-load 'flyspell
|
||
'(define-key flyspell-mode-map (kbd "C-;") 'helm-flyspell-correct)))
|
||
#+end_src
|
||
*** helm-swoop
|
||
|
||
Replace isearch-forward with helm-swoop for a nicer experience.
|
||
|
||
#+BEGIN_NOTES
|
||
Quite usefully, using prefix arguments expands the lines of context
|
||
shown around the search results.
|
||
#+END_NOTES
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package helm-swoop
|
||
:ensure t
|
||
:commands (helm-swoop)
|
||
:bind (("C-s" . helm-swoop))
|
||
:config
|
||
;; Defaults to (lambda () (thing-at-point 'symbol)).
|
||
;; Setting it to return nil, as I find it tends to be more annoying than useful.
|
||
(setq helm-swoop-pre-input-function (lambda () nil))
|
||
;; Enable syntax highlighting. It makes it easier for my eyes to
|
||
;; parse the results, and doesn't seem to slow things down
|
||
;; measurably.
|
||
(setq helm-swoop-speed-or-color t)
|
||
)
|
||
#+END_SRC
|
||
** Undo-Tree
|
||
|
||
Visualize and traverse undo history as a directed graph.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package undo-tree
|
||
:ensure t
|
||
:diminish undo-tree-mode
|
||
:config (global-undo-tree-mode))
|
||
#+END_SRC
|
||
** Multiple Cursors
|
||
#+HEADER: :noweb-ref look-and-feel
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package multiple-cursors
|
||
:bind (("C-S-c C-S-c" . mc/edit-lines)
|
||
("C->" . mc/mark-next-like-this)
|
||
("C-<" . mc/mark-previous-like-this)
|
||
("C-c C-<" . mc/mark-all-like-this)
|
||
("C-M->" . mc/mark-more-like-this-extended)))
|
||
#+END_SRC
|
||
* Coding
|
||
** Languages
|
||
*** Lisps
|
||
#+NAME: lisps
|
||
| Mode | Description |
|
||
|------------+---------------------------|
|
||
| lisp | Common Lisp |
|
||
| emacs-lisp | Emacs Lisp |
|
||
| scheme | Scheme |
|
||
| lfe | Lisp-Flavored Erlang |
|
||
| clojure | Clojure |
|
||
| hy | Hy (Lisp-flavored Python) |
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
;; SLIME
|
||
(if (file-exists-p "~/quicklisp/slime-helper.el")
|
||
(load (expand-file-name "~/quicklisp/slime-helper.el")))
|
||
|
||
(setq inferior-lisp-program "clisp")
|
||
|
||
(use-package paredit
|
||
:ensure t
|
||
:commands (paredit-mode)
|
||
:diminish " ❨❩")
|
||
|
||
(use-package rainbow-identifiers
|
||
:ensure t
|
||
:commands (rainbow-identifiers-mode))
|
||
|
||
(use-package rainbow-delimiters
|
||
:ensure t
|
||
:commands (rainbow-delimiters-mode))
|
||
|
||
(let ((lisp-mode-hooks
|
||
(mapcar (lambda (lisp)
|
||
(intern (concat lisp "-mode-hook")))
|
||
(mapcar 'car (cddr '<<lisps()>>)))))
|
||
(mapc (lambda (hook)
|
||
(message (format "Installing LISP mode hook for %S" hook))
|
||
(add-hook hook (lambda ()
|
||
(show-paren-mode t)
|
||
(electric-indent-mode t)
|
||
(paredit-mode t)
|
||
(rainbow-delimiters-mode t)
|
||
(rainbow-identifiers-mode t))))
|
||
(cons 'eval-expression-minibuffer-setup-hook
|
||
lisp-mode-hooks)))
|
||
#+END_SRC
|
||
**** Lisp-Flavored Erlang
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package lfe-mode
|
||
:ensure t
|
||
:mode "\\.lfe$")
|
||
#+END_SRC
|
||
**** Clojure
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package clojure-mode
|
||
:ensure t
|
||
:mode (("\\.clj[sx]?$" . clojure-mode)
|
||
("\\.edn$" . clojure-mode)))
|
||
#+END_SRC
|
||
***** Cider
|
||
Communicates with the clojure REPL.
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package cider
|
||
:ensure t
|
||
:commands (cider-jack-in cider)
|
||
:config (setq org-babel-clojure-backend 'cider))
|
||
#+END_SRC
|
||
**** Hy
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package hy-mode
|
||
:ensure t
|
||
:mode "\\.hy$")
|
||
|
||
(use-package ob-hy
|
||
:ensure t
|
||
:defer t)
|
||
#+END_SRC
|
||
*** Erlang
|
||
A distributed, fault-tolerant functional language.
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package erlang
|
||
:ensure t
|
||
:mode ("\.[eh]rl$" . erlang-mode)
|
||
:config (add-hook 'erlang-mode-hook
|
||
(lambda ()
|
||
(setq inferior-erlang-machine-options '("-sname" "emacs"
|
||
"-hidden")))))
|
||
#+END_SRC
|
||
*** Elixir
|
||
Ruby-flavoured Erlang.
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package elixir-mode
|
||
:ensure t
|
||
:mode "\\.exs?$")
|
||
|
||
(use-package alchemist
|
||
:ensure t
|
||
:after elixir-mode)
|
||
|
||
(use-package ob-elixir
|
||
:ensure t
|
||
:after ob)
|
||
#+END_SRC
|
||
*** Haskell
|
||
A strongly typed, pure functional language.
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package haskell-mode
|
||
:ensure t
|
||
:mode "\.hs$")
|
||
|
||
(use-package hi2
|
||
:ensure t
|
||
:commands turn-on-hi2
|
||
:init (add-hook 'haskell-mode-hook 'turn-on-hi2))
|
||
#+END_SRC
|
||
*** Elm
|
||
A functional, reactive language for the web that compiles to
|
||
JavaScript.
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package elm-mode
|
||
:ensure t
|
||
:mode "\.elm$"
|
||
:config
|
||
(add-hook 'elm-mode-hook #'elm-oracle-setup-completion)
|
||
(add-to-list 'company-backends 'company-elm))
|
||
|
||
#+END_SRC
|
||
*** Idris
|
||
|
||
A functional language with dependent types.
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package idris-mode
|
||
:ensure t
|
||
:mode "\.idr$")
|
||
#+END_SRC
|
||
*** Web
|
||
**** HTML
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package web-mode
|
||
:ensure t
|
||
:mode "\\.html?$")
|
||
#+END_SRC
|
||
**** SCSS
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package scss-mode
|
||
:ensure t
|
||
:mode "\\.scss$"
|
||
:config (add-hook 'scss-mode-hook
|
||
(lambda ()
|
||
"Customize SCSS indentation"
|
||
(setq css-indent-offset 2))))
|
||
#+END_SRC
|
||
*** JavaScript
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package js2-mode
|
||
:ensure t
|
||
:mode ".js$")
|
||
#+END_SRC
|
||
*** PHP
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package php-mode
|
||
:ensure t
|
||
:mode (("\\.php$" . php-mode)
|
||
("\\.inc$" . php-mode))
|
||
:config (add-hook 'php-mode-hook (lambda ()
|
||
"Customize PHP indentation"
|
||
(c-set-offset 'arglist-cont-nonempty 'c-lineup-arglist)
|
||
(c-set-offset 'substatement-open 0)
|
||
(c-set-offset 'case-label '+))))
|
||
#+END_SRC
|
||
*** Python
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package python-mode
|
||
:ensure t
|
||
:mode "\.py$")
|
||
#+END_SRC
|
||
**** Elpy
|
||
|
||
Full functionality requires a number of python packages to be
|
||
installed:
|
||
|
||
#+BEGIN_SRC sh :exports code
|
||
# Either of these
|
||
pip install rope
|
||
pip install jedi
|
||
# flake8 for code checks
|
||
pip install flake8
|
||
# importmagic for automatic imports
|
||
pip install importmagic
|
||
# and autopep8 for automatic PEP8 formatting
|
||
pip install autopep8
|
||
# and yapf for code formatting
|
||
pip install yapf
|
||
#+END_SRC
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package elpy
|
||
:ensure t
|
||
:after python
|
||
:config (elpy-enable))
|
||
#+END_SRC
|
||
**** Cython
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package cython-mode
|
||
:ensure t
|
||
:mode "\.pyx$")
|
||
#+END_SRC
|
||
*** Ruby
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package rvm
|
||
:ensure t
|
||
:commands (rvm-use
|
||
rvm-use-default))
|
||
#+END_SRC
|
||
*** Yaml
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package yaml-mode
|
||
:ensure t
|
||
:mode "\.yml$")
|
||
#+END_SRC
|
||
*** Docker
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package dockerfile-mode
|
||
:ensure t
|
||
:mode "^Dockerfile$")
|
||
#+END_SRC
|
||
*** Graphviz
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package graphviz-dot-mode
|
||
:ensure t
|
||
:mode "\.dot$"
|
||
:config
|
||
(setq graphviz-dot-indent-width 2))
|
||
#+END_SRC
|
||
*** Gnuplot
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package gnuplot
|
||
:ensure t)
|
||
#+END_SRC
|
||
*** PlantUML
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package plantuml-mode
|
||
:ensure t
|
||
:mode "\\.plantuml\\'"
|
||
:commands plantuml-mode)
|
||
#+END_SRC
|
||
|
||
Don't forget to configure =org-plantuml-jar-path= and
|
||
=plantuml-jar-path= to point to a version of plantuml.jar on your
|
||
system.
|
||
** Tools
|
||
*** EditorConfig
|
||
|
||
Editor-agnostic coding style configuration.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package editorconfig
|
||
:ensure t
|
||
:diminish editorconfig-mode
|
||
:config
|
||
(editorconfig-mode 1))
|
||
#+END_SRC
|
||
|
||
*** Projectile
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package projectile
|
||
:ensure t
|
||
:defer t
|
||
:diminish " 📁"
|
||
:bind-keymap ("C-c p" . projectile-command-map)
|
||
:config
|
||
(projectile-mode t))
|
||
|
||
(use-package helm-projectile
|
||
:ensure t
|
||
:after (helm projectile)
|
||
:config (helm-projectile-on))
|
||
#+END_SRC
|
||
*** Autocomplete
|
||
**** Company
|
||
|
||
Install and configure Company for auto-completion.
|
||
|
||
#+HEADER: :noweb-ref autocomplete
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package company
|
||
:ensure t
|
||
:commands (company-mode)
|
||
:config (progn
|
||
(add-hook 'prog-mode-hook 'company-mode)
|
||
|
||
(bind-key "C-n" #'company-select-next company-active-map)
|
||
(bind-key "C-p" #'company-select-previous company-active-map)))
|
||
#+END_SRC
|
||
**** Auto-Complete
|
||
|
||
Not using this for auto-completion anymore, but several packages
|
||
require it.
|
||
|
||
#+HEADER: :noweb-ref autocomplete
|
||
#+begin_src emacs-lisp
|
||
(use-package auto-complete
|
||
:ensure t
|
||
:defer t)
|
||
#+end_src
|
||
|
||
*** Flycheck
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package flycheck
|
||
:ensure t
|
||
:diminish " ✓"
|
||
:init
|
||
(add-hook 'after-init-hook #'global-flycheck-mode))
|
||
#+END_SRC
|
||
*** Web Mode
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package web-mode
|
||
:ensure t
|
||
:mode ("\\.html$" . web-mode)
|
||
:config (add-hook 'web-mode-hook (lambda ()
|
||
(setq web-mode-markup-indent-offset 4)
|
||
(setq web-mode-css-indent-offset 4)
|
||
(setq web-mode-code-indent-offset 4))))
|
||
#+END_SRC
|
||
*** Skewer
|
||
Live web development in Emacs.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package skewer-mode
|
||
:ensure t
|
||
:commands (run-skewer
|
||
skewer-mode
|
||
skewer-css-mode
|
||
skewer-html-mode)
|
||
:init (progn (add-hook 'js2-mode-hook 'skewer-mode)
|
||
(add-hook 'css-mode-hook 'skewer-css-mode)
|
||
(add-hook 'html-mode-hook 'skewer-html-mode)))
|
||
#+END_SRC
|
||
*** Yasnippet
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package yasnippet
|
||
:ensure t
|
||
:defer t
|
||
:diminish yas-minor-mode
|
||
:config (yas-global-mode 1))
|
||
|
||
(use-package yasnippet-snippets
|
||
:ensure t)
|
||
#+END_SRC
|
||
*** Ag (The Silver Searcher)
|
||
This is a code searching tool that replaces =ack=, and is an order of
|
||
magnitude faster.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package ag
|
||
:ensure t
|
||
:commands (ag))
|
||
#+END_SRC
|
||
*** Expand Region
|
||
Increase selected region by semantic units.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package expand-region
|
||
:ensure t
|
||
:bind (("C-=" . er/expand-region)))
|
||
#+END_SRC
|
||
*** Nameless
|
||
|
||
Hide package namespaces in emacs-lisp code.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package nameless
|
||
:ensure t
|
||
:commands nameless-mode-from-hook
|
||
:init
|
||
(add-hook 'emacs-lisp-mode-hook #'nameless-mode-from-hook)
|
||
:config
|
||
(setq nameless-private-prefix t))
|
||
#+END_SRC
|
||
*** Language Server Protocol
|
||
IDE-level integration supporting multiple languages.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(use-package lsp-mode
|
||
:ensure t
|
||
:init (setq lsp-auto-guess-root t
|
||
lsp-keep-workspace-alive nil
|
||
lsp-enable-xref t
|
||
lsp-prefer-flymake nil
|
||
lsp-auto-configure t
|
||
lsp-response-timeout 3)
|
||
:hook ((prog-mode . lsp-mode)))
|
||
#+end_src
|
||
|
||
#+CAPTION: Language server implementations
|
||
| Language | Server | Installation |
|
||
|---------------+--------------------------------------------+-------------------------------------------|
|
||
| PHP | [[https://www.npmjs.com/package/intelephense][Intelephense]] | =npm i intelephense= |
|
||
| Python | [[https://github.com/palantir/python-language-server][Python Language Server]] | =pip install python-language-server[all]= |
|
||
| Python (Mypy) | [[https://github.com/tomv564/pyls-mypy][Mypy plugin for the Python Language Server]] | =pip install pyls-mypy= |
|
||
**** Company integration
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(use-package company-lsp
|
||
:ensure t
|
||
:init (setq company-lsp-async t)
|
||
:hook ((python-mode . (lambda ()
|
||
(add-to-list 'company-backends 'company-lsp)))
|
||
(js2-mode . (lambda ()
|
||
(add-to-list 'company-backends 'company-lsp)))))
|
||
#+end_src
|
||
**** Fancy UI
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(use-package lsp-ui
|
||
:ensure t
|
||
:hook (lsp-mode . lsp-ui-mode)
|
||
:config
|
||
;; Disable eldoc-mode
|
||
(global-eldoc-mode -1))
|
||
#+end_src
|
||
** Libraries
|
||
*** Dash
|
||
A modern list api for Emacs. No 'cl required.
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package dash
|
||
:ensure t
|
||
:config (dash-enable-font-lock))
|
||
#+END_SRC
|
||
*** Stream
|
||
|
||
Lazy sequences in Emacs (compatible with seq.el).
|
||
|
||
#+HEADER: :noweb-ref programming
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package stream
|
||
:ensure t
|
||
:if (version<= "25.1" emacs-version)
|
||
:defer t)
|
||
#+END_SRC
|
||
* Writing
|
||
** Style
|
||
*** End sentences with a single space
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq sentence-end-double-space nil)
|
||
#+END_SRC
|
||
** Formats
|
||
*** Org
|
||
**** Pretty bullets
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-bullets
|
||
:ensure t
|
||
:hook (org-mode . org-bullets-mode))
|
||
#+END_SRC
|
||
**** Modules
|
||
#+NAME: org-module-table
|
||
| org-habit |
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(let ((modules (mapcar (lambda (m) (intern (car m)))
|
||
'<<org-module-table()>>)))
|
||
(mapcar (lambda (m) (add-to-list 'org-modules m))
|
||
modules))
|
||
(org-load-modules-maybe t)
|
||
#+END_SRC
|
||
**** Tasks
|
||
***** Enforce dependencies
|
||
Require child tasks and checkboxes to be done before a parent task can
|
||
be marked done.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq
|
||
org-enforce-todo-dependencies t
|
||
org-enforce-todo-checkbox-dependencies t)
|
||
#+END_SRC
|
||
***** Keep logs in their own drawer
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-log-into-drawer t)
|
||
#+END_SRC
|
||
***** Log completion
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-log-done 'time)
|
||
#+END_SRC
|
||
***** Habits
|
||
Shift the consistency graph over a bit to make room for task
|
||
names.
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-habit-graph-column 70)
|
||
(setq org-habit-show-habits-only-for-today nil)
|
||
#+END_SRC
|
||
**** Refiling
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-refile-targets '((org-agenda-files . (:maxlevel . 6))))
|
||
#+END_SRC
|
||
**** Babel
|
||
***** Syntax highlighting
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default org-src-fontify-natively t)
|
||
#+END_SRC
|
||
***** HTTP
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(use-package ob-http
|
||
:ensure t
|
||
:after ob)
|
||
#+end_src
|
||
***** Language evaluation
|
||
|
||
Org-babel evaluation will be turned on for the following
|
||
languages. Setting ~Confirm Evaluation~ to ~No~ disables the
|
||
[[http://orgmode.org/manual/Code-evaluation-security.html][security prompt]] for that language.
|
||
|
||
#+NAME: org-babel-languages
|
||
| Language | Alias | Confirm Evaluation? | Description |
|
||
|--------------+-------+---------------------+---------------------------------|
|
||
| emacs-lisp | | Yes | Emacs Lisp |
|
||
| graphviz-dot | dot | No | Directed and undirected graphs |
|
||
| gnuplot | | No | Graphs |
|
||
| ditaa | | No | Ascii diagrams |
|
||
| plantuml | | No | Flow charts |
|
||
| mscgen | | No | Message sequence charts |
|
||
| haskell | | Yes | A pure, functional language |
|
||
| python | | Yes | A dynamic, all-purpose language |
|
||
| hy | | Yes | Python Lisp dialect |
|
||
| ruby | | Yes | A dynamic, all-purpose language |
|
||
| shell | | Yes | Shell scripts |
|
||
| http | | No | HTTP requests |
|
||
| sql | | No | SQL Queries |
|
||
| ledger | | No | Double-Entry Accounting |
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(defvar my/org-babel-evaluated-languages ())
|
||
(defvar my/org-src-lang-modes ())
|
||
(defvar my/org-babel-no-confirm-languages ())
|
||
|
||
(defun my/org-confirm-babel-evaluate (lang body)
|
||
(not (member (intern lang) my/org-babel-no-confirm-languages)))
|
||
|
||
(let ((language-table (cddr '<<org-babel-languages()>>)))
|
||
(mapcar (lambda (lang-pair)
|
||
(let* ((alias (if (not (string= (cadr lang-pair) "")) (cadr lang-pair)))
|
||
(lang (intern (car lang-pair)))
|
||
(lang-or-alias (if alias (intern alias) lang))
|
||
(confirm (not (string= (cl-caddr lang-pair) "No"))))
|
||
(if alias
|
||
(add-to-list 'my/org-src-lang-modes (cons alias lang)))
|
||
(if (not confirm)
|
||
(add-to-list 'my/org-babel-no-confirm-languages lang-or-alias))
|
||
(add-to-list 'my/org-babel-evaluated-languages lang-or-alias)
|
||
lang-or-alias))
|
||
language-table))
|
||
|
||
(mapcar (lambda (alias)
|
||
(add-to-list 'org-src-lang-modes alias))
|
||
my/org-src-lang-modes)
|
||
|
||
(org-babel-do-load-languages
|
||
'org-babel-load-languages
|
||
(mapcar (lambda (lang)
|
||
(cons lang t))
|
||
my/org-babel-evaluated-languages))
|
||
|
||
(setq org-confirm-babel-evaluate 'my/org-confirm-babel-evaluate)
|
||
#+END_SRC
|
||
***** Reload images on source execution
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(defun my/redisplay-org-images ()
|
||
(when org-inline-image-overlays
|
||
(org-redisplay-inline-images)))
|
||
|
||
(add-hook 'org-babel-after-execute-hook
|
||
'my/redisplay-org-images)
|
||
#+end_src
|
||
**** Wrap text in blocks
|
||
A useful snippet for marking a region and wrapping it in an org block.
|
||
|
||
Taken from [[http://pragmaticemacs.com/emacs/wrap-text-in-an-org-mode-block/][Pragmatic Emacs]]
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;; function to wrap blocks of text in org templates ;;
|
||
;; e.g. latex or src etc ;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
(defun org-begin-template ()
|
||
"Make a template at point."
|
||
(interactive)
|
||
(if (org-at-table-p)
|
||
(call-interactively 'org-table-rotate-recalc-marks)
|
||
(let* ((choices '(("s" . "SRC")
|
||
("e" . "EXAMPLE")
|
||
("q" . "QUOTE")
|
||
("v" . "VERSE")
|
||
("c" . "CENTER")
|
||
("l" . "LaTeX")
|
||
("h" . "HTML")
|
||
("a" . "ASCII")))
|
||
(key
|
||
(key-description
|
||
(vector
|
||
(read-key
|
||
(concat (propertize "Template type: " 'face 'minibuffer-prompt)
|
||
(mapconcat (lambda (choice)
|
||
(concat (propertize (car choice) 'face 'font-lock-type-face)
|
||
": "
|
||
(cdr choice)))
|
||
choices
|
||
", ")))))))
|
||
(let ((result (assoc key choices)))
|
||
(when result
|
||
(let ((choice (cdr result)))
|
||
(cond
|
||
((region-active-p)
|
||
(let ((start (region-beginning))
|
||
(end (region-end)))
|
||
(goto-char end)
|
||
(insert "#+END_" choice "\n")
|
||
(goto-char start)
|
||
(insert "#+BEGIN_" choice "\n")))
|
||
(t
|
||
(insert "#+BEGIN_" choice "\n")
|
||
(save-excursion (insert "#+END_" choice))))))))))
|
||
|
||
;;bind to key
|
||
(define-key org-mode-map (kbd "C-<") 'org-begin-template)
|
||
#+END_SRC
|
||
**** Complete keywords with Company
|
||
Taken from https://emacs.stackexchange.com/a/30691.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun org-keyword-backend (command &optional arg &rest ignored)
|
||
(interactive (list 'interactive))
|
||
(cl-case command
|
||
(interactive (company-begin-backend 'org-keyword-backend))
|
||
(prefix (and (eq major-mode 'org-mode)
|
||
(cons (company-grab-line "^#\\+\\(\\w*\\)" 1)
|
||
t)))
|
||
(candidates (mapcar #'upcase
|
||
(cl-remove-if-not
|
||
(lambda (c) (string-prefix-p arg c))
|
||
(pcomplete-completions))))
|
||
(ignore-case t)
|
||
(duplicates t)))
|
||
|
||
(eval-after-load 'company
|
||
'(add-to-list 'company-backends 'org-keyword-backend))
|
||
|
||
(add-hook 'org-mode-hook 'company-mode)
|
||
#+END_SRC
|
||
**** Exporting
|
||
***** LaTeX
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(use-package ox-latex
|
||
:defer t
|
||
:config
|
||
<<configure-ox-latex>>)
|
||
#+END_SRC
|
||
|
||
****** Document classes
|
||
|
||
Add org latex class definitions for some popular LaTeX classes,
|
||
including:
|
||
- [[HTTPS://ctan.org/pkg/koma-script?lang=en][KOMA-Script]]
|
||
- [[https://ctan.org/pkg/memoir?lang=en][Memoir]]
|
||
- [[https://ctan.org/pkg/hitec?lang=en][Hitec]]
|
||
- [[https://ctan.org/pkg/tufte-latex?lang=en][Tufte]]
|
||
- [[https://ctan.org/pkg/labbook?lang=en][Labbook]] (based on KOMA-Script)
|
||
|
||
#+HEADER: :noweb-ref configure-ox-latex
|
||
#+BEGIN_SRC emacs-lisp
|
||
(seq-map (apply-partially #'add-to-list 'org-latex-classes)
|
||
'(("koma-letter"
|
||
"\\documentclass{scrlttr2}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("koma-article"
|
||
"\\documentclass{scrartcl}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("koma-book"
|
||
"\\documentclass{scrbook}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("koma-book-chapters"
|
||
"\\documentclass{scrbook}"
|
||
("\\chapter{%s}" . "\\chapter*{%s}")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("koma-report"
|
||
"\\documentclass{scrreprt}"
|
||
("\\chapter{%s}" . "\\chapter*{%s}")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("memoir"
|
||
"\\documentclass{memoir}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("hitec"
|
||
"\\documentclass{hitec}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("paper"
|
||
"\\documentclass{paper}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("letter"
|
||
"\\documentclass{letter}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("tufte-handout"
|
||
"\\documentclass{tufte-handout}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("tufte-book"
|
||
"\\documentclass{tufte-book}"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("tufte-book-chapters"
|
||
"\\documentclass{tufte-book}"
|
||
("\\chapter{%s}" . "\\chapter*{%s}")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
("labbook"
|
||
"\\documentclass{labbook}"
|
||
("\\chapter{%s}" . "\\chapter*{%s}")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\labday{%s}")
|
||
("\\subsubsection{%s}" . "\\experiment{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
|
||
#+END_SRC
|
||
****** Source Highlighting
|
||
|
||
Configure org-mode LaTeX export to use minted for syntax highlighting.
|
||
|
||
Some languages / markups I use aren't supported by minted, so I map
|
||
them here so they don't fail.
|
||
|
||
#+NAME: ox-latex-minted-mappings
|
||
#+CAPTION: Minted language mappings
|
||
| Language | Mapping |
|
||
|----------+--------------|
|
||
| dot | text |
|
||
| org | text |
|
||
| ditaa | text |
|
||
| plantuml | text |
|
||
| csv | text |
|
||
| conf | linux-config |
|
||
|
||
#+HEADER: :noweb-ref configure-ox-latex
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(setq org-latex-listings 'minted)
|
||
(setq org-latex-minted-options
|
||
'(("fontsize" "\\scriptsize")))
|
||
(seq-map (lambda (mapping)
|
||
(add-to-list 'org-latex-minted-langs
|
||
(cons (intern (car mapping)) (cdr mapping))))
|
||
(seq-drop '<<ox-latex-minted-mappings()>> 2))
|
||
(add-to-list 'org-latex-packages-alist
|
||
'("" "minted" nil))
|
||
#+END_SRC
|
||
****** TeX Engine
|
||
|
||
Prepare the LaTeX export process, and default the compiler to xelatex,
|
||
as it has better unicode support than pdflatex.
|
||
|
||
#+BEGIN_NOTES
|
||
The =%latex= expansion variable is used so that org documents can
|
||
override the latex compiler using the file-level =LATEX_COMPILER=
|
||
directive.
|
||
#+END_NOTES
|
||
|
||
#+HEADER: :noweb-ref configure-ox-latex
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-latex-pdf-process
|
||
(-repeat 3 "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"))
|
||
|
||
;; Default to XeLaTeX
|
||
(setq org-latex-compiler "xelatex")
|
||
|
||
#+END_SRC
|
||
*** LaTeX
|
||
**** AUCTeX
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package tex-site
|
||
:ensure auctex
|
||
:mode ("\\.tex$" . TeX-latex-mode))
|
||
#+END_SRC
|
||
**** LaTeX-Extra
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package latex-extra
|
||
:ensure t
|
||
:diminish latex-extra-mode
|
||
:commands latex-extra-mode
|
||
:init (add-hook 'LaTeX-mode-hook #'latex-extra-mode))
|
||
#+END_SRC
|
||
*** Markdown
|
||
#+HEADER: :noweb-ref packages
|
||
#+begin_src emacs-lisp
|
||
(use-package markdown-mode
|
||
:ensure t
|
||
:mode "\\.md$")
|
||
#+end_src
|
||
** Tools
|
||
*** Flyspell
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package flyspell
|
||
:ensure t
|
||
:commands flyspell-mode
|
||
:diminish flyspell-mode
|
||
:init (mapcar (lambda (mode-hook)
|
||
(add-to-list mode-hook #'flyspell-mode))
|
||
'(text-mode-hook
|
||
org-mode-hook)))
|
||
#+END_SRC
|
||
*** Auto-Fill
|
||
Automatically wrap paragraphs while writing in text modes.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(mapcar (lambda (mode-hook)
|
||
(add-hook mode-hook #'auto-fill-mode))
|
||
'(text-mode-hook
|
||
org-mode-hook))
|
||
#+END_SRC
|
||
*** Unfill
|
||
Re-flowing paragraphs with =fill-paragraph= is nice, but there are
|
||
occasions when it's useful to do the inverse, and get rid of the line
|
||
breaks.
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package unfill
|
||
:ensure t
|
||
:commands (unfill-paragraph
|
||
unfill-region)
|
||
:bind ("M-Q" . unfill-paragraph))
|
||
#+END_SRC
|
||
*** Writegood
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package writegood-mode
|
||
:ensure t
|
||
:commands writegood-mode
|
||
:diminish writegood-mode
|
||
:init (mapcar (lambda (mode-hook)
|
||
(add-hook mode-hook #'writegood-mode))
|
||
'(text-mode-hook
|
||
org-mode-hook)))
|
||
|
||
#+END_SRC
|
||
*** Define Word
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package define-word
|
||
:ensure t
|
||
:bind ("C-c d" . define-word-at-point))
|
||
#+END_SRC
|
||
* Finances
|
||
** Ledger
|
||
|
||
Command-line double-entry accounting system.
|
||
https://www.ledger-cli.org/
|
||
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package ledger-mode
|
||
:ensure t
|
||
:mode "\\.ledger$")
|
||
|
||
#+END_SRC
|
||
* Mail
|
||
** Gnus
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package gnus
|
||
:commands gnus
|
||
:init (progn (defun my/configure-gnus ()
|
||
<<gnus>>
|
||
)
|
||
(setq gnus-before-startup-hook 'my/configure-gnus)))
|
||
#+END_SRC
|
||
*** Avoid rich-text messages
|
||
#+HEADER: :noweb-ref gnus
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq mm-discouraged-alternatives '("text/html" "text/richtext"))
|
||
#+END_SRC
|
||
*** Summary view formatting
|
||
Taken from http://groups.google.com/group/gnu.emacs.gnus/browse_thread/thread/a673a74356e7141f
|
||
|
||
#+HEADER: :noweb-ref gnus
|
||
#+BEGIN_SRC emacs-lisp
|
||
(when window-system
|
||
(setq gnus-sum-thread-tree-indent " ")
|
||
(setq gnus-sum-thread-tree-root "") ;; "● ")
|
||
(setq gnus-sum-thread-tree-false-root "") ;; "◯ ")
|
||
(setq gnus-sum-thread-tree-single-indent "") ;; "◎ ")
|
||
(setq gnus-sum-thread-tree-vertical "│")
|
||
(setq gnus-sum-thread-tree-leaf-with-other "├─► ")
|
||
(setq gnus-sum-thread-tree-single-leaf "╰─► "))
|
||
(setq gnus-summary-line-format
|
||
(concat
|
||
"%0{%U%R%z%}"
|
||
"%3{│%}" "%1{%d%}" "%3{│%}" ;; date
|
||
" "
|
||
"%4{%-20,20f%}" ;; name
|
||
" "
|
||
"%3{│%}"
|
||
" "
|
||
"%1{%B%}"
|
||
"%s\n"))
|
||
(setq gnus-summary-display-arrow t)
|
||
#+END_SRC
|
||
*** Inline images
|
||
#+HEADER: :noweb-ref gnus
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'mm-decode)
|
||
|
||
(add-to-list 'mm-attachment-override-types "image/.*")
|
||
(setq mm-inline-large-images t)
|
||
#+END_SRC
|
||
* Publishing
|
||
** Htmlize
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package htmlize
|
||
:ensure t
|
||
:commands (htmlize-region htmlize-buffer htmlize-file))
|
||
#+END_SRC
|
||
* Source Control
|
||
** Git-Gutter
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package git-gutter
|
||
:ensure t
|
||
:diminish git-gutter-mode
|
||
:bind (("C-x g n" . git-gutter:next-hunk)
|
||
("C-x g p" . git-gutter:previous-hunk))
|
||
:defer 1
|
||
:config
|
||
(progn
|
||
(global-git-gutter-mode t)
|
||
(defadvice ediff-make-temp-file (before make-temp-file-suspend-ll
|
||
activate compile preactivate)
|
||
"Disable git-gutter when running ediff"
|
||
(global-git-gutter-mode 0))
|
||
|
||
(add-hook 'ediff-cleanup-hook
|
||
'(lambda ()
|
||
(global-git-gutter-mode t)))))
|
||
#+END_SRC
|
||
** Magit
|
||
#+HEADER: :noweb-ref packages
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package magit
|
||
:ensure t
|
||
:commands (magit-init
|
||
magit-status
|
||
magit-diff
|
||
magit-commit)
|
||
:bind (("C-c m s" . magit-status)
|
||
("C-c m d" . magit-diff)
|
||
("C-c m c" . magit-commit)
|
||
("C-c m l l" . magit-log-head)
|
||
("C-c m l b" . magit-log-buffer-file)
|
||
("C-c m l r" . magit-reflog-head))
|
||
:config
|
||
(progn
|
||
(defadvice magit-status (around magit-fullscreen activate)
|
||
(window-configuration-to-register :magit-fullscreen)
|
||
ad-do-it
|
||
(delete-other-windows))
|
||
|
||
(defadvice magit-quit-window (around magit-restore-screen activate)
|
||
ad-do-it
|
||
(jump-to-register :magit-fullscreen))))
|
||
|
||
(use-package magit-blame
|
||
:ensure magit
|
||
:commands magit-blame-mode
|
||
:bind ("C-c m b" . magit-blame-addition))
|
||
#+END_SRC
|
||
* Other functionality
|
||
** Disable tab indenting by default
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq-default indent-tabs-mode nil)
|
||
#+END_SRC
|
||
** Prefer encrypted auth sources
|
||
New credentials will be stored in the gpg-encrypted authinfo by
|
||
default.
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq auth-sources '("~/.authinfo.gpg" "~/.authinfo" "~/.netrc"))
|
||
#+END_SRC
|
||
** Rename file and buffer
|
||
Taken from [[http://emacsredux.com/blog/2013/05/04/rename-file-and-buffer/][Emacs Redux]]
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
;; emacsredux.com
|
||
(defun rename-file-and-buffer ()
|
||
"Rename the current buffer and file it is visiting."
|
||
(interactive)
|
||
(let ((filename (buffer-file-name)))
|
||
(if (not (and filename (file-exists-p filename)))
|
||
(message "Buffer is not visiting a file!")
|
||
(let ((new-name (read-file-name "New name: " filename)))
|
||
(cond
|
||
((vc-backend filename) (vc-rename-file filename new-name))
|
||
(t
|
||
(rename-file filename new-name t)
|
||
(rename-buffer new-name)
|
||
(set-visited-file-name new-name)
|
||
(set-buffer-modified-p nil)))))))
|
||
#+END_SRC
|
||
** Eval and Replace
|
||
Taken from [[http://emacsredux.com/blog/2013/06/21/eval-and-replace/][Emacs Redux]]
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun eval-and-replace ()
|
||
"Replace the preceding sexp with its value."
|
||
(interactive)
|
||
(backward-kill-sexp)
|
||
(condition-case nil
|
||
(prin1 (eval (read (current-kill 0)))
|
||
(current-buffer))
|
||
(error (message "Invalid expression")
|
||
(insert (current-kill 0)))))
|
||
|
||
(global-set-key (kbd "C-)") 'eval-and-replace)
|
||
#+END_SRC
|
||
** Smarter navigation to the beginning of a line
|
||
Taken from [[http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/][Emacs Redux]]
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun smarter-move-beginning-of-line (arg)
|
||
"Move point back to indentation of beginning of line.
|
||
|
||
Move point to the first non-whitespace character on this line.
|
||
If point is already there, move to the beginning of the line.
|
||
Effectively toggle between the first non-whitespace character and
|
||
the beginning of the line.
|
||
|
||
If ARG is not nil or 1, move forward ARG - 1 lines first. If
|
||
point reaches the beginning or end of the buffer, stop there."
|
||
(interactive "^p")
|
||
(setq arg (or arg 1))
|
||
|
||
;; Move lines first
|
||
(when (/= arg 1)
|
||
(let ((line-move-visual nil))
|
||
(forward-line (1- arg))))
|
||
|
||
(let ((orig-point (point)))
|
||
(back-to-indentation)
|
||
(when (= orig-point (point))
|
||
(move-beginning-of-line 1))))
|
||
|
||
;; remap C-a to `smarter-move-beginning-of-line'
|
||
(global-set-key [remap move-beginning-of-line]
|
||
'smarter-move-beginning-of-line)
|
||
#+END_SRC
|
||
** Edit file with sudo
|
||
Taken from [[http://www.emacswiki.org/TrampMode#toc32][EmacsWiki]]
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'dired)
|
||
(defun sudo-edit-current-file ()
|
||
(interactive)
|
||
(let ((my-file-name) ; fill this with the file to open
|
||
(position)) ; if the file is already open save position
|
||
(if (equal major-mode 'dired-mode) ; test if we are in dired-mode
|
||
(progn
|
||
(setq my-file-name (dired-get-file-for-visit))
|
||
(find-alternate-file (prepare-tramp-sudo-string my-file-name)))
|
||
(setq my-file-name (buffer-file-name); hopefully anything else is an already opened file
|
||
position (point))
|
||
(find-alternate-file (prepare-tramp-sudo-string my-file-name))
|
||
(goto-char position))))
|
||
|
||
|
||
(defun prepare-tramp-sudo-string (tempfile)
|
||
(if (file-remote-p tempfile)
|
||
(let ((vec (tramp-dissect-file-name tempfile)))
|
||
|
||
(tramp-make-tramp-file-name
|
||
"sudo"
|
||
(tramp-file-name-user nil)
|
||
(tramp-file-name-host vec)
|
||
(tramp-file-name-localname vec)
|
||
(format "ssh:%s@%s|"
|
||
(tramp-file-name-user vec)
|
||
(tramp-file-name-host vec))))
|
||
(concat "/sudo:root@localhost:" tempfile)))
|
||
|
||
(define-key dired-mode-map [s-return] 'sudo-edit-current-file)
|
||
#+END_SRC
|
||
** Backups
|
||
Borrowed from Sacha Chua
|
||
https://github.com/sachac/.emacs.d/
|
||
|
||
This is one of the things people usually want to change right away. By default, Emacs saves backup files in the current directory. These are the files ending in =~= that are cluttering up your directory lists. The following code stashes them all in =~/.emacs.d/backups=, where I can find them with =C-x C-f= (=find-file=) if I really need to.
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+begin_src emacs-lisp
|
||
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
|
||
#+end_src
|
||
|
||
Disk space is cheap. Save lots.
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+begin_src emacs-lisp
|
||
(setq delete-old-versions -1)
|
||
(setq version-control t)
|
||
(setq vc-make-backup-files t)
|
||
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
|
||
#+end_src
|
||
** Disable lock files
|
||
Lock files have only ever gotten in my way.
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq create-lockfiles nil)
|
||
#+END_SRC
|
||
** History
|
||
From http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2014/03/C3F.html
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+begin_src emacs-lisp
|
||
(setq savehist-file "~/.emacs.d/savehist")
|
||
(savehist-mode 1)
|
||
(setq history-length t)
|
||
(setq history-delete-duplicates t)
|
||
(setq savehist-save-minibuffer-history 1)
|
||
(setq savehist-additional-variables
|
||
'(kill-ring
|
||
search-ring
|
||
regexp-search-ring))
|
||
#+end_src
|
||
** Copy filename to clipboard
|
||
|
||
http://emacsredux.com/blog/2013/03/27/copy-filename-to-the-clipboard/
|
||
https://github.com/bbatsov/prelude
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+begin_src emacs-lisp
|
||
(defun prelude-copy-file-name-to-clipboard ()
|
||
"Copy the current buffer file name to the clipboard."
|
||
(interactive)
|
||
(let ((filename (if (equal major-mode 'dired-mode)
|
||
default-directory
|
||
(buffer-file-name))))
|
||
(when filename
|
||
(kill-new filename)
|
||
(message "Copied buffer file name '%s' to the clipboard." filename))))
|
||
#+end_src
|
||
** Prompt for 'y or n' instead of 'yes or no'
|
||
Because typing out "yes" and "no" is irritating.
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defalias 'yes-or-no-p #'y-or-n-p)
|
||
#+END_SRC
|
||
** Support ANSI colors in compilation buffers
|
||
|
||
http://stackoverflow.com/a/13408008
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'ansi-color)
|
||
(defun colorize-compilation-buffer ()
|
||
(toggle-read-only)
|
||
(ansi-color-apply-on-region compilation-filter-start (point))
|
||
(toggle-read-only))
|
||
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
|
||
#+END_SRC
|
||
** Re-bind modifiers on OSX
|
||
|
||
On mac keyboards, the command key placement works better for me as
|
||
Meta rather than the default (Super), because it's right where my
|
||
muscle memory expects a PC keyboard's Alt key.
|
||
|
||
The control keys are typically pretty terrible, too, but I find it
|
||
easier to rebind Caps Lock to Control in the system preferences (which
|
||
is a nice thing to do in other environments, as well).
|
||
|
||
#+HEADER: :noweb-ref other
|
||
#+BEGIN_SRC emacs-lisp
|
||
(when (equal 'darwin system-type)
|
||
;; Command as meta, because alt/option's placement is terrible on
|
||
;; mac keyboards (this doesn't interfere with Spotlight's ⌘-Space
|
||
;; binding)
|
||
(setq ns-command-modifier 'meta))
|
||
#+END_SRC
|
||
* Auto-loading elisp files
|
||
Any elisp files dropped into =~/.emacs.local.d/= will be
|
||
automatically loaded.
|
||
|
||
I usually use this is a testing ground for new configuration before
|
||
adding it here, and also for any personal / sensitive configuration.
|
||
|
||
#+HEADER: :noweb-ref auto-load
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun my/load-elisp-directory (path)
|
||
(let ((file-pattern "\\.elc?$"))
|
||
(when (file-directory-p path)
|
||
(mapcar (lambda (lisp-file)
|
||
(load-file lisp-file))
|
||
(directory-files (expand-file-name path) t file-pattern)))))
|
||
|
||
(my/load-elisp-directory "~/.emacs.local.d")
|
||
#+END_SRC
|
||
* Configuration file layout
|
||
|
||
Here I define the emacs.el file that gets generated by the code in
|
||
this org file.
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle yes :noweb no-export :exports code
|
||
;;;; Do not modify this file by hand. It was automatically generated
|
||
;;;; from `emacs.org` in the same directory. See that file for more
|
||
;;;; information.
|
||
;;;;
|
||
|
||
<<startup>>
|
||
<<custom-settings>>
|
||
<<look-and-feel>>
|
||
<<packages>>
|
||
<<programming>>
|
||
<<autocomplete>>
|
||
<<other>>
|
||
<<auto-load>>
|
||
#+END_SRC
|