;; -*- mode: emacs-lisp; flycheck-mode: nil; -*- ;;;; PRELIMINARIES (defun woz/ensure-directory (path) "Create a directory if it doesn't exist, returning the expanded the path as a file name, not a directory name." (let ((fullpath (expand-file-name path))) (unless (file-accessible-directory-p fullpath) (make-directory fullpath t)) fullpath)) (defconst woz/backup-directory (woz/ensure-directory "~/.local/var/tmp") "Where backup files are stored.") (defvar woz/map (make-sparse-keymap) "Key map for personal keybindings and such. The intent is to bind this to C-c a. (If it's not there, then it's probably time to change this comment.)") (defun woz/show-buffer-file-name () "Display the buffer file name. Seeing the whole file name can be handy sometimes." (interactive) (message "%s" buffer-file-name)) (defun woz/install-selected-packages () "Install any missing packages from `packages-selected-packages' that are not already installed. This will refresh the package contents (which requires network access) only when a package is missing." (let ((pkg-missing nil)) (dolist (pkg package-selected-packages) (unless (package-installed-p pkg) (setq pkg-missing t))) (when pkg-missing (package-refresh-contents) (package-install-selected-packages)))) ;;;; CUSTOMIZE (setq custom-file (concat user-emacs-directory "custom.el")) ;; This contains very little. Just the stuff that is automatically ;; managed in various ways by Emacs. (load custom-file) ;;;; PATH STUFF (add-to-list 'load-path (woz/ensure-directory (concat user-emacs-directory "vendor"))) (add-to-list 'load-path (woz/ensure-directory "~/.local/share/emacs/site-lisp")) (add-to-list 'Info-additional-directory-list (woz/ensure-directory "~/.local/share/info")) ;;;; PACKAGES (require 'package) (package-initialize) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) ;;;; GENERAL STUFF (require 'info) (require 'saveplace) (require 'uniquify) (setq apropos-do-all t confirm-kill-emacs 'y-or-n-p ;; Requires GNU ls, of course. dired-listing-switches "-a -l --dired --group-directories-first --human-readable" display-time-default-load-average nil ediff-window-setup-function 'ediff-setup-windows-plain fill-column 78 inhibit-startup-echo-area-message (user-login-name) inhibit-startup-message t initial-scratch-message "" load-prefer-newer t mouse-yank-at-point t require-final-newline nil ring-bell-function 'ignore save-interprogram-paste-before-kill t save-place-file (concat user-emacs-directory "places") uniquify-buffer-name-style 'post-forward vc-follow-symlinks nil visible-bell nil which-func-modes '(c-mode c++-mode python-mode makefile-mode emacs-lisp-mode sh-mode diff-mode) x-mouse-click-focus-ignore-position nil ;; Backup settings backup-by-copying t backup-directory-alist `(("." . ,woz/backup-directory)) delete-old-versions t kept-new-versions 6 kept-old-versions 2 version-control t ;; Other misc stuff Man-width 80) (setq-default indent-tabs-mode nil) ;; Use a nicer glyph for vertical borders in a terminal. (unless (display-graphic-p) (set-display-table-slot standard-display-table 'vertical-border (make-glyph-code #x2502))) (blink-cursor-mode 0) (column-number-mode 1) (display-time-mode 0) (line-number-mode 1) (menu-bar-mode 0) (save-place-mode 1) (show-paren-mode 1) (tool-bar-mode 0) (which-function-mode 1) (windmove-default-keybindings 'shift) ;;;; KEYBINDINGS ;; The intent is that all keybindings should work in a terminal since ;; that's where I spend most of my time. (global-set-key (kbd "M-i") 'imenu) (global-set-key (kbd "M-/") 'hippie-expand) (global-set-key (kbd "M-DEL") 'kill-region) (global-set-key (kbd "C-w") 'backward-kill-word) (global-set-key (kbd "C-x C-b") 'ibuffer) (global-set-key (kbd "C-s") 'swiper-isearch) (global-set-key (kbd "C-x g") 'magit-status) ;; Bind C-c a to my personal bindings. mode-specific-map should ;; always be C-c. (define-key mode-specific-map (kbd "a") woz/map) ;; The intent is that anything bound to my personal map should work in ;; a terminal. (define-key woz/map (kbd "a") 'woz/show-buffer-file-name) (define-key woz/map (kbd "l") 'comment-line) (define-key woz/map (kbd "r") 'revert-buffer) (define-key woz/map (kbd "[space]") 'just-one-space) ;;;; SHELL (defun woz/shell-mode-hook () (local-set-key (kbd "C-c C-k") 'woz/clear-shell-buffer)) (defun woz/clear-shell-buffer () (interactive) (let ((comint-buffer-maximum-size 0)) (comint-truncate-buffer))) (add-hook 'shell-mode-hook 'woz/shell-mode-hook) ;;;; ESHELL (require 'eshell) (defvar woz/eshell-log-buffer-name "*woz-log*" "Name of the log buffer.") (defun woz/eshell-log-buffer-append (string) "Insert string into the buffer `woz/eshell-log-buffer-name' if the value is a string." (when (stringp string) (with-current-buffer (get-buffer woz/eshell-log-buffer-name) (insert string)))) (defun woz/eshell-prepare-log-buffer (mode) "Setup the log buffer to accept input based on mode. If mode is overwrite, the buffer is cleared. Otherwise, move point to the end of the buffer. The buffer name is `woz/eshell-log-buffer-name'. Returns `woz/eshell-log-buffer-append'." (let ((buf (get-buffer-create woz/eshell-log-buffer-name))) (with-current-buffer buf (if (eq mode 'overwrite) (erase-buffer) (goto-char (point-max)))) 'woz/eshell-log-buffer-append)) (setq eshell-banner-message "") (add-to-list 'eshell-virtual-targets '("/dev/log" woz/eshell-prepare-log-buffer t) t) ;;;; ORG-MODE ;; Seriously, who cares about this... (setq org-html-validation-link nil) ;; Allows for #+BIND in the file, which is useful for settings that ;; can't be done with keywords. (setq org-export-allow-bind-keywords t) ;;;; SOLARIZED THEME (setq solarized-distinct-fringe-background t solarized-use-variable-pitch nil solarized-high-contrast-mode-line t solarized-use-less-bold t solarized-scale-org-headlines nil solarized-height-minus-1 1.0 solarized-height-plus-2 1.0 solarized-height-plus-3 1.0 solarized-height-plus-4 1.0) (load-theme 'solarized-light t) ;;;; MAGIT (require 'magit) ;;;; IVY/COUNSEL/SWIPER (require 'counsel) (setq ivy-use-virtual-buffers t ivy-count-format "(%d/%d) " counsel-find-file-at-point t counsel-preselect-current-file t) (ivy-mode 1) (counsel-mode 1) ;;;; SMARTPARENS (require 'smartparens-config) ;; I keep meaning to configure this but never do. (smartparens-global-mode 1) ;;;; FIC MODE (require 'fic-mode) (setq fic-highlighted-words '("FIXME" "TODO" "BUG" "KLUDGE" "HACK" "NOTE")) (add-hook 'prog-mode-hook 'fic-mode)