#+TITLE: qDot's Emacs Configuration #+AUTHOR: Kyle Machulis #+EMAIL: kyle at machul dot is #+STARTUP: align fold nodlcheck content #+OPTIONS: H:4 num:nil toc:t \n:nil @:t ::t |:t ^:{} -:t f:t *:t #+OPTIONS: skip:nil d:(HIDE) tags:not-in-toc #+PROPERTY: header-args :results none :noweb yes :tangle tangle/emacs_conf.el #+HTML_HEAD: #+LANGUAGE: en #+PROPERTY: comments both * Documentation :PROPERTIES: :EXPORT_FILE_NAME: ./build/Documentation :END: ** Handling Multiple Configuration Blocks Some of the packages I use require a LOT of initialization. mu4e, org-mode, and erc all contain small novels worth of config. In order to provide literate programming descriptions of multiple configuration blocks for a package, I tangle large configs into their own files using properties in the org tree. I leave the use-package call in the main org file, and call load-file on the tangled file from the config block of use-package. ** Config References - https://raw.githubusercontent.com/andreaswilm/my-dot-emacs/master/my-dot-emacs - http://p.writequit.org/org/settings.html * Init File :PROPERTIES: :header-args: :tangle tangle/init.el :END: This section generates the .emacs file, which then loads everything else. It sets up directory variables, loads package, use-package, and org, then calls org-babel-load-file on emacs_conf.org. That will load the rest of the packages and settings, re-tangling the org file before loading if there have been changes, ** Startup Timing :PROPERTIES: :ID: 5c3536bb-87ad-4744-b60a-466e8032de01 :END: Take the time at the beginning of load, then use it at the end to see how long it took to load packages. #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-start-time (current-time)) #+END_SRC ** Directory Configuration :PROPERTIES: :ID: ec9353db-3243-4f6a-acad-c502c5209640 :END: Setting up a few different variables for the different types of directories we have (configurations, locally stored versus el-get fetched libs, etc...) - Set up the base configuration directory and filename #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-conf-dir "~/.emacs_files/" "Directory for emacs configuration") (defconst qdot/emacs-conf-file (expand-file-name (concat qdot/emacs-conf-dir "emacs_conf.org")) "Org-babel file for emacs configuration") #+END_SRC - config compilation directory #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-conf-tangle-dir (expand-file-name (concat qdot/emacs-conf-dir "tangle/")) "Directory for tangled, compiled configuration files") (defconst qdot/emacs-conf-tangle-file (expand-file-name (concat qdot/emacs-conf-dir "tangle/emacs_conf.el")) "Directory for tangled, compiled configuration files") #+END_SRC - Manually installed/maintained elisp directory #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-elisp-dir (expand-file-name (concat qdot/emacs-conf-dir "elisp/")) "Directory for manually installed/maintained elisp files") #+END_SRC - package directory #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-package-dir (expand-file-name (concat qdot/emacs-conf-dir "packages/")) "Directory for elisp packages from elpa/melpa") #+END_SRC - packages that aren't in MELPA/ELPA/etc that we have to maintain repos for. Things like mu, as well as packages I'm actively developing at the moment. #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-dev-package-dir (expand-file-name (concat qdot/emacs-conf-dir "dev-packages/")) "Directory for elisp packages for which we pull and/or maintain repos") #+END_SRC - yasnippets directory #+BEGIN_SRC emacs-lisp (defconst qdot/emacs-snippets-dir (expand-file-name (concat qdot/emacs-conf-dir "snippets/")) "Directory for snippets for yasnippet") #+END_SRC - As of emacs 23, ~/.emacs.d is user-emacs-directory #+BEGIN_SRC emacs-lisp (setq custom-file (concat user-emacs-directory "emacs_conf_custom.el")) (if (not (file-exists-p custom-file)) (with-temp-buffer (write-file custom-file))) (load-file custom-file) #+END_SRC - Add configuration and scripts directories to proper variables #+BEGIN_SRC emacs-lisp (add-to-list 'load-path (expand-file-name qdot/emacs-conf-dir)) (add-to-list 'load-path (expand-file-name qdot/emacs-conf-tangle-dir)) (add-to-list 'load-path (expand-file-name qdot/emacs-elisp-dir)) #+END_SRC ** Load Package Packages *** package.el :package: :PROPERTIES: :ID: f27a5bc9-06d7-4629-802d-1a19266ca486 :END: Just use the built-in package manager, but add melpa/elpa/bleeding edge package repos. #+BEGIN_SRC emacs-lisp (setq package-enable-at-startup nil package-archives '(("gnu" . "http://elpa.gnu.org/packages/") ("marmalade" . "http://marmalade-repo.org/packages/") ("melpa" . "http://melpa.org/packages/") ("org" . "http://orgmode.org/elpa/") ("elpy" . "http://jorgenschaefer.github.io/packages/")) package-user-dir qdot/emacs-package-dir) (package-initialize) #+END_SRC *** use-package :package: :PROPERTIES: :ID: 3bf5b360-937f-45ce-b524-a582fd0a8a7a :END: use-package keeps package loading clean and delayed until the last possible second. Using the :ensure command means that this config file also works as a package manifest when bringing up a new config instance, though that rarely happens. As of version 2.0, use-package no longer needs to be loaded except when compiling, but diminish and bind-key will still be required, so bring those in now. #+BEGIN_SRC emacs-lisp (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (setq use-package-verbose t) (eval-when-compile (require 'use-package)) (require 'bind-key) ;; Add the ability to bind key chords using use-package :bind style. (use-package use-package-chords :ensure t :config (key-chord-mode 1)) #+END_SRC ** Load org-mode :PROPERTIES: :ID: cf822e31-fd2d-42da-ac40-5a13cc550510 :END: We need org-mode here to run org-babel on the file. Loading this early is fine, as it's pretty much guaranteed that org-mode will get used during a session. #+BEGIN_SRC emacs-lisp (use-package org :ensure org-plus-contrib :commands (org-agenda) :bind (("C-c l" . org-store-link) ("C-c a" . org-agenda) ("C-M-r" . org-capture)) :mode (("\\.org_archive\\'" . org-mode) ("\\.org\\'" . org-mode) ("\\.trello\\'" . org-mode)) :config (require 'qdot-org-config)) #+END_SRC ** Recompile Config Function :PROPERTIES: :ID: de1064a9-9a9f-475b-88b5-ecf9b383568f :END: This function tangles the config file, removes all old byte compiled files, and byte compiles all files that were tangled. #+BEGIN_SRC emacs-lisp (defun qdot/tangle-and-compile-config () (interactive) (org-babel-tangle-file qdot/emacs-conf-file) (mapcar (lambda (file) (delete-file file)) (directory-files qdot/emacs-conf-tangle-dir t ".+\\.elc$" nil)) (mapcar (lambda (file) (byte-compile-file file)) (directory-files qdot/emacs-conf-tangle-dir t "^\\([^.]\\|\\.[^.]\\|\\.\\..\\)" nil))) #+END_SRC Unfortunately, trying to run org-babel-load-file on a file that tangles out to multiple files has some bugs. It tries to load all tangled files, based on the relative path of where org-babel-load-file was called from. Since I tangle to a subdirectory, this is wrong. Not only that, I want these files evaluated during requires. So, I ripped out the portion of org-babel-load-file that checks whether it should update the file, and use that to check whether or not I should run tangle-and-compile-config. #+BEGIN_SRC emacs-lisp (defun qdot/build-conf-if-needed () (let* ((file qdot/emacs-conf-file) (exported-file qdot/emacs-conf-tangle-file) (age (lambda (file) (float-time (time-subtract (current-time) (nth 5 (or (file-attributes (file-truename file)) (file-attributes file)))))))) ;; tangle if the org-mode file is newer than the elisp file (unless (and (file-exists-p exported-file) (> (funcall age file) (funcall age exported-file))) (require 'ob-tangle) (qdot/tangle-and-compile-config)))) #+END_SRC ** Load exwm if needed :PROPERTIES: :ID: 2551c65d-6c7e-4041-9f0d-dcf3051222ca :END: If emacs is coming up as a window manager, exwm will be loaded. Otherwise, the load will just throw silently and we'll continue on. #+BEGIN_SRC emacs-lisp (use-package exwm :ensure t :disabled (not linux-p)) #+END_SRC ** Load org configuration file :PROPERTIES: :ID: 851beff4-dfe5-487a-b165-597c3cfb6cbd :END: Debug on error is turned on during configuration file loading so backtraces pop up if something goes wrong. #+BEGIN_SRC emacs-lisp (add-hook 'after-init-hook `(lambda () (setq debug-on-error t) (qdot/build-conf-if-needed) (load-file qdot/emacs-conf-tangle-file) (setq debug-on-error nil))) #+END_SRC * Basic Setup ** Variables :PROPERTIES: :ID: 72ec9b7d-1bda-45e4-a54c-ecd6e2d99595 :END: Anything in this section relates to the core setup of emacs. At this point, there are no packages loaded, so this is just for setting up emacs defaults. Set up basic identity #+BEGIN_SRC emacs-lisp (setq user-mail-address "kyle@nonpolynomial.com" user-full-name "Kyle Machulis") #+END_SRC Prefer UTF-8 everywhere #+BEGIN_SRC emacs-lisp (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) (set-language-environment "UTF-8") (prefer-coding-system 'utf-8) #+END_SRC Set up some simple platform finding variables #+BEGIN_SRC emacs-lisp (defvar mswindows-p (eq system-type 'windows-nt) "True if using windows, nil otherwise") (defvar macosx-p (eq system-type 'darwin) "True if using Mac OS X, nil otherwise") (defvar linux-p (eq system-type 'gnu/linux) "True if using Linux, nil otherwise") #+END_SRC Don't need startup screens. Use both the regular and byte-compiled versions of inhibit-startup-echo-area-message. #+BEGIN_SRC emacs-lisp (setq inhibit-startup-message t) ;; Leave both of these, they're needed for either regular or bytecode bringup. (setq inhibit-startup-echo-area-message "qdot") (eval '(setq inhibit-startup-echo-area-message "qdot")) (setq inhibit-splash-screen t) #+END_SRC Turn off Bell Functions #+BEGIN_SRC emacs-lisp (setq visible-bell nil) (setq ring-bell-function 'ignore) #+END_SRC Set up meta on OS X/Linux to be where I expect them. #+BEGIN_SRC emacs-lisp (when macosx-p ;;avoid hiding with M-h (setq mac-pass-command-to-system nil)) (when linux-p (setq x-alt-keysym 'meta)) #+END_SRC Don't end sentences with a double space. This is important for fill functions. #+BEGIN_SRC emacs-lisp (setq sentence-end-double-space nil) #+END_SRC Even if we start the process in another directory, always set home to default. #+BEGIN_SRC emacs-lisp (setq default-directory "~/") #+END_SRC Make sure message log is really, really big in case I screw something up. #+BEGIN_SRC emacs-lisp (setq message-log-max 5000) #+END_SRC Fix cut/paste on linux #+BEGIN_SRC emacs-lisp (when linux-p (setq ;; copy emacs clipboard to system x-select-enable-clipboard t interprogram-paste-function 'x-cut-buffer-or-selection-value)) #+END_SRC Always show when there's empty lines at the end of a buffer #+BEGIN_SRC emacs-lisp (set-default 'indicate-empty-lines t) #+END_SRC Reset yes-or-no-p to y-or-n-p, and make sure there's no dialog on platforms that might try to bring one up. https://superuser.com/questions/125569/how-to-fix-emacs-popup-dialogs-on-mac-os-x #+BEGIN_SRC emacs-lisp (fset 'yes-or-no-p 'y-or-n-p) (when macosx-p (defadvice yes-or-no-p (around prevent-dialog activate) "Prevent yes-or-no-p from activating a dialog" (let ((use-dialog-box nil)) ad-do-it)) (defadvice y-or-n-p (around prevent-dialog-yorn activate) "Prevent y-or-n-p from activating a dialog" (let ((use-dialog-box nil)) ad-do-it))) #+END_SRC Put autosave files (ie #foo#) in one place, *not* scattered all over the file system #+BEGIN_SRC emacs-lisp (defvar qdot/autosave-dir (concat user-emacs-directory "autosaves/")) (make-directory qdot/autosave-dir t) (defun qdot/auto-save-file-name-p (filename) (string-match "^#.*#$" (file-name-nondirectory filename))) (setq auto-save-file-name-transforms `((".*" ,qdot/autosave-dir t))) #+END_SRC Put backup files (ie foo~) in one place too. (The backup-directory-alist list contains regexp=>directory mappings; filenames matching a regexp are backed up in the corresponding directory. Emacs will mkdir it if necessary.) #+BEGIN_SRC emacs-lisp (defvar qdot/backup-dir (expand-file-name (concat user-emacs-directory "backups/"))) (make-directory qdot/backup-dir t) (setq backup-by-copying t ; don't clobber symlinks backup-directory-alist '(("." . "~/.emacs.d/backups")) ; don't litter my fs tree delete-old-versions t kept-new-versions 6 kept-old-versions 2 version-control t) ; use versioned backups #+END_SRC Enable erase-buffer, since it's handy for shell/irc/etc. #+BEGIN_SRC emacs-lisp (put 'erase-buffer 'disabled nil) #+END_SRC Enable narrow-to-region #+BEGIN_SRC emacs-lisp (put 'narrow-to-region 'disabled nil) #+END_SRC Make sure page up and page down are symmetric, so M-v undoes C-v perfectly. #+BEGIN_SRC emacs-lisp (setq scroll-preserve-screen-position 'always) #+END_SRC When on a mac, make command meta. #+BEGIN_SRC emacs-lisp (when macosx-p (setq mac-command-modifier 'meta) (setq mac-option-modifier nil)) #+END_SRC ** Global Minor Modes :PROPERTIES: :ID: ea0c032d-9615-4d07-8813-e47d225d0916 :END: Save minibuffer history, so oft-used functions bubble to the top. #+BEGIN_SRC emacs-lisp (savehist-mode 1) (setq savehist-file (concat user-emacs-directory "savehist")) (setq savehist-save-minibuffer-history 1) (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring)) #+END_SRC Actually show the region we're selecting when marking. #+BEGIN_SRC emacs-lisp (transient-mark-mode t) #+END_SRC If a file is reverted outside of emacs, and its buffer has NOT been edited inside emacs, automatically revert it. #+BEGIN_SRC emacs-lisp (global-auto-revert-mode t) #+END_SRC Transparently open compressed files. #+BEGIN_SRC emacs-lisp (auto-compression-mode t) #+END_SRC Save a list of recent files visited. #+BEGIN_SRC emacs-lisp (setq recentf-auto-cleanup 'never) (recentf-mode 1) #+END_SRC When region active, delete actually deletes it. #+BEGIN_SRC emacs-lisp (delete-selection-mode 1) #+END_SRC Just expect font lock to be on everywhere. #+BEGIN_SRC emacs-lisp (global-font-lock-mode 1) #+END_SRC If we want to delete something, mark+write should be fine. #+BEGIN_SRC emacs-lisp (delete-selection-mode 1) #+END_SRC ** Display, Font, and Modeline setup :PROPERTIES: :ID: f9259321-db74-433c-b3f2-a1956d33b39e :END: Use fonts we either know we have, or can check for. #+BEGIN_SRC emacs-lisp (when (window-system) (cond ((member "Fira Code" (font-family-list)) (progn (set-face-font 'default "Fira Code-10") (set-face-font 'mode-line "Fira Code-9") (set-face-font 'mode-line-inactive "Fira Code-9") (set-face-font 'mode-line-buffer-id "Fira Code-9") (set-face-font 'header-line "Fira Code-9"))) ((member "Inconsolata" (font-family-list)) (progn (set-face-font 'default "inconsolata-11") (set-face-font 'mode-line "inconsolata-10") (set-face-font 'mode-line-inactive "inconsolata-10") (set-face-font 'mode-line-buffer-id "inconsolata-10") (set-face-font 'header-line "inconsolata-10"))) ((member "Consolas" (font-family-list)) (progn (set-face-font 'default "consolas-11") (set-face-font 'mode-line "consolas-10") (set-face-font 'mode-line-inactive "consolas-10") (set-face-font 'mode-line-buffer-id "consolas-10") (set-face-font 'header-line "consolas-10"))))) #+END_SRC Set up modeline and display variables. Removes all bars, be they scroll or menu, adds date/time to modeline, etc. Redisplay trick taken from http://www.masteringemacs.org/articles/2011/10/02/improving-performance-emacs-display-engine/ #+BEGIN_SRC emacs-lisp (setq display-time-24hr-format t) (setq display-time-day-and-date t) (setq display-time-format "%H:%M") (setq display-time-default-load-average nil) ;; Turn off new mail display completely, as emacs doesn't even know where to look. (setq display-time-mail-string "") (display-time) (line-number-mode t) (column-number-mode t) (tool-bar-mode -1) (menu-bar-mode -1) (scroll-bar-mode -1) (blink-cursor-mode -1) #+END_SRC * exwm setup :PROPERTIES: :ID: c64f8704-3af7-40c8-b9aa-cad0466eca70 :END: Setup taken from https://github.com/technomancy/dotfiles/blob/master/.emacs.d/phil/wm.el #+BEGIN_SRC emacs-lisp (when (and window-system linux-p (require 'exwm nil t)) (use-package exwm-config :after exwm) (exwm-config-default) (exwm-input-set-key (kbd "s-b") #'ivy-switch-buffer) (require 'exwm-systemtray) (exwm-systemtray-enable) ;; If x-alt-keysym is set, M-x mysteriously stops working in applications. (setq x-alt-keysym nil) (add-hook 'exwm-manage-finish-hook (defun qdot/exwm-manage-hook () (when (string= exwm-class-name "xterm") (exwm-input-release-keyboard)) (when (string-match "Chromium" exwm-class-name) (exwm-layout-hide-mode-line)) (when (string-match "Nightly" exwm-class-name) (exwm-layout-hide-mode-line)) (when (string-match "Google-chrome" exwm-class-name) (exwm-layout-hide-mode-line)) (when (string-match "slack" exwm-class-name) (exwm-layout-hide-mode-line)) (when (string-match "Discord" exwm-class-name) (exwm-layout-hide-mode-line)) (when (string-match "TelegramDesktop" exwm-class-name) (exwm-layout-hide-mode-line)) (when (string-match "Firefox" exwm-class-name) (exwm-layout-hide-mode-line)))) (exwm-input-set-simulation-keys (mapcar (lambda (c) (cons (kbd (car c)) (cdr c))) `(("C-b" . left) ("C-f" . right) ("C-p" . up) ("C-n" . down) ("C-a" . home) ("C-e" . end) ("M-v" . prior) ("C-v" . next) ("C-d" . delete) ("C-m" . return) ("C-i" . tab) ("C-g" . escape) ("C-s" . ?\C-f) ("C-y" . ?\C-v) ("M-w" . ?\C-c) ("M-<" . C-home) ("M->" . C-end) ("C-M-a" . ?\C-a) ("C-M-h" . C-backspace))))) #+END_SRC * Package Configuration This section contains installation and configuration information for all the packages I use. In order to quickly access configurations, the org nodes are named after the mode the package exposes, as well as having each configuration node tagged with the 'package' tag. Using the qdot/edit-org-package-config and qdot/edit-current-major-mode-config functions in the qdot-funcs module allows me to easily access configurations without having to search through the org file. ** Emacs Customization *** browse-kill-ring :package: :PROPERTIES: :ID: ab8ede0f-6d07-4c40-b15d-f332451e2be3 :END: See and update/select kill ring history. #+BEGIN_SRC emacs-lisp (use-package browse-kill-ring :ensure browse-kill-ring :commands browse-kill-ring) #+END_SRC *** color-theme-modern :package: :PROPERTIES: :ID: 7c99ab9c-17b5-410e-a715-57c75629ba40 :END: I tend to use dark themes everywhere, be it laptop or desktop. #+BEGIN_SRC emacs-lisp (use-package color-theme-modern :ensure color-theme-modern :config (load-theme 'dark-laptop t t) (enable-theme 'dark-laptop)) #+END_SRC *** counsel :package: :PROPERTIES: :ID: 550e03f5-77bb-443d-a2f5-5a45acd9bc1b :END: #+BEGIN_SRC emacs-lisp (use-package counsel :ensure t :bind (("M-x" . counsel-M-x) ("C-x C-f" . counsel-find-file))) #+END_SRC *** dired :package: :PROPERTIES: :ID: 7beed05f-7c79-420e-9633-12e25680360d :END: Set up dired with extensions, make sure beginning/end commands move inside directory listings instead of buffer. wdired allows text editing of the dired buffer to do things like changing permissions via string/regexp replacement. #+BEGIN_SRC emacs-lisp (use-package dired :commands dired :config (progn ;; Additions to dired ;; http://nflath.com/2009/07/dired/ (require 'dired-x) (require 'wdired) (setq wdired-allow-to-change-permissions 'advanced) ;; dired modifications (bind-keys :map dired-mode-map ("C-s" . dired-isearch-filenames-regexp) ("C-M-s" . dired-isearch-filenames) ("r" . wdired-change-to-wdired-mode)) ;; http://whattheemacsd.com//setup-dired.el-02.html (defun dired-back-to-top () (interactive) (beginning-of-buffer) (dired-next-line (if dired-omit-mode 2 4))) (define-key dired-mode-map (vector 'remap 'beginning-of-buffer) 'dired-back-to-top) (defun dired-jump-to-bottom () (interactive) (end-of-buffer) (dired-next-line -1)) (define-key dired-mode-map (vector 'remap 'end-of-buffer) 'dired-jump-to-bottom))) #+END_SRC *** edit-indirect :package: :PROPERTIES: :ID: 303c8e2d-155c-4aa5-9669-01a65ea2a5c7 :END: #+begin_src emacs-lisp (use-package edit-indirect :ensure t) #+end_src *** exec-path-from-shell :package: :PROPERTIES: :ID: ebfa1dc5-d67d-4cda-8533-eace92ddfc92 :END: Pulls environment variable values from shell when emacs is run in GUI mode on Macs (otherwise system defaults are used). #+BEGIN_SRC emacs-lisp (use-package exec-path-from-shell :ensure t :config (when (memq window-system '(mac ns)) (exec-path-from-shell-initialize))) #+END_SRC *** expand-region :package: :PROPERTIES: :ID: 811e48ae-92ca-4d2f-a343-3048b3c61ef7 :END: Hit C-=, expand up to the next largest region based on mode-context sensitive scope. #+BEGIN_SRC emacs-lisp (use-package expand-region :ensure expand-region :bind (("C-=" . er/expand-region)) :commands (er/expand-region er/enable-mode-expansions)) #+END_SRC *** hide-mode-line :package: :PROPERTIES: :ID: 91aaa182-1bcd-4bdc-ac1e-63363ae5dd2e :END: #+BEGIN_SRC emacs-lisp ;; If you want to hide the mode-line in every buffer by default ;; (add-hook 'after-change-major-mode-hook 'hidden-mode-line-mode) (use-package hide-mode-line :ensure t :commands (hide-mode-line-mode)) #+END_SRC *** ibuffer :package: :PROPERTIES: :ID: 9e00f528-ec3f-49cb-aa84-29e87c926836 :END: List buffers in a dired-ish way. Try to group based on modes or what kind of project something may be related to. #+BEGIN_SRC emacs-lisp (use-package ibuffer :commands ibuffer-other-window :init (setq ibuffer-default-sorting-mode 'major-mode ibuffer-always-show-last-buffer t ibuffer-view-ibuffer t ibuffer-expert t ibuffer-show-empty-filter-groups nil ;; Set up buffer groups based on file and mode types ibuffer-saved-filter-groups (quote (("default" ("IBuffer" (mode . ibuffer-mode)) ("Org" (mode . org-mode)) ("ERC" (mode . erc-mode)) ("Emacs Setup" (or (filename . "/.emacs_files/") (filename . "/.emacs_d/") (filename . "/emacs_d/"))) ("magit" (name . "magit")) ("dired" (mode . dired-mode)) ("emacs" (or (name . "^\\*scratch\\*$") (name . "^\\*Messages\\*$")))))))) #+END_SRC *** ibuffer-vc :package: :PROPERTIES: :ID: c3efde47-d622-450d-849b-7fc897899898 :END: Set up ibuffer groups via vc. #+BEGIN_SRC emacs-lisp (use-package ibuffer-vc :ensure t :after ibuffer :commands ibuffer-other-window :init ;; loads version control groups (call on entering ibuffer) (defun ibuffer-vc-add-vc-filter-groups () (interactive) (dolist (group (ibuffer-vc-generate-filter-groups-by-vc-root)) (add-to-list 'ibuffer-filter-groups group t))) (add-hook 'ibuffer-hook (lambda () (ibuffer-switch-to-saved-filter-groups "default") (ibuffer-vc-add-vc-filter-groups) (ibuffer-update nil)))) #+END_SRC *** icomplete :package: Incremental minibuffer completion. Update per character, as it takes a lot to lag it. #+BEGIN_SRC emacs-lisp :tangle no (icomplete-mode 1) (custom-set-variables '(icomplete-compute-delay 0.2)) #+END_SRC *** ispell :package: :PROPERTIES: :ID: 5116cf0e-24a6-4dce-8ecb-677ab27b2bdb :END: Turns out most spelling dictionaries don't contain "teledildonics". What a horrid oversight. #+BEGIN_SRC emacs-lisp (setq ispell-personal-dictionary "~/.ispell-dict-personal") #+END_SRC *** ivy-mode :package: :PROPERTIES: :ID: 1f6cd13a-7e88-4a99-a3ff-58afe7f06b26 :END: #+BEGIN_SRC emacs-lisp (use-package ivy :ensure swiper :bind (("C-x b" . ivy-switch-buffer)) :init (setq ivy-use-virtual-buffers t) (setq ivy-extra-directories nil) (setq ivy-display-style 'fancy) (defun qdot/ivy-open-current-typed-path () (interactive) (when ivy--directory (let* ((dir ivy--directory) (text-typed ivy-text) (path (concat dir text-typed))) (delete-minibuffer-contents) (ivy--done path)))) (setq ivy-re-builders-alist '((t . ivy--regex-plus))) (setq ivy-count-format "(%d/%d) ") :config (ivy-mode) ;; bind-keys isn't working here? No idea why. (bind-key "C-r" 'ivy-previous-line ivy-minibuffer-map) (bind-key "C-w" 'ivy-backward-kill-word ivy-minibuffer-map) (bind-key "" 'ivy-alt-done ivy-minibuffer-map) (bind-key "C-d" 'qdot/ivy-open-current-typed-path ivy-minibuffer-map)) #+END_SRC *** multiple-cursors :package: :PROPERTIES: :ID: c9c3fa7b-3e4f-454e-bd96-ee35eb43d475 :END: Work with multiple cursors simultaneously. #+BEGIN_SRC emacs-lisp (use-package multiple-cursors :ensure t :commands (mc/mark-next-like-this mc/mark-previous-like-this mc/mark-all-like-this) :bind (("C->" . mc/mark-next-like-this) ("C-<" . mc/mark-previous-like-this) ("C-*" . mc/mark-all-like-this))) #+END_SRC *** rainbow-delimiters :package: :PROPERTIES: :ID: 7935f464-2554-4a49-ae81-866f0adb4aa2 :END: #+BEGIN_SRC emacs-lisp (use-package rainbow-delimiters :ensure t :commands (rainbow-delimiters-mode rainbow-delimiters-mode-enable) :init (custom-set-faces '(rainbow-delimiters-depth-1-face ((t (:foreground "green" :weight extra-bold)))) '(rainbow-delimiters-depth-2-face ((t (:foreground "forestgreen" :weight bold)))) '(rainbow-delimiters-depth-3-face ((t (:foreground "lightseagreen" :weight bold)))) '(rainbow-delimiters-depth-4-face ((t (:foreground "lightskyblue" :weight bold)))) '(rainbow-delimiters-depth-5-face ((t (:foreground "cyan" :weight bold)))) '(rainbow-delimiters-depth-6-face ((t (:foreground "steelblue" :weight bold)))) '(rainbow-delimiters-depth-7-face ((t (:foreground "orchid" :weight bold)))) '(rainbow-delimiters-depth-8-face ((t (:foreground "purple" :weight bold)))) '(rainbow-delimiters-depth-9-face ((t (:foreground "hotpink" :weight bold)))) '(rainbow-delimiters-unmatched-face ((t (:foreground "red" :weight bold)))))) #+END_SRC *** recentf :package: :PROPERTIES: :ID: 611bcd05-ac88-4cfd-9f6a-c827eaaf05f6 :END: Use a list of most recent opened files instead of having to search through drive http://www.masteringemacs.org/articles/2011/01/27/find-files-faster-recent-files-package/ #+BEGIN_SRC emacs-lisp (use-package recentf :init ;; 50 files ought to be enough. (setq recentf-max-saved-items 50)) #+END_SRC *** rect-mark :package: :PROPERTIES: :ID: d653d0e6-2d55-4c7d-a5bf-25aafb689b2f :END: Make rectangular region marking easier. #+BEGIN_SRC emacs-lisp (use-package rect-mark :ensure t :bind (("C-x r C-SPC" . rm-set-mark) ("C-x r C-x" . rm-exchange-point-and-mark) ("C-x r C-w" . rm-kill-region) ("C-x r M-w" . rm-kill-ring-save))) #+END_SRC *** saveplace :package: :PROPERTIES: :ID: 1b96890b-3d1b-4f6d-8fa3-d08d1972a795 :END: Make sure I always come back to the same place in a file after closing/opening. http://groups.google.com/group/comp.emacs/browse_thread/thread/c5e4c18b77a18512 saveplace tends to screw with buffers that have automatically folded layouts, like org-mode. It'll open trees with none of the parents open, which causes weird problems. So org-mode is ignored. #+BEGIN_SRC emacs-lisp (use-package saveplace :init (setq-default save-place t) ;; saveplace and org-mode do not play well together, reset the regexp to include ;; org and org_archive files (setq-default save-place-ignore-files-regexp "\\(?:COMMIT_EDITMSG\\|hg-editor-[[:alnum:]]+\\.txt\\|svn-commit\\.tmp\\|bzr_log\\.[[:alnum:]]+\\|.*\\.org\\|.*\\.org_archive\\)$")) #+END_SRC *** smart-mode-line :package: :PROPERTIES: :ID: 57eb5f10-ccf0-42bd-ba79-6d0836e83cc1 :END: Makes the modeline easier to customize, in terms of both color themes and content. #+BEGIN_SRC emacs-lisp (use-package smart-mode-line :ensure t :init ;; The two known hashes for the sml dark theme (add-to-list 'custom-safe-themes "025354235e98db5e7fd9c1a74622ff53ad31b7bde537d290ff68d85665213d85") (add-to-list 'custom-safe-themes "6a37be365d1d95fad2f4d185e51928c789ef7a4ccf17e7ca13ad63a8bf5b922f") (setq sml/theme "dark") :config (sml/setup) ;; Black doesn't work as a background (custom-theme-set-faces 'smart-mode-line-dark '(mode-line ((t :foreground "gray60" :background "#202020")))) (add-to-list 'sml/replacer-regexp-list '("^~/code/git-projects/" ":GP:")) (add-to-list 'sml/replacer-regexp-list '("^~/.emacs_files/" ":EF:")) (add-to-list 'sml/replacer-regexp-list '("^~/Dropbox/" ":DB:")) (add-to-list 'sml/replacer-regexp-list '("^~/code/mozbuild/" ":MOZ:")) (setq sml/hidden-modes '(" yas" " SP" " Fly"))) #+END_SRC *** smex :package: :PROPERTIES: :ID: b5f0920c-16ac-4b8b-922d-cd3f9116ddaa :END: Smex is ido fuzzy matching for M-x. Deals with sorting most used commands to front of IDO. Instead of using the smex package off ELPA/MELPA, I'm using abo-abo's smex from https://github.com/abo-abo/smex in order to use smex and ivy-mode. So there's no ensure call here and I have to set the completion method. #+BEGIN_SRC emacs-lisp (use-package smex :after ivy :load-path "~/.emacs_files/dev-packages/smex" :bind (("C-c C-c M-x" . execute-extended-command)) :commands (smex smex-major-mode-commands) :config (setq smex-completion-method 'ivy)) #+END_SRC *** swiper :package: :PROPERTIES: :ID: 39c77f67-74b7-463c-9e26-fcfe976bd8c8 :END: #+BEGIN_SRC emacs-lisp (use-package swiper :ensure t :commands (swiper) :bind (("C-s" . swiper) ("C-r" . swiper)) :config ;; advise swiper to recenter on exit ;; http://pragmaticemacs.com/emacs/dont-search-swipe/ (defun qdot/swiper-recenter (&rest args) "recenter display after swiper" (recenter)) (advice-add 'swiper :after #'qdot/swiper-recenter)) #+END_SRC *** tramp :package: :PROPERTIES: :ID: da803671-5167-44e9-bcba-11639c9344a5 :END: I rarely use tramp these days, but usually use ssh when doing so. #+BEGIN_SRC emacs-lisp (use-package tramp :commands tramp :init (setq tramp-default-method "ssh")) #+END_SRC *** undo-tree :package: :PROPERTIES: :ID: 6376feb1-5dc9-4d62-b1d8-f4ce00d11c26 :END: Allow undo to branch, and be visualized as a graph. #+BEGIN_SRC emacs-lisp (use-package undo-tree :ensure t :config (global-undo-tree-mode 1)) #+END_SRC *** uniquify :package: :PROPERTIES: :ID: b8b6c9d3-4477-4717-b9a2-e393a7bcd35a :END: Make buffer names unique, handy when opening files with similar names #+BEGIN_SRC emacs-lisp (use-package uniquify :init (setq uniquify-buffer-name-style 'reverse uniquify-separator "|" uniquify-after-kill-buffer-p t uniquify-ignore-buffers-re "^\\*")) #+END_SRC *** visual-fill-column :package: :PROPERTIES: :ID: b582405f-9bd3-44da-a6f8-145b0a294c90 :END: Sets a fill column limit in visual-line-mode, so it will wrap earlier than the window edge #+BEGIN_SRC emacs-lisp (use-package visual-fill-column :ensure t :init (setq visual-fill-column-width 80)) #+END_SRC ** Emacs Navigation *** ace-jump-mode :package: :PROPERTIES: :ID: 4e7794bb-e8b7-4bbc-a673-9e851fc0b051 :END: Jump to a specified character in the currently visible buffer area. #+BEGIN_SRC emacs-lisp (use-package ace-jump-mode :ensure t :bind ("C-x SPC" . ace-jump-mode)) #+END_SRC *** ace-link :package: :PROPERTIES: :ID: fbcc787c-7a70-4abf-a883-b3cf04d52bb7 :END: Jump to a link in info/help windows. #+BEGIN_SRC emacs-lisp (use-package ace-link :ensure t :config (ace-link-setup-default)) #+END_SRC *** ace-window :package: :PROPERTIES: :ID: 2ad2f615-1292-483b-8490-979780726985 :END: Jump to a specified window by using [prefix-key] + letter #+BEGIN_SRC emacs-lisp (use-package ace-window :ensure t :bind ("M-o" . ace-window) :init (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) :config (custom-set-faces '(aw-leading-char-face ((t (:inherit ace-jump-face-foreground :height 3.0)))))) #+END_SRC *** avy :package: :PROPERTIES: :ID: 58a1bdee-66d7-47f1-a6d7-eaf4fc971cfc :END: #+BEGIN_SRC emacs-lisp (use-package avy :ensure t :bind ("M-g g" . avy-goto-line)) #+END_SRC *** windmove :package: :PROPERTIES: :ID: 045b3c37-402d-4eb2-9c5b-d01dd734b2e4 :END: Move between windows using shift-[arrow key]. #+BEGIN_SRC emacs-lisp (use-package windmove :config (progn (when (fboundp 'windmove-default-keybindings) (windmove-default-keybindings)))) #+END_SRC ** Operations *** docker-mode :package: :PROPERTIES: :ID: 2c3f6fd2-ce23-4458-ae83-7c99b2e91e1c :END: #+begin_src emacs-lisp (use-package docker :ensure t) #+end_src ** Productivity *** org-mode :package: :PROPERTIES: :header-args: :tangle tangle/qdot-org-config.el :END: Without org-mode to remind me that I'm supposed to be doing something, I'd probably just look at porn all day. Unfortunately, I also forget to look at org-mode a lot. A good portion of this setup is taken from [[http://doc.norang.ca/org-mode.html][Bernt Hansen's org-mode config]]. It's by far the most complete org-mode configuration I've ever seen. I use the org-plus-contrib package out of melpa. This keeps me on the bleeding edge of org-mode (once again, usually stable, and useful things land constantly), as well as providing me with multiple contrib modules that I need. **** Modules :PROPERTIES: :ID: 02f3dfd6-937a-4eac-91ea-ee7f6dafe86b :END: :PROPERTIES: :ID: 63de5529-45a1-48a4-b841-160b792f677c :END: Modules I use: - org-checklist: Allows you to clear/set all task internal checklists on task status change - org-screen: Allows org-babel blocks to run in a named screen session. - org-protocol: External access to org. Used along with keysnail for firefox integration with org-mode. - org-mobile: Mobile app that I rarely use 'cause omfg it's so janky. - org-habit: Habit showing in the agenda - org-bbdb: links to bbdb contacts - org-bh: Bernt Hansen's functions that I've stolen. - org-bibtex: Bibtex style bibliography output - org-crypt: gpg crypt'd org blocks - org-id: Creates unique identifiers for org nodes. Used by org-mobile, as well as for certain clocking needs. - org-info: Support linking to info nodes - org-jsinfo: Export org files to html with info-like folding #+BEGIN_SRC emacs-lisp ;;(require 'org-checklist) (require 'org-screen) (require 'org-protocol) (require 'org-mobile) (require 'org-habit) (require 'org-bh) ;; Easy templates were removed from defaults in Org 9. (require 'org-tempo) (setq org-modules (quote (org-bbdb org-tempo org-bibtex org-crypt org-docview org-habit org-id org-info org-jsinfo org-protocol))) #+END_SRC **** Packages :PROPERTIES: :ID: 2a04a1bc-93df-4e2a-af2c-f10942506899 :END: Github Flavored Markdown backend for org exports #+BEGIN_SRC emacs-lisp (use-package ox-gfm :ensure t :after org) #+END_SRC Org Babel async shell (allows :async in sh code blocks) #+begin_src emacs-lisp (use-package ob-async :ensure t :after org) #+end_src Replace all headline markers with unicode bullets #+begin_src emacs-lisp (use-package org-bullets :ensure t :config (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))) #+end_src **** Variables :PROPERTIES: :ID: d2917f45-4633-4a17-a152-4cb411f18925 :END: Add markdown export backend. #+BEGIN_SRC emacs-lisp (add-to-list 'org-export-backends 'md) #+END_SRC global STYLE property values for completion. #+BEGIN_SRC emacs-lisp (setq org-global-properties (quote (("STYLE_ALL" . "habit")))) #+END_SRC Use ~/emacs_org for storing files. Usually symlinked to Dropbox. #+BEGIN_SRC emacs-lisp (setq org-directory "~/emacs_org") #+END_SRC By default, at least timestamp done states. #+BEGIN_SRC emacs-lisp (setq org-log-done t) #+END_SRC Keep drawer for logs too. #+BEGIN_SRC emacs-lisp (setq org-drawers (quote ("PROPERTIES" "LOGBOOK"))) #+END_SRC We deal with stuck projects ourselves. #+BEGIN_SRC emacs-lisp (setq org-stuck-projects (quote ("" nil nil ""))) #+END_SRC Save clock data and state changes and notes in the LOGBOOK drawer. #+BEGIN_SRC emacs-lisp (setq org-log-into-drawer t) (setq org-clock-into-drawer t) #+END_SRC Start indented. #+BEGIN_SRC emacs-lisp (setq org-startup-indented t) #+END_SRC Hide blank lines inside folded nodes. #+BEGIN_SRC emacs-lisp (setq org-cycle-separator-lines 0) #+END_SRC Show notes in a task first. #+BEGIN_SRC emacs-lisp (setq org-reverse-note-order nil) #+END_SRC How much to indent in from the node level. #+BEGIN_SRC emacs-lisp (setq org-indent-indentation-per-level 2) #+END_SRC Archive to the file name, assume we're not doubling up names across projects #+BEGIN_SRC emacs-lisp (setq org-archive-location "~/emacs_org/archives/%s_archive::") #+END_SRC Sometimes I may want to archive undone things #+BEGIN_SRC emacs-lisp (setq org-archive-mark-done nil) #+END_SRC Always save inherited tags when archiving, otherwise I'll never find things in archive searches. #+BEGIN_SRC emacs-lisp (setq org-archive-subtree-add-inherited-tags t) #+END_SRC Do single letter confirm of links. #+BEGIN_SRC emacs-lisp (setq org-confirm-elisp-link-function 'y-or-n-p) #+END_SRC Use IDO for target completion. #+BEGIN_SRC emacs-lisp (setq org-completion-use-ido t) #+END_SRC Targets include this file and any file contributing to the agenda - up to 9 levels deep. #+BEGIN_SRC emacs-lisp (setq org-refile-targets (quote ((nil :maxlevel . 9) (org-agenda-files :maxlevel . 9)))) #+END_SRC Use outline paths, but let IDO handle things. #+BEGIN_SRC emacs-lisp (setq org-refile-use-outline-path (quote file)) #+END_SRC Allow refile to create parent tasks with confirmation. #+BEGIN_SRC emacs-lisp (setq org-refile-allow-creating-parent-nodes (quote confirm)) #+END_SRC IDO now handles header finding. #+BEGIN_SRC emacs-lisp (setq org-outline-path-complete-in-steps nil) #+END_SRC How far back to show in clocking history. Yes it's long... but more is better. #+BEGIN_SRC emacs-lisp (setq org-clock-history-length 35) #+END_SRC Resume clocking task on clock-in if the clock is open. #+BEGIN_SRC emacs-lisp (setq org-clock-in-resume t) #+END_SRC Save clock data and notes in the LOGBOOK drawer. #+BEGIN_SRC emacs-lisp (setq org-clock-into-drawer t) #+END_SRC Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration. #+BEGIN_SRC emacs-lisp (setq org-clock-out-remove-zero-time-clocks t) #+END_SRC Don't clock out when moving task to a done state. #+BEGIN_SRC emacs-lisp (setq org-clock-out-when-done nil) #+END_SRC Save the running clock and all clock history when exiting Emacs, load it on startup. #+BEGIN_SRC emacs-lisp (setq org-clock-persist t) #+END_SRC Don't use priorities and accidentally set them all the time, so just turn them off. #+BEGIN_SRC emacs-lisp (setq org-enable-priority-commands nil) #+END_SRC Don't use super/subscript globally, makes exports weird due to underscores. If they need to be used, set them on a per file level #+BEGIN_SRC emacs-lisp (setq org-use-sub-superscripts nil) #+END_SRC The habit graph display column in the agenda. #+BEGIN_SRC emacs-lisp (setq org-habit-graph-column 50) #+END_SRC Use speed commands (single key commands that can be used when cursor is at beginning of a line for a node). #+BEGIN_SRC emacs-lisp (setq org-use-speed-commands t) #+END_SRC Return shouldn't follow links, as this causes weird issues with collapsed content where the last thing is a link (for instance, a node that only has a SCHEDULED/DEADLINE date, so the date is the last thing in the link) #+BEGIN_SRC emacs-lisp (setq org-return-follows-link nil) #+END_SRC Make lists cycle whether they're nodes or plain. #+BEGIN_SRC emacs-lisp (setq org-cycle-include-plain-lists t) #+END_SRC Fontify org-src blocks like their language mode. #+BEGIN_SRC emacs-lisp (setq org-src-fontify-natively t) #+END_SRC Turn on sticky agendas so we don't have to regenerate them. #+BEGIN_SRC emacs-lisp (setq org-agenda-sticky nil) #+END_SRC If there's a region, do whatever it is I'm trying to do to ALL headlines in region. #+BEGIN_SRC emacs-lisp (setq org-loop-over-headlines-in-active-region t) #+END_SRC Changes the affect of C-a/C-e when used on org node lines. Does things like making C-a go to point after stars. This seemed like a good idea to have at t at first, but now it's driving me crazy so making sure it's off. #+BEGIN_SRC emacs-lisp (setq org-special-ctrl-a/e nil) #+END_SRC Do special stuff when cutting in a headline. #+BEGIN_SRC emacs-lisp (setq org-special-ctrl-k t) #+END_SRC When yanking subtrees, promote/demote levels based on the node being yanked into, if any. #+BEGIN_SRC emacs-lisp (setq org-yank-adjusted-subtrees t) #+END_SRC Always start with everything folded. #+BEGIN_SRC emacs-lisp (setq org-startup-folded t) #+END_SRC Don't lock to the week/month in the agenda, and always show ahead 7 days unless told otherwise #+BEGIN_SRC emacs-lisp (setq org-agenda-start-on-weekday nil) #+END_SRC Start agenda showing the next week by default. #+BEGIN_SRC emacs-lisp (setq org-agenda-span 7) #+END_SRC Multiple pass pdf generation. #+BEGIN_SRC emacs-lisp (setq org-latex-to-pdf-process '("xelatex -interaction nonstopmode %f" "xelatex -interaction nonstopmode %f")) #+END_SRC Include all files in the base emacs-org directory in agenda building/searches. #+BEGIN_SRC emacs-lisp (setq org-agenda-files (append (file-expand-wildcards "~/emacs_org/*.org"))) #+END_SRC I HATE INVISIBLE EDITS. So show me where it's happening and then make sure it doesn't happen. #+BEGIN_SRC emacs-lisp (setq org-catch-invisible-edits 'show-and-error) #+END_SRC No blank lines before headings #+BEGIN_SRC emacs-lisp (setq org-blank-before-new-entry (quote ((heading) (plain-list-item . auto)))) #+END_SRC Add ability to make bugzilla links. #+BEGIN_SRC emacs-lisp (setq org-link-abbrev-alist '(("bugzilla" . "https://bugzilla.mozilla.org/show_bug.cgi?id="))) #+END_SRC C-c C-t brings up a menu of possible todo state selections #+BEGIN_SRC emacs-lisp (setq org-use-fast-todo-selection t) #+END_SRC Shift-cursor selection will still change states, but won't log the change. I rarely use shift-cursor anyways since I use fast-todo-selection, so just set this to nil so it can be used to change without typing and logging. #+BEGIN_SRC emacs-lisp (setq org-treat-S-cursor-todo-selection-as-state-change nil) #+END_SRC For tag searches ignore tasks with scheduled and deadline dates #+BEGIN_SRC emacs-lisp (setq org-agenda-tags-todo-honor-ignore-options t) #+END_SRC Include agenda archive files when searching for things #+BEGIN_SRC emacs-lisp (setq org-agenda-text-search-extra-files (quote (agenda-archives))) #+END_SRC Leave cruft out of agenda #+BEGIN_SRC emacs-lisp (setq org-agenda-compact-blocks t) #+END_SRC Set ellipsis to at least be slightly smaller. Could also be something like ⤵, ▼, ↴, ⬎, ⤷, and ⋱. #+BEGIN_SRC emacs-lisp (setq org-ellipsis "…") #+END_SRC Use UUIDs when creating header links. Keeps us from having to worry about keeping titles straight. #+BEGIN_SRC emacs-lisp (setq org-id-link-to-org-use-id t) #+END_SRC **** Hooks :PROPERTIES: :ID: dc5b3f9d-9506-474c-b087-9fa9e0f89773 :END: Flyspell mode for spell checking everywhere. #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook 'turn-on-flyspell 'append) #+END_SRC Always indent text using outline. #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook (lambda () (org-indent-mode t))) #+END_SRC Undefine C-c [ and C-c ] since this breaks my org-agenda files when directories are included. It expands the files in the directories individually. #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook (lambda () (org-defkey org-mode-map "\C-c[" 'undefined) (org-defkey org-mode-map "\C-c]" 'undefined)) 'append) #+END_SRC Always hilight the current agenda line. #+BEGIN_SRC emacs-lisp (add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)) 'append) #+END_SRC Use visual-line mode. #+begin_src emacs-lisp (add-hook 'org-mode-hook 'visual-line-mode) #+end_src **** Clocking :PROPERTIES: :ID: 7d743563-3451-42dc-81cf-517556d1372a :END: Resume clocking tasks when emacs is restarted #+BEGIN_SRC emacs-lisp (org-clock-persistence-insinuate) #+END_SRC Set the ID for the base clock-in task, used when no other task is currently clocked. #+BEGIN_SRC emacs-lisp (setq bh/organization-task-id "6ef1b5e8-2a71-4aeb-8051-a2c22ba50665") #+END_SRC Show lot of clocking history so it's easy to pick items off the C-F11 list #+BEGIN_SRC emacs-lisp (setq org-clock-history-length 23) #+END_SRC Resume clocking task on clock-in if the clock is open #+BEGIN_SRC emacs-lisp (setq org-clock-in-resume t) #+END_SRC Change tasks to NEXT when clocking in #+BEGIN_SRC emacs-lisp (setq org-clock-in-switch-to-state 'bh/clock-in-to-next) #+END_SRC Separate drawers for clocking and logs #+BEGIN_SRC emacs-lisp (setq org-drawers (quote ("PROPERTIES" "LOGBOOK"))) #+END_SRC Save clock data and state changes and notes in the LOGBOOK drawer #+BEGIN_SRC emacs-lisp (setq org-clock-into-drawer t) #+END_SRC Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration #+BEGIN_SRC emacs-lisp (setq org-clock-out-remove-zero-time-clocks t) #+END_SRC Clock out when moving task to a done state #+BEGIN_SRC emacs-lisp (setq org-clock-out-when-done t) #+END_SRC Save the running clock and all clock history when exiting Emacs, load it on startup #+BEGIN_SRC emacs-lisp (setq org-clock-persist t) #+END_SRC Do not prompt to resume an active clock #+BEGIN_SRC emacs-lisp (setq org-clock-persist-query-resume nil) #+END_SRC Enable auto clock resolution for finding open clocks #+BEGIN_SRC emacs-lisp (setq org-clock-auto-clock-resolution (quote when-no-clock-is-running)) #+END_SRC Include current clocking task in clock reports #+BEGIN_SRC emacs-lisp (setq org-clock-report-include-clocking-task t) #+END_SRC #+END_SRC **** Todo flow setup :PROPERTIES: :ID: 376fe72f-9a3d-43c4-b34c-a5dabc83c688 :END: This is just Bernt's todo setup, copied verbatim. More information at http://doc.norang.ca/org-mode.html#TasksAndStates. #+BEGIN_SRC emacs-lisp (setq org-todo-keywords (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)") (sequence "WAITING(w@/!)" "HOLD(h!/!)" "|" "CANCELLED(c@/!)")))) (setq org-todo-state-tags-triggers (quote (("CANCELLED" ("CANCELLED" . t)) ("WAITING" ("WAITING" . t)) ("HOLD" ("WAITING" . t) ("HOLD" . t)) (done ("WAITING") ("HOLD")) ("TODO" ("WAITING") ("CANCELLED") ("HOLD")) ("NEXT" ("WAITING") ("CANCELLED") ("HOLD")) ("DONE" ("WAITING") ("CANCELLED") ("HOLD"))))) #+END_SRC **** Speed key bindings :PROPERTIES: :ID: b8ac18c6-1b72-4c2b-92ce-102c95b79f73 :END: Using speedkeys, s will narrow to the subtree, but you have to call widen explicitly. Set capital S to widen. #+BEGIN_SRC emacs-lisp (setq org-speed-commands-user (quote (("S" . widen)))) #+END_SRC **** Capture :PROPERTIES: :ID: fdb2dd1b-4abc-46f4-a80e-da7a9295a67c :END: Once again, stealing Bernt's ideas. Clock during capture, to either todos or notes. Added a reply capture for the mu4e reply capture action. #+BEGIN_SRC emacs-lisp ;; Once again, stolen from norang, except for the contacts one, which ;; was taken from the org-mode list. (setq org-capture-templates (quote (("t" "todo" entry (file "~/emacs_org/refile.org") "* TODO %?\n%u\n%a\n" :clock-in t :clock-resume t) ("n" "note" entry (file "~/emacs_org/notes.org") "* %? :NOTE:\n%u\n%a" :clock-in t :clock-resume t) ("r" "mu4e email reply" entry (file "~/emacs_org/email.org") "* %c" :immediate-finish t)))) #+END_SRC **** Agenda :PROPERTIES: :ID: 30553113-2bbb-4779-a999-ccdb931eb65f :END: I only have one custom agenda at the moment, but it's huge. It contains everything happening for the next week, as well as tasks needed to refile, emails I should look at, and all my projects. Bet you can guess where I got the idea from. This agenda contains a LOT of functions relating to Bernt's project setup (stuck projects, next steps, etc). For more info on that, see http://doc.norang.ca/org-mode.html#CustomAgendaViews. #+BEGIN_SRC emacs-lisp ;; Personal agenda modes (setq org-agenda-custom-commands (quote ((" " "Agenda" ((agenda "" nil) (tags "REFILE" ((org-agenda-overriding-header "Tasks to Refile") (org-tags-match-list-sublevels nil))) (tags "email+TODO=\"TODO\"" ((org-agenda-overriding-header "Emails") (org-tags-match-list-sublevels nil))) (tags-todo "-HOLD-CANCELLED/!" ((org-agenda-overriding-header "Live Projects") (org-agenda-skip-function 'bh/skip-non-projects) (org-tags-match-list-sublevels 'indented) (org-agenda-sorting-strategy '(category-keep)))) (tags-todo "-CANCELLED/!NEXT" ((org-agenda-overriding-header "Project Next Tasks") (org-agenda-skip-function 'bh/skip-projects-and-habits-and-single-tasks) (org-tags-match-list-sublevels t) (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks) (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks) (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks) (org-agenda-sorting-strategy '(priority-down todo-state-down effort-up category-keep)))) (tags-todo "-CANCELLED/!" ((org-agenda-overriding-header "Stuck Projects") (org-agenda-skip-function 'bh/skip-non-stuck-projects) (org-agenda-sorting-strategy '(category-keep)))) (tags-todo "+CANCELLED+WAITING/!" ((org-agenda-overriding-header "Waiting and Postponed Projects") (org-agenda-skip-function 'bh/skip-non-projects) (org-tags-match-list-sublevels nil) (org-agenda-todo-ignore-scheduled 'future) (org-agenda-todo-ignore-deadlines 'future))) (tags-todo "-REFILE-CANCELLED-WAITING-EVENT/!" ((org-agenda-overriding-header (if (marker-buffer org-agenda-restrict-begin) "Project Subtasks" "Standalone Tasks")) (org-agenda-skip-function 'bh/skip-project-tasks-maybe) (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks) (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks) (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks) (org-agenda-sorting-strategy '(category-keep)))) (tags-todo "-CANCELLED+WAITING/!" ((org-agenda-overriding-header "Waiting and Postponed Tasks") (org-agenda-skip-function 'bh/skip-stuck-projects) (org-tags-match-list-sublevels nil) (org-agenda-todo-ignore-scheduled 'future) (org-agenda-todo-ignore-deadlines 'future))) (tags "-REFILE/" ((org-agenda-overriding-header "Tasks to Archive") (org-agenda-skip-function 'bh/skip-non-archivable-tasks) (org-tags-match-list-sublevels nil))) nil))))) #+END_SRC **** Appointment warning bindings :PROPERTIES: :ID: 8c5a9b1a-8523-42cc-9354-fad3db19b002 :END: Warn 15 min in advance of events. #+BEGIN_SRC emacs-lisp (setq appt-message-warning-time 15) #+END_SRC Warn every 5 minutes once warnings begin. #+BEGIN_SRC emacs-lisp (setq appt-display-interval 5) #+END_SRC Show appointment warning in the modeline. #+BEGIN_SRC emacs-lisp (setq appt-display-mode-line t) #+END_SRC use our func #+BEGIN_SRC emacs-lisp (setq appt-display-format 'nil) #+END_SRC Org mode notifications via aptp the appointment notification facility #+BEGIN_SRC emacs-lisp (appt-activate 1) ;; active appt (appointment notification) (display-time) ;; time display is required for this... ;; update appt each time agenda opened (add-hook 'org-finalize-agenda-hook 'org-agenda-to-appt) #+END_SRC **** Faces :PROPERTIES: :ID: 11eaa10c-c192-4afd-9a9e-44a21a9e591a :END: Highlight the currently clocked in task. #+BEGIN_SRC emacs-lisp (custom-set-faces '(org-mode-line-clock ((t (:background "grey75" :foreground "red" :box (:line-width -1 :style released-button)))) t)) #+END_SRC Sasha Chua's org done faces http://sachachua.com/blog/2012/12/emacs-strike-through-headlines-for-done-tasks-in-org/ #+BEGIN_SRC emacs-lisp (setq org-fontify-done-headline t) (custom-set-faces '(org-done ((t (:foreground "PaleGreen" :weight normal :strike-through t)))) '(org-headline-done ((((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon" :strike-through t))))) #+END_SRC Set up face colors for tags. Makes quickly scanning the agenda easier. #+BEGIN_SRC emacs-lisp (setq org-tag-faces '(("mozilla" . (:foreground "DarkOrange3")) ("habits" . (:foreground "slate gray")) ("projects" . (:foreground "blue violet")) ("addimation" . (:foreground "PaleGreen4")) ("event" . (:foreground "deep pink")))) #+END_SRC **** Mobile Org :PROPERTIES: :ID: 00376626-e1d9-493d-8c5c-433d56907b8b :END: I've tried using mobile-org many times, but the interface to the android app is so painfully bad that I never stick with it for long. Nonetheless, I keep the config around just in case I feel like trying again. #+BEGIN_SRC emacs-lisp (setq org-mobile-inbox-for-pull "~/emacs_org/refile.org") (setq org-mobile-directory "~/Dropbox/MobileOrg") (setq org-mobile-files '("~/emacs_org/events.org" "~/emacs_org/tasks.org")) (setq org-mobile-agendas '("w")) #+END_SRC **** Disable org agenda window resizing :PROPERTIES: :ID: a6b403f7-09a5-4b9b-9ad4-940355d5c1a0 :END: The agenda is really horrible about resizing windows when I don't want it to, especially in a workgroups setup. Make sure that doesn't happen. #+BEGIN_SRC emacs-lisp (defvar org-agenda-no-resize nil "When non-nil, don't let org-mode resize windows for you") (setq org-agenda-no-resize t) (defadvice qdot/org-fit-agenda-window (around org-fit-agenda-window-select) "Will not let org-fit-agenda-window resize if org-agenda-no-resize is non-nil" (when (not org-agenda-no-resize) ad-do-it)) #+END_SRC **** Habit reloading :PROPERTIES: :ID: 7b4a17ee-ae43-4c86-a8bf-42d8e891ce89 :END: I usually turn off habits mid-day when most of them are done. If I leave emacs on over night, this turns them back on at 6am so I'll see them when I wake up. #+BEGIN_SRC emacs-lisp (run-at-time "06:00" 86400 '(lambda () (setq org-habit-show-habits t))) #+END_SRC **** Refile settings :PROPERTIES: :ID: 1c57ffd0-58dc-417b-a328-fda410b752e2 :END: Don't allow refiling into anything that's set to DONE. #+BEGIN_SRC emacs-lisp (defun qdot/verify-refile-target () "Exclude todo keywords with a done state from refile targets" (not (member (nth 2 (org-heading-components)) org-done-keywords))) (setq org-refile-target-verify-function 'qdot/verify-refile-target) #+END_SRC **** org-babel :PROPERTIES: :ID: 273a0ba1-4213-4c40-a828-ba03ca931139 :END: Set up languages that babel will handle. This includes lilypond, which I use for music. I also make sure that I don't have to confirm evaluation on a few languages. #+BEGIN_SRC emacs-lisp (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (shell . t) (org . t) (C . t))) (defun qdot/org-confirm-babel-evaluate (lang body) (and (not (string= lang "emacs-lisp")) (not (string= lang "sh")) (not (string= lang "shell")) (not (string= lang "ditaa")))) (setq org-confirm-babel-evaluate 'qdot/org-confirm-babel-evaluate) #+END_SRC **** ispell fix :PROPERTIES: :ID: 650555ef-1759-4c15-a021-4354dd732e70 :END: http://endlessparentheses.com/ispell-and-org-mode.html #+BEGIN_SRC emacs-lisp (defun qdot/org-ispell () "Configure `ispell-skip-region-alist' for `org-mode'." (make-local-variable 'ispell-skip-region-alist) (add-to-list 'ispell-skip-region-alist '(org-property-drawer-re)) (add-to-list 'ispell-skip-region-alist '("~" "~")) (add-to-list 'ispell-skip-region-alist '("=" "=")) (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_SRC" . "^#\\+END_SRC"))) (add-hook 'org-mode-hook #'qdot/org-ispell) #+END_SRC **** org-trello :PROPERTIES: :ID: 53e19cb9-0d94-43e7-a08f-12b3e1008b4a :END: #+BEGIN_SRC emacs-lisp (use-package org-trello :ensure t :disabled t :config (custom-set-variables '(org-trello-files '("~/emacs_org/trello-tasks.org" "~/emacs_org/trello-testing.org" "~/emacs_org/trello-notes.org"))) ;; add a hook function to check if this is trello file, then activate the org-trello minor mode. (add-hook 'org-mode-hook (lambda () (let ((filename (buffer-file-name (current-buffer)))) (when (and filename (string= "trello" (file-name-extension filename))) (org-trello-mode)))))) #+END_SRC **** org project exports :PROPERTIES: :ID: cdb0bca2-7359-4055-a618-313496d81c68 :END: #+BEGIN_SRC emacs-lisp (setq org-publish-project-alist '(("web-emacs-config" :base-directory "~/.emacs_files/" :include ("emacs_conf.org") :exclude "README.org" :publishing-directory "~/code/git-projects/kyle.machul.is/content/config/" :publishing-function org-html-publish-to-html :headline-levels 4 :section-numbers nil :with-toc t :html-head "" :html-preamble nil :html-postamble nil :html-tag-class-prefix "cv-" :html-head-include-default-style nil :body-only t ))) #+END_SRC **** export subtrees to different files :PROPERTIES: :ID: 81ee3946-fe0b-49cc-b664-255ec652d316 :END: #+BEGIN_SRC emacs-lisp ;; export headlines to separate files ;; http://emacs.stackexchange.com/questions/2259/how-to-export-top-level-headings-of-org-mode-buffer-to-separate-files (defun org-export-gitbook () "Export all subtrees that are *not* tagged with :noexport: to separate files. Subtrees that do not have the :EXPORT_FILE_NAME: property set are exported to a filename derived from the headline text." (interactive) (save-buffer) (let ((modifiedp (buffer-modified-p))) (save-excursion (goto-char (point-min)) (goto-char (re-search-forward "^*")) (set-mark (line-beginning-position)) (goto-char (point-max)) (org-map-entries (lambda () (let ((export-file (org-entry-get (point) "EXPORT_FILE_NAME"))) (unless export-file (org-set-property "EXPORT_FILE_NAME" (replace-regexp-in-string " " "_" (nth 4 (org-heading-components))))) (deactivate-mark) (org-gfm-export-to-markdown nil t) (unless export-file (org-delete-property "EXPORT_FILE_NAME")) (set-buffer-modified-p modifiedp))) "-noexport" 'region-start-level)))) #+END_SRC **** Add capf to org-mode :PROPERTIES: :ID: 833ae2a8-c3c3-4002-aace-946389199a79 :END: #+BEGIN_SRC elisp (defun add-pcomplete-to-capf () (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)) (add-hook 'org-mode-hook #'add-pcomplete-to-capf) #+END_SRC **** fix easy templates :PROPERTIES: :ID: ecd18a94-6273-400f-b80e-b93ff51ec971 :END: Easy templates were removed from defaults in Org 9. #+begin_src emacs-lisp (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) (add-to-list 'org-structure-template-alist '("sh" . "src sh")) #+end_src **** Provide Statement :PROPERTIES: :ID: f725dca4-48e8-4839-a9d7-a0660262ca9d :END: This should always come last. It's the provide statement so we can load this config using require. #+BEGIN_SRC emacs-lisp (provide 'qdot-org-config) #+END_SRC ** Programming *** cargo :package: :PROPERTIES: :ID: ed3f5961-5124-4fa0-83b4-299227bf57e1 :END: #+BEGIN_SRC emacs-lisp (use-package cargo :ensure t :mode "\\.rs\\'" :hook (rust-mode . cargo-minor-mode)) #+END_SRC *** cc-mode :package: :PROPERTIES: :ID: 49c62c49-51eb-4040-945f-e2619790e7a0 :END: Settings for C/C++ modes. Doxymacs currently commented out because it doesn't have a related package. #+BEGIN_SRC emacs-lisp (custom-set-variables'(cc-search-directories '("." "/usr/include" "/usr/local/include/*" "../include" "../../include" "../src" "../../src"))) (defun qdot/cc-mode-hook () ;; (doxymacs-font-lock) (c-add-style "qdot/cc-code-style" '("bsd" (c-basic-offset . 2))) (c-set-style "qdot/cc-code-style") (c-set-offset 'innamespace 0) (bind-keys :map c-mode-map ("C-m" . newline-and-indent) ("C-o" . ff-find-other-file)) (bind-keys :map c++-mode-map ("C-m" . newline-and-indent) ("C-o" . ff-find-other-file)) (company-mode 1) (subword-mode 1)) (add-hook 'c-mode-common-hook 'qdot/cc-mode-hook) #+END_SRC http://stackoverflow.com/questions/3312114/how-to-tell-emacs-to-open-h-file-in-c-mode #+BEGIN_SRC emacs-lisp ;; function decides whether .h file is C or C++ header, sets C++ by ;; default because there's more chance of there being a .h without a ;; .cc than a .h without a .c (ie. for C++ template files) (defun qdot/c-c++-header () "sets either c-mode or c++-mode, whichever is appropriate for header" (interactive) (let ((c-file (concat (substring (buffer-file-name) 0 -1) "c"))) (if (file-exists-p c-file) (c-mode) (c++-mode)))) (add-to-list 'auto-mode-alist '("\\.h\\'" . qdot/c-c++-header)) ;; and if that doesn't work, a function to toggle between c-mode and ;; c++-mode (defun qdot/toggle-c-mode () "toggles between c-mode and c++-mode" (interactive) (cond ((string= major-mode "c-mode") (c++-mode)) ((string= major-mode "c++-mode") (c-mode)))) ;; doxymacs mode for editing doxygen ;; doxymacs isn't in elpa. :( ;; (add-hook 'c-mode-common-hook 'doxymacs-mode) #+END_SRC *** change-log-mode :package: :PROPERTIES: :ID: 152fd3ac-68a0-4288-9db0-b12db75694d8 :END: #+BEGIN_SRC emacs-lisp (use-package change-log-mode :no-require t :mode ("ChangeLog\\.txt\\'" . change-log-mode)) #+END_SRC *** cmake-mode :package: :PROPERTIES: :ID: d0bf2227-a07b-4048-ae34-48caf3f5f287 :END: #+BEGIN_SRC emacs-lisp (use-package cmake-mode :ensure t :mode ("\\.cmake$" . cmake-mode)) #+END_SRC *** company :package: :PROPERTIES: :ID: d4ac7439-488d-43b1-9924-841c5f9f7b14 :END: #+BEGIN_SRC emacs-lisp (use-package company :ensure t :after yasnippet :init (setq company-idle-delay 0.2) (setq company-minimum-prefix-length 1) (setq company-dabbrev-ignore-case t) (setq company-dabbrev-downcase nil) (setq company-tooltip-align-annotations t) :config ;; (add-to-list 'company-backends 'company-yasnippet) (add-to-list 'company-backends 'company-elisp) ;; clang backend has issues, not really used. (setq company-backends (remove 'company-clang company-backends))) ;; https://github.com/jorgenschaefer/elpy/wiki/FAQ ;; (add-hook 'company-mode-hook ;; (lambda () ;; (substitute-key-definition ;; 'company-complete-common ;; 'company-yasnippet-or-completion ;; company-active-map)))) (use-package company-quickhelp :ensure t :after company :init (add-hook 'company-mode-hook (lambda () (company-quickhelp-mode 1)))) (use-package company-lsp :ensure t :after company) #+END_SRC *** compilation :package: :PROPERTIES: :ID: 78c819a6-403f-4df4-9b47-0a7c23b0f972 :END: Compilation mode. #+BEGIN_SRC emacs-lisp (defun qdot/recompile () "Run compile and resize the compile window closing the old one if necessary" (interactive) (progn (when (get-buffer "*compilation*") ; If old compile window exists (delete-windows-on (get-buffer "*compilation*")) ; Delete the compilation windows (kill-buffer "*compilation*")) ; and kill the buffers (call-interactively 'compile) (enlarge-window 30))) (use-package compile :commands (compile) :init (setq compilation-disable-input nil) (setq compilation-read-command nil) (setq compilation-auto-jump-to-first-error nil) (setq compilation-scroll-output 'first-error) (setq mode-compile-always-save-buffer-p t) :config ;; Turn on ansi colors in compilation buffers (ignore-errors (require 'ansi-color) (defun my-colorize-compilation-buffer () (when (eq major-mode 'compilation-mode) (ansi-color-apply-on-region compilation-filter-start (point-max)))) (add-hook 'compilation-filter-hook 'my-colorize-compilation-buffer))) #+END_SRC *** csharp-mode :package: :PROPERTIES: :ID: a4148006-be91-43fe-ab86-9b9320400652 :END: #+BEGIN_SRC emacs-lisp (use-package csharp-mode :ensure t :mode (("\\.cs$" . csharp-mode))) #+END_SRC *** dockerfile-mode :package: :PROPERTIES: :ID: 94722701-20d5-449f-ae62-33cba7ef8bb3 :END: #+begin_src emacs-lisp (use-package dockerfile-mode :ensure t :mode (("Dockerfile\\'" . dockerfile-mode))) #+end_src *** edebug-x :package: :PROPERTIES: :ID: 3433d9a2-9b91-4534-b596-ae926b2cf355 :END: #+BEGIN_SRC emacs-lisp (use-package edebug-x :ensure t :commands (edebug-x-modify-breakpoint-wrapper edebug-x-show-breakpoints edebug-x-show-instrumented edebug-x-show-data)) #+END_SRC *** elpy :package: :PROPERTIES: :ID: 650ede78-345d-4379-b8de-19afe87b3618 :END: #+BEGIN_SRC emacs-lisp (use-package elpy :ensure t :interpreter ("python" . python-mode) :init (if (file-exists-p "/usr/bin/python3") (setq python-shell-interpreter "/usr/bin/python3" python-shell-interpreter-args "-i" elpy-rpc-python-command "/usr/bin/python3")) (if (file-exists-p "/opt/homebrew/bin/python3") (setq python-shell-interpreter "/opt/homebrew/bin/python3" python-shell-interpreter-args "-i" elpy-rpc-python-command "/opt/homebrew/bin/python3")) (defun qdot/python-mode-hook() (setq tab-width 4) (setq py-indent-offset 4) (setq python-indent-offset 4) (set-variable 'python-indent-guess-indent-offset nil t) (set-variable 'fill-paragraph-function 'py-fill-paragraph t) ;;(setq ac-sources (append '(ac-source-yasnippet) ac-sources)) (set-fill-column 79) (bind-key "M-q" 'python-fill-paragraph python-mode-map) (setq eldoc-idle-delay 1.0) (setq flymake-no-changes-timeout 0.5) (elpy-enable) (setq elpy-rpc-backend "jedi") (subword-mode 1)) (elpy-enable) ;; (elpy-clean-modeline) ;; use flycheck instead of flymake ;; (when (require 'flycheck nil t) ;; (setq elpy-default-minor-modes (delete 'flymake-mode elpy-default-minor-modes)) ;; (add-to-list 'elpy-default-minor-modes 'flycheck-mode)) (add-hook 'python-mode-hook 'qdot/python-mode-hook)) #+END_SRC *** emacs-lisp-mode :package: :PROPERTIES: :ID: fbe84c8a-0785-4b02-8c52-77ae20ae8f11 :END: #+BEGIN_SRC emacs-lisp (defun esk-remove-elc-on-save () "If you're saving an elisp file, likely the .elc is no longer valid." (make-local-variable 'after-save-hook) (add-hook 'after-save-hook (lambda () (if (file-exists-p (concat buffer-file-name "c")) (delete-file (concat buffer-file-name "c")))))) ;; eldoc mode for showing function calls in mode line (setq eldoc-idle-delay 0.5) (autoload 'turn-on-eldoc-mode "eldoc" nil t) (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode) ;; default lisp indentation looks weird (setq lisp-indent-function 'common-lisp-indent-function) ;; stealin' things from esk (add-hook 'emacs-lisp-mode-hook 'esk-remove-elc-on-save) (add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode-enable) (add-hook 'emacs-lisp-mode-hook 'company-mode) (define-key emacs-lisp-mode-map (kbd "C-c v") 'eval-buffer) (define-key lisp-mode-shared-map (kbd "RET") 'reindent-then-newline-and-indent) ;; Enable jumping to elisp via help mode ;; http://emacsredux.com/blog/2014/06/18/quickly-find-emacs-lisp-sources/ (define-key 'help-command (kbd "C-l") 'find-library) (define-key 'help-command (kbd "C-f") 'find-function) (define-key 'help-command (kbd "C-k") 'find-function-on-key) (define-key 'help-command (kbd "C-v") 'find-variable) #+END_SRC *** lsp-mode :package: :PROPERTIES: :ID: ffa32f27-adf0-46d9-9bf0-b47fb6364929 :END: #+begin_src emacs-lisp (use-package lsp-mode :ensure t) #+end_src *** lsp-ui :package: :PROPERTIES: :ID: c0a24b20-938d-4334-aa33-a02a592ca82d :END: #+begin_src emacs-lisp (use-package lsp-ui :ensure t) #+end_src *** lsp-treemacs :package: :PROPERTIES: :ID: 32070190-a0dc-43e6-8b7f-74396c6bbbfe :END: #+begin_src emacs-lisp (use-package lsp-treemacs :ensure t) #+end_src *** fish-mode :package: :PROPERTIES: :ID: d32f1def-684e-459f-9762-484f7397bfb8 :END: #+begin_src emacs-lisp (use-package fish-mode :ensure t) #+end_src *** flycheck :package: :PROPERTIES: :ID: be9fa82d-b857-477b-a0d1-6101f1948876 :END: Using flycheck instead of flymake #+BEGIN_SRC emacs-lisp (use-package flycheck :ensure t :commands flycheck-mode :config (global-flycheck-mode) ;; Set Python3 executables for flycheck (custom-set-variables '(flycheck-python-flake8-executable "python3") '(flycheck-python-pycompile-executable "python3") '(flycheck-python-mypy-executable "python3") '(flycheck-python-pylint-executable "python3"))) #+END_SRC *** flycheck-inline :package: :PROPERTIES: :ID: c86e897c-2633-42e8-9564-c7ce2d7deff2 :END: #+begin_src emacs-lisp (use-package flycheck-inline :ensure t :config (with-eval-after-load 'flycheck (add-hook 'flycheck-mode-hook #'flycheck-inline-mode))) #+end_src *** flycheck-rtags :package: :PROPERTIES: :ID: c456737b-bd3a-42e3-99af-9c98b568135b :END: #+BEGIN_SRC emacs-lisp (use-package flycheck-rtags :ensure t :config ;; c-mode-common-hook is also called by c++-mode (defun setup-flycheck-rtags () (interactive) (flycheck-select-checker 'rtags) ;; RTags creates more accurate overlays. (setq-local flycheck-highlighting-mode nil) (setq-local flycheck-check-syntax-automatically nil)) (add-hook 'c-mode-common-hook #'setup-flycheck-rtags)) #+END_SRC *** flycheck-rust :package: :PROPERTIES: :ID: 1542ff9f-8621-46f0-92a9-6bd67acb81bb :END: #+BEGIN_SRC emacs-lisp (use-package flycheck-rust :ensure t :config (with-eval-after-load 'rust-mode (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) #+END_SRC *** gdb :package: :PROPERTIES: :ID: 57a92b27-4226-4333-8e53-eb7a1a9637ec :END: #+BEGIN_SRC emacs-lisp ;; Turn off non-stop by default. All or nothing, damnit. (setq gdb-non-stop-setting nil) ;; gdb/gud (setq gdb-many-windows t) (setq gdb-show-main t) (setq gud-chdir-before-run nil) (setq gud-tooltip-mode t) #+END_SRC *** git-gutter-fringe :package: :PROPERTIES: :ID: ed23e031-497d-40e6-b48f-bbbebe07e474 :END: Shows git status of current files in fringe. #+BEGIN_SRC emacs-lisp (use-package git-gutter-fringe :ensure t :commands (git-gutter git-gutter:toggle)) #+END_SRC *** git-messenger :package: :PROPERTIES: :ID: 3be94264-1108-419d-b18b-c5b0af99d8b8 :END: Shows git commit corresponding to the current line #+BEGIN_SRC emacs-lisp (use-package git-messenger :ensure t :commands (git-messenger:popup-message) :init (setq git-messenger:show-detail t) ;; Use magit-show-commit for showing status/diff commands (custom-set-variables '(git-messenger:use-magit-popup t))) #+END_SRC *** gitattributes-mode :package: :PROPERTIES: :ID: 290f1482-0b08-4106-8083-21dad90075c4 :END: Used for dealing with git attribute files #+BEGIN_SRC emacs-lisp (use-package gitattributes-mode :mode ("\\.gitattributes$" . gitattributes-mode) :ensure t) #+END_SRC *** gitconfig-mode :package: :PROPERTIES: :ID: 65a9a721-68b8-42c6-90d8-64fb9364b5cf :END: Modes for editing gitconfig, gitignore, etc. #+BEGIN_SRC emacs-lisp (use-package gitconfig-mode :ensure t) #+END_SRC *** gitignore-mode :package: :PROPERTIES: :ID: 0bc4f962-9daf-46f0-bab1-2cc45b3921dd :END: #+BEGIN_SRC emacs-lisp (use-package gitignore-mode :ensure t) #+END_SRC *** git-timemachine :package: :PROPERTIES: :ID: 5ee0aeb2-c943-4e54-816f-188e170d82a0 :END: Step through git versions of the current file #+BEGIN_SRC emacs-lisp (use-package git-timemachine :commands (git-timemachine) :ensure git-timemachine) #+END_SRC *** haskell-mode :package: :PROPERTIES: :ID: 663f7b28-d074-4d18-8f0d-b1e78b8e285d :END: #+BEGIN_SRC emacs-lisp (use-package haskell-mode :ensure haskell-mode :mode ("\\.hs$" . haskell-mode) :config (require 'inf-haskell) (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation) (add-hook 'haskell-mode-hook 'font-lock-mode) (add-hook 'haskell-mode-hook 'rainbow-delimiters-mode-enable) (setq haskell-font-lock-symbols t)) #+END_SRC *** idl-mode :package: :PROPERTIES: :ID: be58be65-aa7f-4df6-9ba1-b6e4dea82b24 :END: #+BEGIN_SRC emacs-lisp (use-package idl-mode :no-require t :mode ("\\.\\(idl\\|webidl\\)\\'" . idl-mode)) #+END_SRC *** indent-guide :package: :PROPERTIES: :ID: dc86b022-2259-4c1a-88b5-1796267b9ff7 :END: Shows indentation guides when in code blocks #+BEGIN_SRC emacs-lisp (use-package indent-guide :ensure t :commands (indent-guide-mode indent-guide-global-mode)) #+END_SRC *** js2-mode :package: :PROPERTIES: :ID: 13791349-b740-416c-8ec9-feef4f804ce9 :END: #+BEGIN_SRC emacs-lisp (use-package js2-mode :ensure t :commands (js2-mode) :mode (("\\.js\\'" . js2-mode) ("\\.jsm\\'" . js2-mode)) :init ;; Fix for .js files that have Java set as the mode (I'm looking at ;; you, mozilla-central) (add-hook 'java-mode-hook (lambda () (when (string-match "\\.js\\'" buffer-file-name) (js2-mode)))) :config (setq js-indent-level 2) (setq js2-basic-offset 2) (add-hook 'js2-mode-hook (lambda () (flycheck-mode) (company-mode 1)))) #+END_SRC *** js2-refactor :package: :PROPERTIES: :ID: b847efad-0ee6-4959-b9a6-ea62c01183bb :END: #+BEGIN_SRC emacs-lisp (use-package js2-refactor :ensure t :config (add-hook 'js2-mode-hook #'js2-refactor-mode)) #+END_SRC *** js-doc :package: :PROPERTIES: :ID: d37a0910-8c84-4e48-ab23-d2af97441e9b :END: #+BEGIN_SRC emacs-lisp (use-package js-doc :ensure t :config (setq js-doc-mail-address "kyle@machul.is" js-doc-author (format "Kyle Machulis <%s>" js-doc-mail-address) js-doc-url "http://kyle.machul.is" js-doc-license "BSD 3-Clause") (add-hook 'js2-mode-hook #'(lambda () (define-key js2-mode-map "\C-ci" 'js-doc-insert-function-doc) (define-key js2-mode-map "@" 'js-doc-insert-tag)))) #+END_SRC *** json-mode :package: :PROPERTIES: :ID: bfb36a5b-7f03-43cb-aa8a-d851f8e2d428 :END: #+BEGIN_SRC emacs-lisp (use-package json-mode :ensure json-mode :ensure json-reformat :ensure json-snatcher :mode ("\\.json\\'" . json-mode)) #+END_SRC *** lua :package: :PROPERTIES: :ID: 27312d07-4ae5-484f-9089-e938158c1a72 :END: #+BEGIN_SRC emacs-lisp (use-package lua-mode :ensure lua-mode :mode ("\\.lua\\'" . lua-mode)) #+END_SRC *** magit :package: :PROPERTIES: :ID: f6ea2635-681e-4169-8419-a1727c1cb28a :END: git management in emacs. #+BEGIN_SRC emacs-lisp (use-package magit :ensure t :bind (("M-g s" . magit-status)) :chords (("qg" . magit-status)) :commands (magit magit-status) :init ;; omfg shut up magit I am fine with auto reverting (setq magit-last-seen-setup-instructions "1.4.0") :config (setq magit-completing-read-function 'magit-ido-completing-read) (add-hook 'magit-log-edit-mode-hook 'turn-on-flyspell 'append) ;; Set up diffing faces, and always full screen magit (eval-after-load 'magit '(progn ;; full screen magit-status (defadvice magit-status (around magit-fullscreen activate) (window-configuration-to-register :magit-fullscreen) ad-do-it (delete-other-windows)) (defun magit-quit-session () "Restores the previous window configuration and kills the magit buffer" (interactive) (kill-buffer) (jump-to-register :magit-fullscreen)) (define-key magit-status-mode-map (kbd "q") 'magit-quit-session))) ;; use ivy for completing read if available (setq magit-completing-read-function 'ivy-completing-read) ;; Don't require confirm to stage changes (setq magit-stage-all-confirm nil) (add-to-list 'magit-no-confirm 'stage-all-changes) (if macosx-p (setq magit-git-executable "/opt/homebrew/bin/git"))) #+END_SRC *** nose :package: :PROPERTIES: :ID: e3077e70-173b-4d3e-8c98-bb561513ef8f :END: #+BEGIN_SRC emacs-lisp ;; (use-package nose ;; :ensure nose) #+END_SRC *** nxml-mode :package: :PROPERTIES: :ID: 34ab4f97-8da9-40c3-9c4b-93b4024b2fa4 :END: #+BEGIN_SRC emacs-lisp (use-package nxml-mode :mode ("\\.\\(xml\\|mxml\\)\\'" . nxml-mode)) #+END_SRC *** powershell :package: :PROPERTIES: :ID: cae62b72-f698-4cbe-8056-11ec8baf44db :END: #+BEGIN_SRC emacs-lisp (use-package powershell :ensure t) #+END_SRC *** prog-mode :package: :PROPERTIES: :ID: 82cf0d82-ba2c-4c36-9fe3-8d348e5e3e13 :END: Set up defaults for all programming modes. Always indent 2. #+BEGIN_SRC emacs-lisp (setq-default c-basic-offset 2) (setq-default tab-width 2) #+END_SRC Spaces, not tabs. Everywhere. #+BEGIN_SRC emacs-lisp (setq-default indent-tabs-mode nil) #+END_SRC Keep linum offset to expect thousands so we don't bounce when changing buffers. #+BEGIN_SRC emacs-lisp (setq linum-format "%4d") #+END_SRC Set up fill column and whitespace-mode settings when starting programming mode. #+BEGIN_SRC emacs-lisp (defun qdot/programming-mode-hook () (set-fill-column 80) (setq whitespace-line-column 80) (setq whitespace-style '(face lines-tail)) (setq show-trailing-whitespace t)) (add-hook 'prog-mode-hook 'qdot/programming-mode-hook) #+END_SRC Always check spelling in comments and documentation. #+BEGIN_SRC emacs-lisp ;;(add-hook 'prog-mode-hook 'flyspell-prog-mode) #+END_SRC Always show where whitespace is off. #+BEGIN_SRC emacs-lisp ;;(add-hook 'prog-mode-hook 'whitespace-mode) #+END_SRC Highlight matching paren/bracket/etc pairs. #+BEGIN_SRC emacs-lisp (eval-after-load 'smartparens-mode (add-hook 'prog-mode-hook 'show-smartparens-mode)) #+END_SRC Line numbers #+BEGIN_SRC emacs-lisp (add-hook 'prog-mode-hook 'display-line-numbers-mode) #+END_SRC *** projectile :package: :PROPERTIES: :ID: 04732738-a291-4ef6-9f62-4554da385154 :END: #+BEGIN_SRC emacs-lisp (use-package projectile :ensure projectile :bind (("" . projectile-run-project) ("C-S-b" . projectile-compile-project)) :chords (("qp" . hydra-projectile/body)) :config (projectile-global-mode) (setq projectile-completion-system 'ivy) (projectile-register-project-type 'gecko '("mach" "moz.build") :compile "NO_BUILDSTATUS_MESSAGES=1 python mach --log-no-times build" :test "python mach mochitest" :run "python mach run") (defun qdot/projectile-off () (projectile-mode -1)) ;; Don't want this on for IRC (add-hook 'erc-mode 'qdot/projectile-off)) #+END_SRC *** protobuf-mode :package: :PROPERTIES: :ID: 2c1bedb5-6ba7-484b-967a-2f9a9416c7ff :END: #+BEGIN_SRC emacs-lisp (use-package protobuf-mode :ensure t :mode (("\\.proto\\'" . protobuf-mode))) #+END_SRC *** pug-mode :package: :PROPERTIES: :ID: e89b6ddd-8a0e-4e92-8b35-97e030df2e9f :END: #+BEGIN_SRC emacs-lisp (use-package pug-mode :ensure t :mode (("\\.pug\\'" . pug-mode))) #+END_SRC *** racer :package: :PROPERTIES: :ID: 31da4844-43d6-49dc-bea9-62d8336c9c41 :END: #+BEGIN_SRC emacs-lisp (use-package racer :ensure racer :config (setq racer-cmd "~/.cargo/bin/racer") (if (file-exists-p "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src") (setq racer-rust-src-path "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src")) (if (file-exists-p "~/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src") (setq racer-rust-src-path "~/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src")) (defun racer-setup () (setq eldoc-idle-delay 0.5)) (add-hook 'racer-mode-hook 'racer-setup) (add-hook 'rust-mode-hook #'racer-mode) (add-hook 'racer-mode-hook #'eldoc-mode) (add-hook 'racer-mode-hook #'company-mode)) #+END_SRC *** rtags :package: :PROPERTIES: :ID: 247e8e8f-dedb-4fad-9f41-9cb95d77e2cf :END: Use rtags for symbol lookup and jumps, irony-mode for completion. #+BEGIN_SRC emacs-lisp (use-package rtags :ensure t :disabled t :config (add-hook 'c-mode-common-hook 'rtags-start-process-unless-running) (add-hook 'c++-mode-common-hook 'rtags-start-process-unless-running) (defun use-rtags (&optional useFileManager) (and (rtags-executable-find "rc") (cond ((not (gtags-get-rootpath)) t) ((and (not (eq major-mode 'c++-mode)) (not (eq major-mode 'c-mode))) (rtags-has-filemanager)) (useFileManager (rtags-has-filemanager)) (t (rtags-is-indexed))))) (setq rtags-display-result-backend 'ivy) (setq rtags-autostart-diagnostics t) (rtags-diagnostics) (setq rtags-completions-enabled t) (defun tags-find-symbol-at-point (&optional prefix) (interactive "P") (if (and (not (rtags-find-symbol-at-point prefix)) rtags-last-request-not-indexed) (gtags-find-tag))) (defun tags-find-references-at-point (&optional prefix) (interactive "P") (if (and (not (rtags-find-references-at-point prefix)) rtags-last-request-not-indexed) (gtags-find-rtag))) (defun tags-find-symbol () (interactive) (call-interactively (if (use-rtags) 'rtags-find-symbol 'gtags-find-symbol))) (defun tags-find-references () (interactive) (call-interactively (if (use-rtags) 'rtags-find-references 'gtags-find-rtag))) (defun tags-find-file () (interactive) (call-interactively (if (use-rtags t) 'rtags-find-file 'gtags-find-file))) (defun tags-imenu () (interactive) (call-interactively (if (use-rtags t) 'rtags-imenu 'idomenu))) (define-key c-mode-base-map (kbd "M-.") (function tags-find-symbol-at-point)) (define-key c-mode-base-map (kbd "M-,") (function tags-find-references-at-point)) ;;(define-key c-mode-base-map (kbd "M-;") (function tags-find-file)) (define-key c-mode-base-map (kbd "C-.") (function tags-find-symbol)) (define-key c-mode-base-map (kbd "C-,") (function tags-find-references)) (define-key c-mode-base-map (kbd "C-<") (function rtags-find-virtuals-at-point)) (define-key c-mode-base-map (kbd "M-i") (function tags-imenu)) (define-key global-map (kbd "M-.") (function tags-find-symbol-at-point)) (define-key global-map (kbd "M-,") (function tags-find-references-at-point)) ;;(define-key global-map (kbd "M-;") (function tags-find-file)) (define-key global-map (kbd "C-.") (function tags-find-symbol)) (define-key global-map (kbd "C-,") (function tags-find-references)) (define-key global-map (kbd "C-<") (function rtags-find-virtuals-at-point)) (define-key global-map (kbd "M-i") (function tags-imenu))) #+END_SRC *** rust-mode :package: :PROPERTIES: :ID: c1bc6012-e687-4c4c-8278-dce57eaf7a44 :END: #+BEGIN_SRC emacs-lisp (use-package rust-mode :ensure t :mode (("\\.rs$" . rust-mode)) :config (define-key rust-mode-map (kbd "TAB") #'company-indent-or-complete-common) (add-hook 'rust-mode-hook (lambda () (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) ;;; emacs rustdoc editting via C-c ' (similar to org-babel) ;;; Taken from https://github.com/czipperz/emacs.d/blob/master/modules/rustdoc/config.el ;;; Rust-mode is supposed to integrate this at some point ;;; Issue: https://github.com/rust-lang/rust-mode/pulls ;;; ;;; Copyright (C) 2018, 2019 Andreas Fuchs ;;; Copyright (C) 2019 Chris Gregory ;;; Made available to you under the terms of GPLv2 or later: https://choosealicense.com/licenses/gpl-2.0/ (defconst asf--rustdoc-line-prefixes (concat "^\\([\t ]*" (regexp-opt '("///" "//!")) "\\)")) (defun asf--rustdoc-current-comment-block-region () (save-excursion (forward-line 0) (when (looking-at asf--rustdoc-line-prefixes) ;; determine the current line's prefix & extract all the lines ;; with matching prefixes that surround it (we assume that's the ;; extent of the rustdoc block): (let ((prefix (match-string-no-properties 1)) (initial-position (point)) start end) ;; look back: (while (and (looking-at prefix) (not (eql (point) (point-min)))) (setq start (point)) (forward-line -1)) (when (looking-at prefix) ;; we're at the beginning of the buffer; make sure we got that: (setq start (point))) (goto-char initial-position) (while (and (not (eql (point) (point-max))) (looking-at prefix)) (forward-line 1) (setq end (point))) (list start end))))) (defvar asf--rustdoc-prefix) (defun asf--rustdoc-prefix-without-space (prefix) (replace-regexp-in-string "[\t ]*$" "" prefix)) (defun asf--rustdoc-strip-prefix () (save-excursion (goto-char (point-min)) ;; infer prefix from first line: (let* ((prefix (when (looking-at (concat asf--rustdoc-line-prefixes "[\t ]*")) (match-string 0))) (prefix-re (concat "^" prefix)) (empty-line-prefix-re (concat "^" (asf--rustdoc-prefix-without-space prefix)))) (while (< (point) (point-max)) (when (or (looking-at prefix-re) (looking-at empty-line-prefix-re)) (replace-match "") (forward-line 1))) prefix))) (defun asf--rustdoc-apply-prefix () (let ((prefix asf--rustdoc-prefix)) (save-excursion (goto-char (point-min)) (while (and (re-search-forward "^" nil t) (not (eql (point) (point-max)))) (replace-match prefix " ") (when (eolp) (delete-horizontal-space))) (goto-char (point-max)) ;; non-empty lines at the end must end in a newline: (unless (looking-at "^$") (insert "\n"))))) (defun asf--rustdoc-setup-buffer () ;; Strip the comment prefix from lines & set up the buffer's major mode: (let ((prefix (asf--rustdoc-strip-prefix))) (markdown-mode) (setq-local asf--rustdoc-prefix prefix) (setq-local edit-indirect-before-commit-hook '(asf--rustdoc-apply-prefix)) (setq-local polymode-default-inner-mode 'rust-mode))) (defun asf-rustdoc-edit () (interactive) (let ((guess (asf--rustdoc-current-comment-block-region))) (unless guess (error "Not in a rustdoc comment that I can guess!")) (destructuring-bind (start end) guess (let ((edit-indirect-after-creation-hook 'asf--rustdoc-setup-buffer)) (edit-indirect-region start end t))))) (define-key rust-mode-map (kbd "C-c '") 'asf-rustdoc-edit)) #+END_SRC *** smartparens :package: :PROPERTIES: :ID: 6242c0f2-07e0-4c1b-81a0-b3ab3606d41d :END: Smarter paren matching without going the paredit route. Turning off deferred loading because this is useful almost everywhere. #+BEGIN_SRC emacs-lisp (use-package smartparens-config :ensure smartparens :commands (smartparens-global-mode) :bind (("" . sp-forward-slurp-sexp) ("" . sp-forward-barf-sexp) ("" . sp-backward-slurp-sexp) ("" . sp-backward-barf-sexp)) :init (smartparens-global-mode t) ;; I start words with ' a lot when I chat apparently (sp-local-pair 'erc-mode "'" nil :actions nil)) #+END_SRC *** smerge-mode :package: :PROPERTIES: :ID: 04c2ad90-a2da-48dc-ac3f-069d58ffca33 :END: :PROPERTIES: :ID: f795d7f6-7260-4468-91af-98cb3978fed7 :END: Adds commands for dealing with conflicted merge files (i.e. >>>>>>> and <<<<<<< files) http://atomized.org/2010/06/resolving-merge-conflicts-the-easy-way-with-smerge-kmacro/ #+BEGIN_SRC emacs-lisp (use-package smerge-mode :commands (smerge-mode sm-try-smerge)) (defun sm-try-smerge () (save-excursion (goto-char (point-min)) (when (re-search-forward "^<<<<<<< " nil t) (smerge-mode 1)))) (add-hook 'find-file-hook 'sm-try-smerge t) #+END_SRC *** tide :package: :PROPERTIES: :ID: 1a791625-3882-41c6-b4d1-e72f56c504e3 :END: #+BEGIN_SRC emacs-lisp (use-package tide :ensure t :diminish t :init (defun setup-tide-mode () (interactive) (tide-setup) (flycheck-mode +1) (flycheck-add-next-checker 'typescript-tide '(t . typescript-tslint) 'append) (setq flycheck-check-syntax-automatically '(save mode-enabled)) (eldoc-mode +1) (setq eldoc-idle-delay 0.5) (tide-hl-identifier-mode +1) ;; company is an optional dependency. You have to ;; install it separately via package-install ;; `M-x package-install [ret] company` (company-mode +1) ;; aligns annotation to the right hand side (setq company-tooltip-align-annotations t))) (flycheck-add-mode 'typescript-tslint 'web-mode) #+END_SRC *** twee-mode :package: :PROPERTIES: :ID: 3651856a-e762-4ede-a997-d7e37a44eb27 :END: Mode for editing twine files. File in elisp directory for the moment. #+BEGIN_SRC emacs-lisp (use-package twee-mode :mode (("\\.twee\\'" . twee-mode))) #+END_SRC *** typescript-mode :package: :PROPERTIES: :ID: 81754e0a-2b2e-4728-a45a-3f53ccf6a9ad :END: #+BEGIN_SRC emacs-lisp (use-package typescript-mode :ensure t :init ;; aligns annotation to the right hand side (setq typescript-indent-level 2) (add-hook 'typescript-mode-hook #'setup-tide-mode)) #+END_SRC *** toml-mode :package: :PROPERTIES: :ID: b532ccd7-cd10-4f57-a10c-a0f904881722 :END: toml files are usually used for Rust Cargo specifications. #+BEGIN_SRC emacs-lisp (use-package toml-mode :mode ("\\.toml$" . toml-mode) :ensure toml-mode) #+END_SRC *** web-mode :package: :PROPERTIES: :ID: cd21c7bf-6554-463f-95c8-806deac15f4b :END: #+BEGIN_SRC emacs-lisp (use-package web-mode :ensure web-mode :mode (("\\.html\\'" . web-mode) ("\\.phtml\\'" . web-mode) ("\\.xul\\'" . web-mode) ("\\.tpl\\.php\\'" . web-mode) ("\\.jsp\\'" . web-mode) ("\\.as[cp]x\\'" . web-mode) ("\\.erb\\'" . web-mode) ("\\.mustache\\'" . web-mode) ("\\.djhtml\\'" . web-mode) ("\\.vue\\'" . web-mode) ("\\.ejs\\'" . web-mode)) :config (setq web-mode-markup-indent-offset 2) (setq web-mode-css-indent-offset 2) (setq web-mode-code-indent-offset 2) ;; Turn off flycheck-mode in webcode, as multiple language checking is broken. (add-hook 'web-mode-hook (lambda () (flycheck-mode -1)))) #+END_SRC *** yaml-mode :package: :PROPERTIES: :ID: 46a9b080-a30b-42c4-bc43-785364ca3032 :END: Used for Travis configs, sometimes for Pelican work #+BEGIN_SRC emacs-lisp (use-package yaml-mode :mode ("\\.yaml$" . yaml-mode) :ensure yaml-mode) #+END_SRC *** yasnippet :package: :PROPERTIES: :ID: ce903f75-1f82-4440-8e7a-f23ba161acc6 :END: Provides fillable templates. #+BEGIN_SRC emacs-lisp (use-package yasnippet :ensure yasnippet :commands (yas-global-mode yas-minor-mode yas-minor-mode-on yas-expand) :config (add-to-list 'yas-snippet-dirs qdot/emacs-snippets-dir) (add-hook 'prog-mode-hook 'yas-minor-mode-on) (add-hook 'markdown-mode-hook 'yas-minor-mode-on) ;; Turn off yas otherwise tab screws up (add-hook 'term-mode-hook (lambda() (yas-minor-mode -1))) (yas-reload-all)) #+END_SRC ** Writing *** adoc-mode :package: :PROPERTIES: :ID: b5336356-8c0d-45ab-a944-0ba58ecb3abb :END: Asciidoc. I rarely use this format anymore, but it's handy for legacy stuff. #+BEGIN_SRC emacs-lisp (use-package adoc-mode :ensure adoc-mode :mode ("\\.asciidoc\\'" . adoc-mode)) #+END_SRC *** htmlize :package: :PROPERTIES: :ID: 7dc0d2d7-1bfd-4932-bdf8-f45b7f5e2f76 :END: Used for HTMLizing buffers, but mostly for code block export in org-mode. #+BEGIN_SRC emacs-lisp (use-package htmlize :ensure htmlize) #+END_SRC *** markdown-mode :package: :PROPERTIES: :ID: 4742cb15-fd37-4d32-a76f-2650087eed40 :END: Markdown. Used mostly for blogging and README files. #+BEGIN_SRC emacs-lisp (use-package markdown-mode :mode (("\\.markdown\\'" . markdown-mode) ("\\.md\\'" . markdown-mode)) :ensure markdown-mode) #+END_SRC ** Utilities *** sauron :package: :PROPERTIES: :ID: 33e5abcf-f2b8-4a6e-8245-fefcca6d3856 :END: Notification system. Usually kept in its own window in a workgroup that also houses my org mode agenda. Handy way to see who msg'd while I was away. #+BEGIN_SRC emacs-lisp (use-package sauron :ensure sauron :commands sauron-start :config (setq sauron-separate-frame nil sauron-modules '(sauron-dbus sauron-org sauron-notifications) sauron-max-line-length 200 ;; 60 was a little long, and there's a lot of times I switch away quickly after ;; replying. sauron-nick-insensitivity 5)) #+END_SRC *** rg :package: :PROPERTIES: :ID: 8d0435cc-14af-48c8-ab84-44c6c4814052 :END: Frontend for ripgrep #+BEGIN_SRC emacs-lisp (use-package rg :ensure t) #+END_SRC ** Terminals *** ansi-color :package: :PROPERTIES: :ID: 7f251497-74c8-461c-bf43-5b143dbe0799 :END: Turn on ansi in shells #+BEGIN_SRC emacs-lisp (use-package ansi-color :ensure ansi-color :commands shell :config (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)) #+END_SRC *** eshell :package: :PROPERTIES: :ID: 46fa58de-6616-46f9-93a1-61bf365ed4c2 :END: #+BEGIN_SRC emacs-lisp (use-package eshell :ensure eshell :disabled t :commands eshell :config (progn ;; ;; Stealing from ESK, with some things removed (setq eshell-cmpl-cycle-completions nil eshell-save-history-on-exit t eshell-buffer-shorthand t eshell-cmpl-dir-ignore "\\`\\(\\.\\.?\\|CVS\\|\\.svn\\|\\.git\\)/\\'") ;;;###autoload (eval-after-load 'esh-opt '(progn (require 'em-prompt) (require 'em-term) (require 'em-cmpl) (require 'em-rebind) (setenv "PAGER" "cat") (set-face-attribute 'eshell-prompt nil :foreground "turquoise1") (add-hook 'eshell-mode-hook ;; for some reason this needs to be a hook '(lambda () (define-key eshell-mode-map "\C-a" 'eshell-bol))) (setq eshell-cmpl-cycle-completions nil) ;; TODO: submit these via M-x report-emacs-bug (add-to-list 'eshell-visual-commands "ssh") (add-to-list 'eshell-visual-commands "tail") (add-to-list 'eshell-command-completions-alist '("gunzip" "gz\\'")) (add-to-list 'eshell-command-completions-alist '("tar" "\\(\\.tar|\\.tgz\\|\\.tar\\.gz\\)\\'")))) ;; these two haven't made it upstream yet ;;;###autoload (when (not (functionp 'eshell/find)) (defun eshell/find (dir &rest opts) (find-dired dir (mapconcat (lambda (arg) (if (get-text-property 0 'escaped arg) (concat "\"" arg "\"") arg)) opts " ")))) ;;;###autoload (when (not (functionp 'eshell/rgrep)) (defun eshell/rgrep (&rest args) "Use Emacs grep facility instead of calling external grep." (eshell-grep "rgrep" args t))) (defface esk-eshell-error-prompt-face '((((class color) (background dark)) (:foreground "red" :bold t)) (((class color) (background light)) (:foreground "red" :bold t))) "Face for nonzero prompt results" :group 'eshell-prompt) (add-hook 'eshell-after-prompt-hook (defun esk-eshell-exit-code-prompt-face () (when (and eshell-last-command-status (not (zerop eshell-last-command-status))) (let ((inhibit-read-only t)) (add-text-properties (save-excursion (beginning-of-line) (point)) (point-max) '(face esk-eshell-error-prompt-face)))))))) #+END_SRC ** Misc *** easy-pg :package: :PROPERTIES: :ID: 9e91eaaa-4868-4f9c-8b50-982337bbb2d0 :END: gpg file auto query/loading #+BEGIN_SRC emacs-lisp (use-package epa-file :defer t :config (progn (epa-file-enable) (setq epa-file-cache-passphrase-for-symmetric-encryption t))) #+END_SRC *** proced :package: :PROPERTIES: :ID: 5e02cdea-930d-4304-b11b-dcc02285c93a :END: #+BEGIN_SRC emacs-lisp (use-package proced :commands (proced) :config (progn (setq proced-auto-update-interval 2) (defun qdot/proced-settings () (proced-toggle-auto-update t)) (add-hook 'proced-mode-hook 'qdot/proced-settings))) #+END_SRC *** qblog :package: :PROPERTIES: :ID: 3a106b89-a33b-42df-b642-d0b932693eae :END: #+BEGIN_SRC emacs-lisp (use-package qblog :defer t :commands (qblog/new-blog-post) :load-path "~/.emacs_files/dev-packages/qblog" :init (setq qblog/blog-base-dir (expand-file-name "~/code/git-projects")) (setq qblog/blog-post-dir "/content/posts/") (setq qblog/blog-list '("metafetish.com" "nonpolynomial.com" "openyou.org")) (setq qblog/image-base-dir "~/code/git-projects/metafetish.com/content/images") (setq qblog/blog-file-extension ".markdown")) #+END_SRC *** qdot-funcs :package: :PROPERTIES: :ID: 3145e293-844a-473c-903c-31c1f7200af0 :END: #+BEGIN_SRC emacs-lisp (require 'qdot-funcs) (bind-key "C-c C-s" 'qdot/sudo-edit-current-file) (bind-key "C-c C-r" 'qdot/reload-file) ;; remap C-a to `smarter-move-beginning-of-line' (bind-key [remap move-beginning-of-line] 'qdot/smarter-move-beginning-of-line) #+END_SRC * Keybinds :PROPERTIES: :ID: 7f61df27-4dcc-46e6-916c-00e3ca7d6ce8 :END: #+BEGIN_SRC emacs-lisp (bind-key "C-c r" 'revert-buffer) (bind-key "C-c v" 'visual-line-mode) (bind-key "C-c e" 'eval-and-replace) (bind-key "C-x C-k" 'kill-region) (bind-key "C-x k" 'qdot/kill-this-buffer) (bind-key "C-x C-b" 'ibuffer-other-window) (bind-key "C-c C-m" 'execute-extended-command) (bind-key "C-c C-k" 'kill-region) (bind-key "C-M-g" 'goto-line) (bind-key "C-w" 'backward-kill-word) ;; make this like shell. ;; Don't need backgrounding (bind-key "C-z" nil) ;; Stealin' from esk ;; http://whattheemacsd.com//key-bindings.el-03.html (bind-key "M-j" (lambda () (interactive) (join-line -1))) #+END_SRC * Function Warnings/Disables :PROPERTIES: :ID: 8dbbba25-07b7-4fe9-9130-03497b099275 :END: #+BEGIN_SRC emacs-lisp (put 'downcase-region 'disabled nil) #+END_SRC * Startup Timing Output :PROPERTIES: :ID: 15d8cfb3-a1b6-4572-ad44-8f4541e0af71 :END: Taken from jwiegley's conf https://github.com/jwiegley/dot-emacs/blob/master/init.el #+BEGIN_SRC emacs-lisp (when window-system (let ((elapsed (float-time (time-subtract (current-time) qdot/emacs-start-time)))) (message "Loading %s...done (%.3fs)" load-file-name elapsed)) (add-hook 'after-init-hook `(lambda () (let ((elapsed (float-time (time-subtract (current-time) qdot/emacs-start-time)))) (message "Loading %s...done (%.3fs) [after-init]" ,load-file-name elapsed))) t)) #+END_SRC * Hooks :PROPERTIES: :ID: d11880e5-e8d6-4dcb-8216-5fc000b2ae08 :END: Extra hooks to functions from the qdot-funcs modules #+BEGIN_SRC emacs-lisp ;; Make sure we want to quit (add-hook 'kill-emacs-query-functions 'qdot/ask-before-quit) ;; Whenever a mouse click has happened, clear the minibuffer (add-hook 'mouse-leave-buffer-hook 'qdot/stop-using-minibuffer) ;; Byte compile buffer whenever we save (add-hook 'after-save-hook 'qdot/byte-compile-current-buffer) #+END_SRC * Tasks :noexport: ** TODO bug-reference-mode http://www.lunaryorn.com/2014/12/23/bug-reference-mode.html ** TODO Add repo search capability for magit-repo-dirs :emacs: :LOGBOOK: CLOCK: [2014-03-02 Sun 14:17]--[2014-03-02 Sun 14:18] => 0:01 :END: [2014-03-02 Sun] ** TODO Check out Skewer for emacs :LOGBOOK: CLOCK: [2013-07-24 Wed 14:57]--[2013-07-24 Wed 14:58] => 0:01 :END: [2013-07-24 Wed] http://nullprogram.com/blog/2012/10/31/ https://github.com/skeeto/skewer-mode ** TODO Fix agenda display of mozilla subtree in email task file ** TODO Make org date function that will show events on certain days AFTER a certain date ** TODO Aggressive Indent ** TODO Collapse diminishes into use-package calls ** TODO Sort out python mode settings ** TODO Fold functions file into base config file ** TODO Fold bernt's org functions info base config file ** exwm *** TODO Check out gpastel https://gitlab.petton.fr/DamienCassou/gpastel ** Programming mode tasks *** TODO Clean up python/elpy configuration, split properly *** TODO Turn on git-gutter-fringe everywhere possible *** TODO Make keybind for git-messenger?