436 lines
11 KiB
Org Mode
436 lines
11 KiB
Org Mode
#+PROPERTY: header-args :results silent
|
|
|
|
* Overview
|
|
|
|
This is my personal emacs configuration, which enables my workflow. Highlights include:
|
|
|
|
- =helm= for completion
|
|
- =projectile= for project interaction
|
|
- =magit= for an emacs-based =git= porcelain
|
|
- =org-mode= for note organization and capture
|
|
|
|
** Package Manager Bootstrapping
|
|
*** Setting Repositories
|
|
|
|
First, use =package= to set up additional repos, which will be leveraged later.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(require 'package)
|
|
(setq package-enable-at-startup nil)
|
|
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
|
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))
|
|
(package-initialize)
|
|
#+END_SRC
|
|
|
|
*** =use-package=
|
|
|
|
Setup =use-package= and configure it to always install missing
|
|
packages. This means that emacs will be slow to boot, as it reaches
|
|
out to the network to pull down updated versions. I tend to run emacs
|
|
as a daemon, so this doesn't happen too often.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(unless (package-installed-p 'use-package)
|
|
(package-refresh-contents)
|
|
(package-install 'use-package))
|
|
|
|
(eval-when-compile
|
|
(require 'use-package))
|
|
(setq use-package-always-ensure t)
|
|
#+END_SRC
|
|
|
|
** Basic Configuration
|
|
|
|
Ensure that emacs doesn't add a custom file which will add
|
|
configuration that isn't in described this file.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq custom-file "/dev/null")
|
|
#+END_SRC
|
|
|
|
Configure some startup parameters.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(line-number-mode t) ;; enable line numbers
|
|
(column-number-mode t) ;; enable column numbers
|
|
(setq inhibit-splash-screen t) ;; disable the splash screen on boot
|
|
(menu-bar-mode 0) ;; disable the menu bar
|
|
(tool-bar-mode 0) ;; disable the tool bar
|
|
(if (window-system)
|
|
(scroll-bar-mode nil)) ;; disable scroll bars
|
|
#+END_SRC
|
|
|
|
*** Deleting
|
|
|
|
By default, if you a region selected and hit "backspace" it does not
|
|
actually delete the region, which is weird to me. This changes that
|
|
behavior.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq delete-active-region t)
|
|
#+END_SRC
|
|
|
|
**** ChomeOS
|
|
|
|
On ChromeOS, M-DEL is mapped to <deletechar>, so remap fix up.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
;; TODO: Figure out how to make this conditional on ChromeOS
|
|
(global-set-key (kbd "<deletechar>") 'backward-kill-word)'
|
|
#+END_SRC
|
|
|
|
*** Backups
|
|
|
|
Enable automatic file saves to a location that won't clutter source
|
|
directories.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(savehist-mode t)
|
|
(setq backup-directory-alist '(("." . "~/.emacs_backups")))
|
|
#+END_SRC
|
|
|
|
*** Minions Mode (Hide minor modes)
|
|
|
|
The modeline can get cluttered with lots of minor modes. Use
|
|
=minions-mode= to diminish all of the minor modes, and leave room for
|
|
more important context like major mode, line number, and git branch.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package minions
|
|
:init (minions-mode t))
|
|
#+END_SRC
|
|
|
|
*** Theme
|
|
|
|
Monokai theme is my theme of choice.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package monokai-theme)
|
|
;; This is busted when the font isn't installed (i.e. on MacOS)
|
|
;; (set-frame-font "Ubuntu Mono-12" nil t)
|
|
#+END_SRC
|
|
|
|
*** Navigation
|
|
|
|
Don't use the arrow keys, try to stay on the home row.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(mapc 'global-unset-key '([left] [right] [up] [down] [C-down] [C-up] [C-right] [C-left]))
|
|
#+END_SRC
|
|
|
|
Use zoom-window to enable full-screening a single window, briefly.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package zoom-window
|
|
:bind* ("C-c z z" . zoom-window-zoom))
|
|
#+END_SRC
|
|
|
|
=ace-window= makes it easy to jump between windows. I usually have 3+,
|
|
so this is nice.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package ace-window
|
|
:bind ("C-x o" . ace-window)
|
|
:custom
|
|
(aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
|
|
(aw-scope 'frame))
|
|
#+END_SRC
|
|
|
|
|
|
=smooth-scrolling= makes emacs scroll nicely and keeps the buffer in a
|
|
sane place when the point moves. bottom of the window.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package smooth-scrolling
|
|
:config (smooth-scrolling-mode t))
|
|
#+END_SRC
|
|
|
|
*** Replacement
|
|
|
|
I use replace-string enough to deserve it's own binding.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(global-set-key (kbd "C-c r") 'replace-string)
|
|
#+END_SRC
|
|
|
|
** Org-mode
|
|
|
|
Org-mode is great. As a format, it's fine- but it's emacs integration is powerful
|
|
|
|
Enable =org-capture=, which is intended for jotting down quick
|
|
notes. I don't use it enough, so I haven't fleshed out useful
|
|
templates yet.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package org
|
|
:bind (("C-c o c" . org-capture)
|
|
("C-c o l" . org-store-link))
|
|
:custom (initial-major-mode 'org-mode)
|
|
(org-src-tab-acts-natively t)
|
|
(org-confirm-babel-evaluate nil)
|
|
(org-capture-templates
|
|
'(("b" "Bookmark" entry
|
|
(file+headline "~/notes/bookmarks.org" "Unsorted")
|
|
"* %T %^{Title}\n\n Source: %u, %c\n\n %i")))
|
|
:init (org-babel-do-load-languages 'org-babel-load-languages
|
|
'((shell . t)
|
|
(ruby . t)
|
|
(python . t)
|
|
(C . t))))
|
|
#+END_SRC
|
|
|
|
*** org-journal
|
|
|
|
On the other hand, I do use org-journal for notetaking and searching
|
|
through my notes.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package org-journal
|
|
:bind (("C-c o j c" . org-journal-new-entry)
|
|
("C-c o j s" . org-journal-search-forever)))
|
|
#+END_SRC
|
|
|
|
** Development Tools
|
|
*** General Emacs
|
|
|
|
When doing compilation, always jump to the first error to reduce development cycle times.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq compilation-auto-jump-to-first-error t)
|
|
#+END_SRC
|
|
|
|
*** Dired
|
|
|
|
=dired-tree= allows expanding directories in dired buffers. This is
|
|
nice for pinning a dired buffer to the side to use as a file browser.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package dired-tree)
|
|
#+END_SRC
|
|
|
|
=dired= is great, but too detailed by default. Disable
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package dired
|
|
:hook ((dired . dired-hide-details-mode)
|
|
(dired . (lambda (toggle-truncate-lines t))))
|
|
:bind ("<TAB>" . dired-subtree-toggle))
|
|
#+END_SRC
|
|
*** Git (=magit=)
|
|
|
|
Install magit, the emacs porcelain for git.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package magit
|
|
:custom (magit-bury-buffer-function 'magit-mode-quit-window))
|
|
|
|
(use-package with-editor)
|
|
#+END_SRC
|
|
|
|
*** Terminals (=multi-Term=)
|
|
|
|
Multi-term is useful for having multiple terminal buffers.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package multi-term
|
|
:custom
|
|
(term-bind-key-alist
|
|
'(("C-<backspace>" . term-send-backward-kill-word)
|
|
("C-<delete>" . term-send-forward-kill-word)
|
|
("C-<left>" . term-send-backward-word)
|
|
("C-<right>" . term-send-forward-word)
|
|
("C-c C-j" . term-line-mode)
|
|
("C-c C-k" . term-char-mode)
|
|
("C-c C-c" . term-interrupt-subjob)
|
|
("C-r" . term-send-reverse-search-history)
|
|
("C-v" . scroll-up)
|
|
("C-y" . term-paste)
|
|
("C-z" . term-stop-subjob)
|
|
("C-p" . term-send-prior)
|
|
("C-n" . term-send-next)
|
|
("M-p" . scroll-up-line)
|
|
("M-n" . scroll-down-line)
|
|
("M-DEL" . term-send-backward-kill-word)
|
|
("M-d" . term-send-forward-kill-word)
|
|
("M-r" . isearch-backward)
|
|
("M-s" . term-send-forward-kill-word))))
|
|
#+END_SRC
|
|
|
|
*** File/command completion (=helm=)
|
|
|
|
Install helm, a completion framework, and install its functions over
|
|
some of the usual emacs keybinds.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package helm
|
|
:config (helm-mode)
|
|
:bind (("M-x" . helm-M-x)
|
|
("C-x b" . helm-mini)
|
|
("C-x C-b" . helm-buffers-list)
|
|
("M-y" . helm-show-kill-ring))
|
|
:custom (helm-split-window-inside-p t))
|
|
#+END_SRC
|
|
|
|
=helm-gtags= works nicely for finding tags/references. Though it has
|
|
confused me many times, =helm-gtags= does not depend on =ggtags=.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package helm-gtags)
|
|
#+END_SRC
|
|
|
|
=helm-mt= is integrates =multi-term= with helm. It works nicely to
|
|
label and search multiple sesions.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package helm-mt
|
|
:bind (("C-c t" . helm-mt)))
|
|
#+END_SRC
|
|
|
|
=Helm-projectile= integrates helm with projectile, which makes it very
|
|
easy to search for files in a given project.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package helm-projectile
|
|
:bind (("C-c p f" . helm-projectile))
|
|
:init (add-to-list 'helm-mini-default-sources 'helm-projectile-sources-list)
|
|
(helm-projectile-on))
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package helm-purpose
|
|
:bind (("C-c b" . helm-purpose-switch-buffer-with-purpose)))
|
|
#+END_SRC
|
|
|
|
|
|
|
|
*** Code completion (=company=)
|
|
|
|
Company is great for doing completion. It probably deserves more
|
|
configuration than I'm giving it.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package company
|
|
:init (global-company-mode))
|
|
#+END_SRC
|
|
|
|
*** Projects (=projectile=)
|
|
|
|
Install projectile for managing buffers within projects.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package projectile
|
|
:config (projectile-mode)
|
|
:bind (("C-c p c" . projectile-compile-project)
|
|
("C-c p t" . projectile-test-project))
|
|
:custom (projectil-completion-system 'helm))
|
|
#+END_SRC
|
|
|
|
*** Licenses (=lice=)
|
|
|
|
=lice= makes it easy to drop the MIT license into all of my code.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package lice
|
|
:custom (lice:copyright-holder "Max Regan")
|
|
(lice:default-license "mit" "MIT is my default license"))
|
|
#+END_SRC
|
|
|
|
|
|
Use the builtin =hs-minor-mode= to hide the initial comment in code
|
|
files- usually its a big license notice.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(add-hook 'prog-mode-hook #'hs-minor-mode)
|
|
(add-hook 'hs-minor-mode-hook 'hs-hide-initial-comment-block)
|
|
#+END_SRC
|
|
|
|
*** Whitespace (=ws-butler=)
|
|
|
|
Use =ws-butler= to automatically clean up any trailing whitespace I
|
|
leave behind. Other lines are left untouched.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package ws-butler
|
|
:config (ws-butler-global-mode t))
|
|
#+END_SRC
|
|
|
|
*** Python (=elpy=)
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq python-shell-interpreter "python3")
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package elpy
|
|
:init (elpy-enable))
|
|
#+END_SRC
|
|
|
|
|
|
*** C/C++
|
|
|
|
TBD
|
|
|
|
*** Other languages
|
|
|
|
Add major modes for other languages/filetypes that I work with on occasion.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package yaml-mode)
|
|
(use-package markdown-mode)
|
|
#+END_SRC
|
|
|
|
* Uncategorized
|
|
|
|
C-mode configurations. Set tab width to 4, since that's what I'm used
|
|
to.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun my-c-common-hook()
|
|
(setq c-hungry-delete-key t)
|
|
(setq adaptive-wrap-extra-indent c-basic-offset)
|
|
(adaptive-wrap-prefix-mode t)
|
|
(toggle-word-wrap t))
|
|
|
|
(add-hook 'c-mode-common-hook 'my-c-common-hook)
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(setq-default c-basic-offset 4
|
|
tab-width 4
|
|
indent-tabs-mode nil)
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package highlight-doxygen
|
|
:init (highlight-doxygen-global-mode))
|
|
#+END_SRC
|
|
|
|
Add the ability to toggle a buffer as dedicated to its window, to
|
|
prevent other buffers from popping into that window. This comes from
|
|
[[https://emacs.stackexchange.com/questions/2189][StackOverflow]].
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(defun toggle-window-dedicated ()
|
|
"Control whether or not Emacs is allowed to display another
|
|
buffer in current window."
|
|
(interactive)
|
|
(message
|
|
(if (let (window (get-buffer-window (current-buffer)))
|
|
(set-window-dedicated-p window (not (window-dedicated-p window))))
|
|
"%s is dedicated to the window."
|
|
"%s is released from the window.")
|
|
(current-buffer)))
|
|
|
|
(global-set-key (kbd "C-c d") 'toggle-window-dedicated)'
|
|
#+END_SRC
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(add-to-list 'auto-mode-alist '("\\.ino\\'" . c++-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
|
|
#+END_SRC
|