#+BEGIN_SRC emacs-lisp (require 'package) (setq package-enable-at-startup nil) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")) (package-initialize) #+END_SRC Setup use-package and configure it to always install missing packages. #+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 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 (set-background-color "#000000") (line-number-mode t) (column-number-mode t) (setq inhibit-splash-screen t) (menu-bar-mode 0) (tool-bar-mode 0) (scroll-bar-mode 0) (savehist-mode t) #+END_SRC On ChromeOS, M-DEL is mapped to , so remap fix up. #+BEGIN_SRC emacs-lisp ;; TODO: Figure out how to make this conditional on ChromeOS (global-set-key (kbd "") '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 (winner-mode t) #+END_SRC 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 #+BEGIN_SRC emacs-lisp (use-package org-journal :bind (("C-c C-j" . org-journal-new-entry))) #+END_SRC #+BEGIN_SRC emacs-lisp (use-package org :bind (("C-c c" . org-capture) ("C-c l" . org-store-link)) :config (setq org-capture-templates '(("b" "Bookmark" entry (file+headline "~/notes/bookmarks.org" "Unsorted") "* %T %^{Title}\n\n Source: %u, %c\n\n %i")))) #+END_SRC Install magit, and explicitly call out with-editor as well, even though its a requirement for magit. #+BEGIN_SRC emacs-lisp (use-package magit) (use-package with-editor) #+END_SRC Multi-term is useful for having multiple terminal buffers. #+BEGIN_SRC emacs-lisp (use-package multi-term :config (add-hook 'term-mode-hook (lambda () (dolist (bind '(("C-" . term-send-backward-kill-word) ("C-" . term-send-forward-kill-word) ("C-" . term-send-backward-word) ("C-" . term-send-forward-word) ("C-c C-j" . term-line-mode) ("C-c C-k" . term-char-mode) ("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))) (add-to-list 'term-bind-key-alist bind))))) #+END_SRC Eyebrowse is a package for managing multiple simultaneous window configurations. #+BEGIN_SRC emacs-lisp (use-package eyebrowse :config (eyebrowse-mode t)) #+END_SRC 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-c b" . helm-mini) ("C-x C-b" . helm-buffers-list) ("C-x b" . helm-buffers-list) ("M-y" . helm-show-kill-ring))) #+END_SRC Install projectile for managing buffers within projects. #+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 (use-package helm-gtags) (use-package helm-mt :bind (("C-c t" . helm-mt))) (use-package helm-projectile) #+END_SRC Add helm-swoop for searching across multiple buffers. #+BEGIN_SRC emacs-lisp (use-package helm-swoop) #+END_SRC 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 Scroll buffers so that the cursor doesn't get too close to the top or bottom of the window. #+BEGIN_SRC emacs-lisp (use-package smooth-scrolling :config (smooth-scrolling-mode t)) #+END_SRC Tango dark is my standard of the last few years. #+BEGIN_SRC emacs-lisp (load-theme 'tango-dark) #+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 Disable the mouse too. I don't really need it. #+BEGIN_SRC emacs-lisp (use-package disable-mouse :config (global-disable-mouse-mode)) #+END_SRC #+BEGIN_SRC emacs-lisp (use-package ace-window :bind* ("C-x o" . ace-window) :init (progn (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) (setq aw-scope 'frame))) #+END_SRC C-mode configurations. Set tab width to 4, since that's what I'm used to. #+BEGIN_SRC emacs-lisp (setq c-default-style "linux" c-basic-offset 4) (setq-default c-basic-offset 4 tab-width 4 indent-tabs-mode nil) (add-hook 'c-mode-hook (lambda () (setq c-hungry-delete-key t))) #+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 Because ChomeOS maps M-backspace to delete. #+BEGIN_SRC emacs-lisp (global-set-key (kbd "") '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 (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 (add-to-list 'auto-mode-alist '("\\.ino\\'" . c++-mode)) #+END_SRC