Merge branch 'init-cleanup' into 'master'

Begin cleanup of init.org

See merge request max/configs!1
This commit is contained in:
2020-06-25 05:09:21 +00:00

View File

@@ -1,3 +1,19 @@
#+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 #+BEGIN_SRC emacs-lisp
(require 'package) (require 'package)
(setq package-enable-at-startup nil) (setq package-enable-at-startup nil)
@@ -6,7 +22,12 @@
(package-initialize) (package-initialize)
#+END_SRC #+END_SRC
Setup use-package and configure it to always install missing packages. *** =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 #+BEGIN_SRC emacs-lisp
(unless (package-installed-p 'use-package) (unless (package-installed-p 'use-package)
@@ -18,16 +39,7 @@ Setup use-package and configure it to always install missing packages.
(setq use-package-always-ensure t) (setq use-package-always-ensure t)
#+END_SRC #+END_SRC
Automatically update packages one per week. ** Basic Configuration
#+BEGIN_SRC emacs-lisp
(use-package auto-package-update
:ensure t
:config
(setq auto-package-update-delete-old-versions t
auto-package-update-interval 7)
(auto-package-update-maybe))
#+END_SRC
Ensure that emacs doesn't add a custom file which will add Ensure that emacs doesn't add a custom file which will add
configuration that isn't in described this file. configuration that isn't in described this file.
@@ -39,43 +51,16 @@ configuration that isn't in described this file.
Configure some startup parameters. Configure some startup parameters.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(line-number-mode t) (line-number-mode t) ;; enable line numbers
(column-number-mode t) (column-number-mode t) ;; enable column numbers
(setq inhibit-splash-screen t) (setq inhibit-splash-screen t) ;; disable the splash screen on boot
(menu-bar-mode 0) (menu-bar-mode 0) ;; disable the menu bar
(tool-bar-mode 0) (tool-bar-mode 0) ;; disable the tool bar
(scroll-bar-mode 0)
(savehist-mode t) ;; (scroll-bar-mode 0) ;; disable scroll bars
#+END_SRC #+END_SRC
On ChromeOS, M-DEL is mapped to <deletechar>, so remap fix up. *** Deleting
#+BEGIN_SRC emacs-lisp
;; TODO: Figure out how to make this conditional on ChromeOS
(global-set-key (kbd "<deletechar>") 'backward-kill-word)'
#+END_SRC
Winner-mode keeps a history of window configurations. Handy when magit
decides to blow away, or I hit the wrong key and blow away my windows.
#+BEGIN_SRC emacs-lisp
(use-package winner
:init
(winner-mode))
#+END_SRC
Add Purpose for binding a "purpose" to a window, such as "terminal" or
"edit", so only buffers with that purpose may end up in that
window. This helps keep things organized without too much manual
tweaking. You can also save and load window layouts and purposes.
#+BEGIN_SRC emacs-lisp
(use-package window-purpose
:bind (("C-c p s" . purpose-set-window-purpose))
:init (purpose-mode t)
;(purpose-x-kill-setup) ;; This seems to cause slowness in helm
(purpose-x-magit-multi-on))
#+END_SRC
By default, if you a region selected and hit "backspace" it does not 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 actually delete the region, which is weird to me. This changes that
@@ -85,41 +70,158 @@ behavior.
(setq delete-active-region t) (setq delete-active-region t)
#+END_SRC #+END_SRC
**** ChomeOS
On ChromeOS, M-DEL is mapped to <deletechar>, so remap fix up.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package org-journal ;; TODO: Figure out how to make this conditional on ChromeOS
:bind (("C-c C-j" . org-journal-new-entry))) (global-set-key (kbd "<deletechar>") 'backward-kill-word)'
#+END_SRC #+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)
(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 #+BEGIN_SRC emacs-lisp
(use-package org (use-package org
:bind (("C-c c" . org-capture) :bind (("C-c o c" . org-capture)
("C-c l" . org-store-link)) ("C-c o l" . org-store-link))
:config (setq org-capture-templates :custom (initial-major-mode 'org-mode)
(org-src-tab-acts-natively t)
(org-confirm-babel-evalute nil)
(org-capture-templates
'(("b" "Bookmark" entry '(("b" "Bookmark" entry
(file+headline "~/notes/bookmarks.org" "Unsorted") (file+headline "~/notes/bookmarks.org" "Unsorted")
"* %T %^{Title}\n\n Source: %u, %c\n\n %i")))) "* %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 #+END_SRC
Install magit, and explicitly call out with-editor as well, even *** org-journal
though its a requirement for magit.
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
*** Git (=magit=)
Install magit, the emacs porcelain for git.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package magit (use-package magit
:config (setq magit-bury-buffer-function 'magit-mode-quit-window)) :custom (magit-bury-buffer-function 'magit-mode-quit-window))
(use-package with-editor) (use-package with-editor)
#+END_SRC #+END_SRC
*** Terminals (=multi-Term=)
Multi-term is useful for having multiple terminal buffers. Multi-term is useful for having multiple terminal buffers.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package multi-term (use-package multi-term
:config :custom
(add-hook 'term-mode-hook (term-bind-key-alist
(lambda ()
(dolist
(bind
'(("C-<backspace>" . term-send-backward-kill-word) '(("C-<backspace>" . term-send-backward-kill-word)
("C-<delete>" . term-send-forward-kill-word) ("C-<delete>" . term-send-forward-kill-word)
("C-<left>" . term-send-backward-word) ("C-<left>" . term-send-backward-word)
@@ -137,10 +239,11 @@ Multi-term is useful for having multiple terminal buffers.
("M-DEL" . term-send-backward-kill-word) ("M-DEL" . term-send-backward-kill-word)
("M-d" . term-send-forward-kill-word) ("M-d" . term-send-forward-kill-word)
("M-r" . isearch-backward) ("M-r" . isearch-backward)
("M-s" . term-send-forward-kill-word))) ("M-s" . term-send-forward-kill-word))))
(add-to-list 'term-bind-key-alist bind)))))
#+END_SRC #+END_SRC
*** File/command completion (=helm=)
Install helm, a completion framework, and install its functions over Install helm, a completion framework, and install its functions over
some of the usual emacs keybinds. some of the usual emacs keybinds.
@@ -151,36 +254,32 @@ some of the usual emacs keybinds.
("C-x b" . helm-mini) ("C-x b" . helm-mini)
("C-x C-b" . helm-buffers-list) ("C-x C-b" . helm-buffers-list)
("M-y" . helm-show-kill-ring)) ("M-y" . helm-show-kill-ring))
:init (setq helm-split-window-inside-p t)) :custom (helm-split-window-inside-p t))
#+END_SRC #+END_SRC
Install projectile for managing buffers within projects. =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 projectile
:config (projectile-mode))
#+END_SRC
Install ggtags. It requires that the "gtags" executable be in the
users PATH, and is installable on Ubuntu as "global".
#+BEGIN_SRC emacs-lisp
(use-package ggtags)
#+END_SRC
Use helm completions for projectile, multi-term, and projectile.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package helm-gtags) (use-package helm-gtags)
(use-package helm-mt
:bind (("C-c t" . helm-mt)))
(use-package helm-projectile)
#+END_SRC #+END_SRC
Add helm-swoop for searching across multiple buffers. =helm-mt= is integrates =multi-term= with helm. It works nicely to
label and search multiple sesions.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package helm-swoop) (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 #+END_SRC
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
@@ -188,7 +287,52 @@ Add helm-swoop for searching across multiple buffers.
:bind (("C-c b" . helm-purpose-switch-buffer-with-purpose))) :bind (("C-c b" . helm-purpose-switch-buffer-with-purpose)))
#+END_SRC #+END_SRC
Use ws-butler to automatically clean up any trailing whitespace I
*** 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. leave behind. Other lines are left untouched.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
@@ -196,46 +340,40 @@ leave behind. Other lines are left untouched.
:config (ws-butler-global-mode t)) :config (ws-butler-global-mode t))
#+END_SRC #+END_SRC
Scroll buffers so that the cursor doesn't get too close to the top or *** Python (=elpy=)
bottom of the window.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package smooth-scrolling (setq python-shell-interpreter "python3")
:config (smooth-scrolling-mode t))
#+END_SRC
Monokai theme is my theme of choice.
#+BEGIN_SRC emacs-lisp
(use-package monokai-theme)
#+END_SRC
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 #+END_SRC
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package ace-window (use-package elpy
:bind* ("C-x o" . ace-window) :init (elpy-enable))
:init (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
(setq aw-scope 'frame))
#+END_SRC #+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 C-mode configurations. Set tab width to 4, since that's what I'm used
to. to.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(defun my-c-common-hook() (defun my-c-common-hook()
(setq c-hungry-delete-key t) (setq c-hungry-delete-key t)
(setq adaptive-wrap-extra-indent c-basic-offset)
(adaptive-wrap-prefix-mode t) (adaptive-wrap-prefix-mode t)
(toggle-word-wrap t)) (toggle-word-wrap t))
@@ -248,14 +386,6 @@ to.
indent-tabs-mode nil) indent-tabs-mode nil)
#+END_SRC #+END_SRC
#+BEGIN_SRC emacs-lisp
(defconst my-cc-style
'("linux"
(c-offsets-alist . ((innamespace . [0])))))
(c-add-style "my-cc-style" my-cc-style)
#+END_SRC
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package highlight-doxygen (use-package highlight-doxygen
:init (highlight-doxygen-global-mode)) :init (highlight-doxygen-global-mode))
@@ -280,144 +410,7 @@ prevent other buffers from popping into that window. This comes from
(global-set-key (kbd "C-c d") 'toggle-window-dedicated)' (global-set-key (kbd "C-c d") 'toggle-window-dedicated)'
#+END_SRC #+END_SRC
Because ChomeOS maps M-backspace to delete.
#+BEGIN_SRC emacs-lisp
(global-set-key (kbd "<deletechar>") 'backward-kill-word)
#+END_SRC
Configure desktop-save mode to restore lost state on emacs exit.
#+BEGIN_SRC emacs-lisp
(desktop-save-mode 1)
(add-to-list 'desktop-modes-not-to-save 'dired-mode)
(add-to-list 'desktop-modes-not-to-save 'term-mode)
#+END_SRC
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
Cycling forward or backward one buffer is handy when using slighty
more buffers than windows, but helm buffers (and others) can really
add a lot of unhelpful buffers. Instead, filter out "boring" buffers.
Boring buffers can still be found via helm/ibuffer.
#+BEGIN_SRC emacs-lisp
(defun buffer-is-boring (buffer)
(or
(and (string-match-p "^\*" (buffer-name buffer)))
(string-match-p "^magit" (buffer-name buffer))))
(defun buffer-iterate (iter-fun)
(let ((bread-crumb (buffer-name)))
(funcall iter-fun)
(while
(and
(buffer-is-boring (current-buffer))
(not (equal bread-crumb (buffer-name))))
(funcall iter-fun))))
(defun my-next-buffer ()
(interactive)
(buffer-iterate 'next-buffer))
(defun my-previous-buffer ()
(interactive)
(buffer-iterate 'previous-buffer))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
#+END_SRC
#+BEGIN_SRC emacs-lisp
;; source: http://steve.yegge.googlepages.com/my-dot-emacs-file
(defun rename-file-and-buffer (new-name)
"Renames both current buffer and file it's visiting to NEW-NAME."
(interactive "sNew name: ")
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not filename)
(message "Buffer '%s' is not visiting a file!" name)
(if (get-buffer new-name)
(message "A buffer named '%s' already exists!" new-name)
(progn
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil))))))
#+END_SRC
#+BEGIN_SRC emacs-lisp
(use-package clang-format
:commands clang-format clang-format-buffer clang-format-region)
#+END_SRC
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(add-to-list 'auto-mode-alist '("\\.ino\\'" . c++-mode)) (add-to-list 'auto-mode-alist '("\\.ino\\'" . c++-mode))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
#+END_SRC #+END_SRC
#+BEGIN_SRC emacs-lisp
(use-package yaml-mode)
(use-package markdown-mode)
#+END_SRC
#+BEGIN_SRC emacs-lisp
(use-package adaptive-wrap)
#+END_SRC
Add cquery for completions. This requires.
1. The cquery is checked out into ~/software/cquery/ and built.
2. The project has a .cquery file at its root, which specifies all of the includes paths.
#+BEGIN_SRC emacs-lisp
(defun cquery//enable ()
(condition-case nil
(lsp)
(user-error nil)))
(use-package cquery
:commands lsp
:after (:any c-mode c++-mode objc-mode)
:config (setq cquery-executable "~/software/cquery/build/release/bin/cquery")
(add-hook 'c-mode-hook #'cquery//enable)
(add-hook 'c++-mode-hook #'cquery//enable)
;; Do not use projectile for root-matching, since we have multiple git projects that are compiled together
(setq cquery-project-root-matchers '(cquery-project-roots-matcher "compile_commands.json" ".cquery" "build/compile_commands.json"))
(push 'company-lsp company-backends)
)
(use-package company
:init (add-hook 'c-mode-hook company-mode)
(add-hook 'c++-mode-hook company-mode)
)
(use-package company-lsp
:init (push 'company-lsp company-backends))
#+END_SRC
Move backups to somewhere less intrusive.
#+BEGIN_SRC emacs-lisp
(setq backup-directory-alist `(("." . "~/.saves")))
#+END_SRC
Use dumb-jump as a low-configuration option for jump-to-definition/reference.
#+BEGIN_SRC emacs-lisp
(use-package dumb-jump
:config (setq dumb-jump-selector 'helm)
(setq dumb-jump-force-searcher 'ag)
:init (dumb-jump-mode t))
#+END_SRC