Table of Contents
+-
+
- 1. About +
- 2. Early
+
-
+
- 2.1. Lexical Binding +
- 2.2. Setup auto-compile +
- 2.3. Prefer Newer Versions +
- 2.4. Custom Files +
- 2.5. emit + + +
- 2.6. Benchmarking +
- 2.7. GUI Disables +
- 2.8. Byte-Compiler +
- 2.9. exec-path-from-shell +
- 2.10. Non-Forking Shell Command To String +
- 2.11. Security +
- 2.12. ELPA Archive Setup +
- 2.13. Bootstrap Package Loading +
- 2.14. Set EMACS environment variable +
+ - 3. Functions
+
-
+
- 3.1. Join Paths +
- 3.2. Variables +
- 3.3. Use Package Wrapper With Local Load Path Support +
- 3.4. Required Packages + + +
- 3.5. Macros + + +
- 3.6. Add Files to
org-agenda-files
+ - 3.7. Get String From File +
- 3.8. Get Current Location +
- 3.9. Haversine distance +
- 3.10. Font Size +
- 3.11. Message Result Builder +
- 3.12. Custom
shell-command-on-region
+ - 3.13. Copy String Functions + + +
- 3.14. Named Compile +
- 3.15. Replace Escape Sequences +
- 3.16. Download a File Into a Buffer +
- 3.17. Concat With Symbols +
- 3.18. Edit a script on PATH +
- 3.19. Toggle lexical binding in the current buffer +
- 3.20. Sync kill ring with copyq +
- 3.21. Other +
- 3.22. Keyboard Macros + + +
+ - 4. General
+
-
+
- 4.1. User Info +
- 4.2. Sane Defaults +
- 4.3. Line Numbers +
- 4.4. Backups + + +
- 4.5. Prompts + + +
- 4.6. Splitting +
- 4.7. Fill Setup +
- 4.8. Encoding +
- 4.9. Visible Bell +
- 4.10. Configure
vc
+ - 4.11. Time in Mode Line +
- 4.12. Kill Ring +
- 4.13. Subword +
- 4.14. Scratch Buffer +
- 4.15. Don't prompt about local variables +
- 4.16. proced +
- 4.17. Set default browser +
- 4.18. Set epa program +
- 4.19. Make files executable +
- 4.20. Misc +
- 4.21. paradox +
- 4.22. diminish +
- 4.23. edit-server +
- 4.24. load-dir +
- 4.25. server +
- 4.26. list-environment +
- 4.27. bug-hunter +
- 4.28. shackle +
- 4.29. beacon +
- 4.30. discover-my-major +
- 4.31. refine +
- 4.32. winner +
- 4.33. eyebrowse +
- 4.34. fill-column-indicator +
- 4.35. overseer +
+ - 5. Keybindings + + +
- 6. Navigation + + +
- 7. Completion
+
-
+
- 7.1. company + + +
- 7.2. auto-complete +
+ - 8. Text Manipulation + + +
- 9. Source Control + + +
- 10. Major Modes
+
-
+
- 10.1. Programming + + +
- 10.2. Data/Config/Protocol + + +
- 10.3. Document + + +
- 10.4. Utility + + +
+ - 11. Programming + + +
- 12. Utility + + +
- 13. Chat + + +
- 14. Cooperation + + +
- 15. Other
+
-
+
- 15.1. anzu +
- 15.2. fontawesome +
- 15.3. shell-history +
- 15.4. iedit +
- 15.5. tramp +
- 15.6. flycheck +
- 15.7. narrow-indirect +
- 15.8. editorconfig +
- 15.9. dtrt-indent +
- 15.10. indent-guide +
- 15.11. rainbow-delimiters +
- 15.12. undo-tree +
- 15.13. recentf +
- 15.14. key-chord +
- 15.15. nodejs-repl +
- 15.16. calc-mode +
- 15.17. helm-spotify +
- 15.18. jabber +
- 15.19. htmlize +
- 15.20. calfw +
- 15.21. clocker +
- 15.22. deft +
- 15.23. epg +
- 15.24. pinentry +
- 15.25. twittering-mode +
- 15.26. matrix-client +
- 15.27. mu4e +
- 15.28. gmail-message-mode +
- 15.29. ham-mode +
- 15.30. alert +
- 15.31. sauron +
- 15.32. screenshot +
- 15.33. libmpdee +
- 15.34. flyspell +
- 15.35. web-mode +
- 15.36. helm-themes +
- 15.37. helm-swoop +
- 15.38. perspective +
- 15.39. smex +
- 15.40. java +
- 15.41. android-mode +
- 15.42. gradle-mode +
- 15.43. jsx-mode +
- 15.44. css +
- 15.45. robe +
- 15.46. rinari +
- 15.47. helm-gtags +
- 15.48. sgml-mode +
- 15.49. evil +
- 15.50. hackernews +
+ - 16. Appearance + + +
- 17. Post Init Custom +
1 About
++This is my emacs configuration in literate form. It aspires to be like the +incredibly well commented literate configurations of Sacha Chua and Ryan Rix, +but I haven't quite gotten around to polishing it to the point where nearly +every section has commentary explaining why it is there, as those two have. +
+ ++Still, there are definitely a few sections of which I am quite proud, and that +others may find to be useful. +
+2 Early
++The configurations in this section need to occur early in emacs startup for some reason or another. +
+2.1 Lexical Binding
++This makes it so that the file that is produced from tangling this +file uses lexical scoping. +
+;;; -*- lexical-binding: t -*- +(setq-default lexical-binding t) ++
2.2 Setup auto-compile
+(when (boundp 'use-package) + (use-package auto-compile + :ensure t + :config + (progn + (auto-compile-on-load-mode) + (auto-compile-on-save-mode)))) ++
2.3 Prefer Newer Versions
++To reduce the risk of loading outdated byte code files, we set +load-prefer-newer and enable auto-compile-on-load-mode as early as +possible. +
+(setq load-prefer-newer t) ++
2.4 Custom Files
+
+The default value of custom-file
is just the current user's .emacs.d/init.el
+file. Emacs will add content to custom-file
whenever a variable is customized
+or marked as safe. When init.el is version controlled, it is quite annoying to
+have random machine-generated variable settings amended to it because those
+changes are often not worth keeping permanently, so we set a different custom
+file here to avoid this situation.
+
+custom-before.el is loaded before the rest of init.el, while custom-after.el is +loaded afterwards. this-machine.el has customizations that should only apply to +the current machine. custom-before and custom-after are not version controlled +in the dotfiles repo but they are shared across machines elsewhere. +
+(defvar machine-custom "~/.emacs.d/this-machine.el") +(defvar custom-after-file "~/.emacs.d/custom-after.el") +(setq custom-file "~/.emacs.d/custom-before.el") +(when (file-exists-p custom-file) (load custom-file)) ++
2.5 emit
+2.5.1 TODO this needs to be done better, but it works for now
+(when (file-exists-p "~/.emacs.d/load.d/emit.el") + (load "~/.emacs.d/load.d/emit.el")) ++
2.6 Benchmarking
++This appears here so that it can accurately benchmark as much of +startup as possible. +
+(defvar imalison:do-benchmark) + (when (and (boundp 'use-package) + (bound-and-true-p imalison:do-benchmark)) + (use-package benchmark-init)) ++
2.7 GUI Disables
++Death to any gui elements in emacs! Do this EARLY so that emacs +doesn't redisplay in a way that is visually unpleasant on startup a +bunch of times. +
+(when (fboundp 'menu-bar-mode) (menu-bar-mode -1)) +(when (fboundp 'tool-bar-mode) (tool-bar-mode -1)) +(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1)) ++
+Tooltips are annoying: +
+(if (fboundp 'tooltip-mode) (tooltip-mode -1) (setq tooltip-use-echo-area t))' ++
2.8 Byte-Compiler
++These definitions silence the byte-compiler. +
+(defvar grep-find-ignored-directories nil) +(defvar grep-find-ignored-files nil) +(defvar ido-context-switch-command nil) +(defvar ido-cur-item nil) +(defvar ido-cur-list nil) +(defvar ido-default-item nil) +(defvar inherit-input-method nil) +(defvar oauth--token-data nil) +(defvar tls-checktrust nil) +(defvar tls-program nil) +(defvar url-callback-arguments nil) +(defvar url-callback-function nil) +(defvar url-http-extra-headers nil) ++
;; This variable doesn't exist in old versions of org-mode +(defvar org-show-context-detail) ++
2.9 exec-path-from-shell
++Sets environment variables by starting a shell. +
+;; TODO: this does not seem to actually install exec-path-from-shell +(eval-and-compile + (when (fboundp 'use-package) + (use-package exec-path-from-shell + :config + (progn + ;; For debugging + (when nil + (message "path: %s, setup: %s" (getenv "PATH") + (getenv "ENVIRONMENT_SETUP_DONE")) + (setq exec-path-from-shell-debug t)) + (setq exec-path-from-shell-arguments (list "-l")) + (setq exec-path-from-shell-check-startup-files nil) + (add-to-list 'exec-path-from-shell-variables "SHELL") + (add-to-list 'exec-path-from-shell-variables "GOPATH") + (add-to-list 'exec-path-from-shell-variables "ENVIRONMENT_SETUP_DONE") + (add-to-list 'exec-path-from-shell-variables "PYTHONPATH") + (exec-path-from-shell-initialize))))) ++
2.10 Non-Forking Shell Command To String
+
+Emacs' built in shell-command-to-string
function has the downside that it
+forks a new shell process every time it is executed. This means that any shell
+startup cost is incurred when this function is called.
+
+The following implementation uses eshell's executable-find
to find the
+binary (which is the only reason shell-comand-to-string
is typically used
+anyway), but it avoids incurring any shell-startup cost.
+
+This was originally inspired by this issue. +
+(defun imalison:call-process-to-string (program &rest args) + (with-temp-buffer + (apply 'call-process program nil (current-buffer) nil args) + (buffer-string))) + +(defun imalison:get-call-process-args-from-shell-command (command) + (cl-destructuring-bind + (the-command . args) (split-string command " ") + (let ((binary-path (executable-find the-command))) + (when binary-path + (cons binary-path args))))) + +(defun imalison:shell-command-to-string (command) + (let ((call-process-args + (imalison:get-call-process-args-from-shell-command command))) + (if call-process-args + (apply 'imalison:call-process-to-string call-process-args) + (shell-command-to-string command)))) ++
+This makes it so that we always try to call-process instead of shell-command-to-sting. It may cause undesireable behavior. +
+(defun imalison:try-call-process (command) + (let ((call-process-args + (imalison:get-call-process-args-from-shell-command command))) + (if call-process-args + (apply 'imalison:call-process-to-string call-process-args)))) + +(advice-add 'shell-command-to-string :before-until 'imalison:try-call-process) ++
2.11 Security
+(defvar imalison:secure t) + +(defun imalison:use-https-and-tls () + (setq tls-checktrust t) + (let ((trustfile + (replace-regexp-in-string + "\\\\" "/" + (replace-regexp-in-string + "\n" "" + (shell-command-to-string "python -m certifi"))))) + (setq tls-program + (list + (format "gnutls-cli%s --x509cafile %s -p %%p %%h" + (if (eq window-system 'w32) ".exe" "") trustfile))))) + +(defun imalison:test-security () + (interactive) + (let ((bad-hosts + (loop for bad + in `("https://wrong.host.badssl.com/" + "https://self-signed.badssl.com/") + if (condition-case _e + (url-retrieve + bad (lambda (_retrieved) t)) + (error nil)) + collect bad))) + (if bad-hosts + (error (format "tls misconfigured; retrieved %s ok" + bad-hosts)) + (url-retrieve "https://badssl.com" + (lambda (_retrieved) t))))) + +(when imalison:secure (imalison:use-https-and-tls)) ++
2.12 ELPA Archive Setup
++The org archive does not support https, so we set http as the protocol explicitly. +
+1: (require 'package) + 2: + 3: (defun imalison:build-archive-uri (uri protocol) + 4: (unless protocol (setq protocol (if imalison:secure "https" "http"))) + 5: (format "%s://%s" protocol uri)) + 6: + 7: (defvar imalison:melpa-uri nil) + 8: (defvar imalison:package-archive-triples + 9: `(("elpa" "tromey.com/elpa/" "http") +10: ("org" "orgmode.org/elpa/" "http") +11: ("melpa" ,(or imalison:melpa-uri "melpa.org/packages/") nil) +12: ("melpa-stable" "stable.melpa.org/packages/" nil))) +13: +14: (defun imalison:add-package-archive (archive-name archive-uri) +15: (add-to-list 'package-archives +16: `(,archive-name . ,archive-uri) t)) +17: +18: (cl-loop for package-triple in imalison:package-archive-triples +19: do (cl-destructuring-bind (archive-name archive-uri protocol) package-triple +20: (imalison:add-package-archive +21: archive-name (imalison:build-archive-uri archive-uri protocol)))) ++
2.13 Bootstrap Package Loading
+
+Its a shame that everyone has to have some version of this function in
+their init.el. I use use-package's own mechanism for ensuring packages
+are installed so my version of ensure-packages-installed
is really
+only used to download use-package itself.
+
(defun ensure-packages-installed (packages) + (unless package-archive-contents + (package-refresh-contents)) + (mapcar + (lambda (package) + (if (package-installed-p package) + package + (progn (message (format "Installing package %s." package)) + (package-install package)))) + packages)) ++
+Ensure that use-package is installed. +
+(package-initialize t) +(ensure-packages-installed '(use-package)) ++
+use-package is only needed at compile time. +
+(eval-when-compile (require 'use-package)) ++
+Ensure by default since most of the package for which I use use-package need to be downloaded. ensure can be disabled explicitly with a :ensure nil
.
+
(setq use-package-always-ensure t) ++
2.14 Set EMACS environment variable
++Emacs cask seems to depend on the EMACS environment variable being set to the +binary path of emacs. I found the method for getting the path to the emacs +executable here. +
+(setenv "EMACS" + (file-truename (expand-file-name invocation-name invocation-directory))) ++
+Update: It turns out that it is term-exec-1 that is causing this environment +variable to be set to something strange. When I tried to disable it, it seemed +to cause issues. Oh well… +
+3 Functions
+3.1 Join Paths
++Works in the same way as os.path.join in python +
+(defun imalison:join-paths (root &rest dirs) + (let ((result root)) + (cl-loop for dir in dirs do + (setq result (concat (file-name-as-directory result) dir))) + result)) ++
3.2 Variables
+(defvar imalison:projects-directory + (imalison:join-paths (substitute-in-file-name "$HOME") "Projects")) + +(defvar imalison:gpg-key) ++
3.3 Use Package Wrapper With Local Load Path Support
+(put 'imalison:use-package 'lisp-indent-function 'defun) +(put 'imalison:use-package* 'lisp-indent-function 'defun) + +(defmacro imalison:use-package* (package target-directory &rest forms) + (let* ((actual-target (if (file-exists-p target-directory) + target-directory + (let ((in-projects (imalison:join-paths imalison:projects-directory + target-directory))) + (when (file-exists-p in-projects) + in-projects)))) + (additional-forms + (when actual-target + (list + :load-path actual-target + :ensure nil)))) + `(use-package ,package + ,@additional-forms ,@forms))) + +(defmacro imalison:use-package (package &rest forms) + `(imalison:use-package* ,package ,(symbol-name package) ,@forms)) ++
3.4 Required Packages
++The packages in this section provide no functionality on their own, +but provide support for writing custom elisp. +
+3.4.1 s
+(use-package s :demand t) ++
3.4.2 dash
+(use-package dash + :config + (progn + (dash-enable-font-lock))) ++
3.4.3 gh
+(imalison:use-package* gh "gh.el" + :demand t) ++
3.4.4 shut-up
+(use-package shut-up + :config + (defun imalison:shut-up-around (function &rest args) + (shut-up (apply function args)))) ++
3.4.5 pcache
+(use-package pcache + :demand t) ++
3.4.6 parse-csv
+(use-package parse-csv + :demand t) ++
3.4.7 emit
++This is disabled for now until I figure out what to do with emit. +
+(imalison:use-package emit + :disabled t + :demand t) +(require 'emit) ++
3.4.8 request
+(use-package request) ++
3.5 Macros
+3.5.1 Named Build
++imalison:named-build provides a way to invoke a macro in such a way +that the lambda that it produces is given a name. +
+(defmacro imalison:named-build (name builder &rest args) + `(defalias (quote ,name) (,builder ,@args))) +(put 'imalison:named-build 'lisp-indent-function 1) ++
+imalison:named-builder-builder
builds a macro from another macro
+that builds lambda functions. The arguments to the macro that results
+are exactly the same as those of the original macro, except that the
+first argument of the new macro is used to name the lambda produced by
+the original macro (which is passed as the second argument to
+imalison:named-builder-builder
).
+
(defmacro imalison:named-builder-builder (named-builder-name builder-name) + `(progn + (defmacro ,named-builder-name (function-name &rest args) + (cons 'imalison:named-build + (cons function-name + (cons (quote ,builder-name) args)))) + (put (quote ,named-builder-name) 'lisp-indent-function 1))) ++
+imalison:named-builder
runs imalison:named-builder-builder
with the
+convention that original macro to modify is the concatenation of the
+new macro name and the -fn suffix.
+
(defmacro imalison:named-builder (name) + `(imalison:named-builder-builder + ,name ,(intern (concat (symbol-name name) "-fn")))) ++
3.5.2 Emacs Version Predicate
+(defmacro imalison:emacs-version-predicate-fn (major-version minor-version) + `(lambda () + (or (> emacs-major-version ,major-version) + (and (>= emacs-major-version ,major-version) + (>= emacs-minor-version ,minor-version))))) + +(defun imalison:check-emacs-version (major-version minor-version) + (funcall (imalison:emacs-version-predicate-fn major-version minor-version))) + +(imalison:named-builder imalison:emacs-version-predicate) ++
3.5.3 Compose Functions
+- A version supporting macros++ ++
(defun imalison:help-function-arglist (fn) + (let ((result (help-function-arglist fn))) + (if (eq result t) '(&rest args) result))) + +(defmacro imalison:compose-fn (&rest funcs) + (let* ((last-function (car (last funcs))) + (arguments (imalison:help-function-arglist last-function)) + (call-arguments (delq '&optional arguments))) + ;; When we have an &rest arguments there is no point in taking any + ;; of the arguments by name, so we simply pass them all as an + ;; argument list. See the comment below to understand how this + ;; impacts the evaluation of the last function. + (when (memq '&rest arguments) + (setq arguments '(&rest args)) + (setq call-arguments '(args))) + `(imalison:compose-argspec ,arguments ,call-arguments ,@funcs))) + +(defmacro imalison:compose-argspec (arguments call-arguments &rest funcs) + "Build a new function with NAME that is the composition of FUNCS." + `(lambda ,arguments + (imalison:compose-helper ,funcs ,call-arguments))) + +(defmacro imalison:compose-helper (funcs arguments) + "Builds funcalls of FUNCS applied to the arg." + (if (equal (length funcs) 1) + (let ((last-function (car funcs))) + ;; This hideous clause is here because it is the only way to + ;; handle functions that take &rest args. + (when (memq '&rest (imalison:help-function-arglist last-function)) + (setq last-function (apply-partially 'apply last-function))) + `(,last-function ,@arguments)) + `(,(car funcs) + (imalison:compose-helper ,(cdr funcs) ,arguments)))) + +(defmacro imalison:compose-macro-fn (&rest args) + `(cons 'macro (imalison:compose-fn ,@args))) + +(imalison:named-builder imalison:compose) +(imalison:named-builder imalison:compose-macro) +
+
+ - Arbitrary arguments at every step++ ++
(defun imalison:make-list (thing) + (if (listp thing) + thing + (list thing))) + +(defmacro imalison:compose-with-apply (&rest funcs) + "Build a new function with NAME that is the composition of FUNCS." + `(lambda (&rest args) + (imalison:compose-with-apply-helper ,funcs))) + +(defmacro imalison:compose-with-apply-helper (funcs) + "Builds funcalls of FUNCS applied to the arg." + (if (equal (length funcs) 0) + (quote args) + `(apply ,(car funcs) + (imalison:make-list (imalison:compose-with-apply-helper ,(cdr funcs)))))) +
+
+ - Simpler unary version++ ++
(defmacro imalison:compose-unary (&rest funcs) + "Build a new function with NAME that is the composition of FUNCS." + `(lambda (arg) + (imalison:compose-helper-unary ,funcs))) + +(defmacro imalison:compose-helper-unary (funcs) + "Builds funcalls of FUNCS applied to the arg." + (if (equal (length funcs) 0) + 'arg + `(funcall ,(car funcs) (imalison:compose-helper-unary ,(cdr funcs))))) +
+
3.5.4 Make Interactive
+(defmacro imalison:make-interactive-fn (function) + `(lambda (&rest args) + (interactive) + (apply ,function args))) + +(imalison:named-builder imalison:make-interactive) ++
3.5.5 Advice Add Around Builder
+
+For composing functions with an apply so that they can be used with
+the :around
keyword of advice-add.
+
(defmacro imalison:advice-add-around-builder-fn (&rest functions) + `(imalison:compose-argspec + (function &rest args) (function args) ,@functions apply)) + +(imalison:named-builder imalison:advice-add-around-builder) ++
3.5.6 Let Around
+(defmacro imalison:let-around-fn (orig-func &rest forms) + (let* ((orig-interactive-form (interactive-form orig-func)) + (docstring-form (format "Call `%s' with bindings: %s." orig-func forms)) + (additional-forms (list docstring-form))) + (when orig-interactive-form + (nconc additional-forms (list orig-interactive-form))) + `(lambda (&rest args) + ,@additional-forms + (let ,forms + (apply (quote ,orig-func) args))))) + +(imalison:named-builder imalison:let-around) ++
3.5.7 Let Around Advice
+(defmacro imalison:let-advise-around-fn (&rest forms) + `(lambda (orig-func &rest args) + (let ,forms + (apply orig-func args)))) + +(imalison:named-builder imalison:let-advise-around) ++
3.5.8 Compose Around Builder
+
+For composing functions with an apply so that they can be used with the :around
keyword of advice-add.
+
;; TODO/XXX: Isn't this just apply? why doesn't apply work here +(defun imalison:around-identity (fn &rest args) + (apply fn args)) + +(defmacro imalison:compose-around-builder-fn (&rest functions) + `(imalison:compose-fn ,@functions imalison:around-identity)) + +(imalison:named-builder imalison:compose-around-builder) ++
3.5.9 Measure Time
+(defmacro imalison:measure-time (&rest body) + "Measure and return the running time of the code block." + (declare (indent defun)) + (let ((start (make-symbol "start"))) + `(let ((,start (float-time))) + ,@body + (- (float-time) ,start)))) ++
3.6 Add Files to org-agenda-files
+(defun imalison:add-to-org-agenda-files (incoming-files) + (setq org-agenda-files + (delete-dups + (cl-loop for filepath in (append org-agenda-files incoming-files) + when (and filepath (file-exists-p (file-truename filepath))) + collect (file-truename filepath))))) ++
3.7 Get String From File
+(defun imalison:get-string-from-file (file-path) + "Return file-path's file content." + (with-temp-buffer + (insert-file-contents file-path) + (buffer-string))) ++
3.8 Get Current Location
+(defun imalison:get-lat-long () + (condition-case _ex + (mapcar 'string-to-number (s-split "," (s-trim (shell-command-to-string + "whereami")))) + (error (list 37.7879312624533 -122.402388853402)))) ++
3.9 Haversine distance
+(defun imalison:sin2 (p) + (let ((sin-p (sin p))) + (* sin-p sin-p) )) + +(defun imalison:haversine-distance + (left-lat-long right-lat-long &optional radius) + ;; Default to earth radius in km + (unless radius (setq radius 6378.1)) + (interactive) + (cl-destructuring-bind (left-lat left-long) left-lat-long + (cl-destructuring-bind (right-lat right-long) right-lat-long + (let ((l1 (degrees-to-radians left-lat)) + (f1 (degrees-to-radians left-long)) + (l2 (degrees-to-radians right-lat)) + (f2 (degrees-to-radians right-long)) ) + (* 2 radius + (asin + (sqrt + (+ (imalison:sin2 (/ (- f2 f1) 2)) + (* (cos f2) (cos f1) (imalison:sin2 (/ (- l2 l1) 2))) )))))))) ++
3.10 Font Size
++This was taken from here but it has diverged significantly from the original. +
+(defvar imalison:default-font-size-pt + (cond ((eq system-type 'darwin) 120) + ((eq system-type 'gnu/linux) 105))) + +(defvar imalison:huge-font-size 280) + +(defun imalison:current-font-size () + (plist-get (custom-face-attributes-get 'default nil) :height)) + +(defun imalison:set-font-size (size) + (interactive (list (string-to-number (read-string "Enter a font size: ")))) + (set-face-attribute 'default nil :height size)) + +(defun imalison:set-huge-font-size () + (interactive) + (imalison:set-font-size imalison:huge-font-size)) + +(cl-defun imalison:modify-font-size (&optional (arg 10)) + (interactive "p") + (imalison:set-font-size (+ (imalison:current-font-size) arg))) + +(defun imalison:font-size-incr () + (interactive) + (imalison:modify-font-size +10)) + +(defun imalison:font-size-decr () + (interactive) + (imalison:modify-font-size -10)) + +(defun imalison:font-size-reset () + (interactive) + (imalison:set-font-size imalison:default-font-size-pt)) ++
3.11 Message Result Builder
++This macro is useful when writing emacs-lisp. It creates a new interactive command that shows you the result of evaluating a function, with optionally provided arguments. +
+(defmacro imalison:message-result-builder (new-function-name function-to-call &rest args) + `(defun ,new-function-name () + (interactive) + (message "%s" (apply (quote ,function-to-call) (list ,@args))))) ++
+This interactive functions allows the user the select a function to invoke using a freshly minted imalison:message-result-builder +
+(defun imalison:message-result-builder-runtime (function &rest args) + (lambda () + (interactive) + (message "%s" (apply function-to-call args)))) + +(defun imalison:message-function-result (function) + (interactive (find-function-read)) + (message "%s" (funcall function))) ++
3.12 Custom shell-command-on-region
+(defun imalison:copy-shell-command-on-region (start end command) + (interactive (list (region-beginning) (region-end) + (read-shell-command "Shell command on region: "))) + (let ((original-buffer (current-buffer))) + (with-temp-buffer + (let ((temp-buffer (current-buffer))) + (with-current-buffer original-buffer + (shell-command-on-region start end command temp-buffer)) + (let ((min (point-min)) + (max (point-max))) + (kill-ring-save min max) + (buffer-substring min max)))))) + +(defun imalison:shell-command-on-region-replace (start end command) + (interactive (list (region-beginning) (region-end) + (read-shell-command "Shell command on region: "))) + (shell-command-on-region start end command nil t)) + +(emit-prefix-selector imalison:shell-command-on-region + imalison:copy-shell-command-on-region + imalison:shell-command-on-region-replace) ++
3.13 Copy String Functions
++A macro for composing functions together to build an interactive command to copy a string to the kill ring. +
+(defmacro imalison:compose-copy-builder-fn (&rest funcs) + `(imalison:make-interactive-fn + (imalison:compose-fn kill-new ,@funcs))) + +(imalison:named-builder imalison:compose-copy-builder) ++
3.13.1 Copy portions of the buffer file name
+(defmacro imalison:copy-buffer-file-path-builder (&rest args) + `(imalison:compose-copy-builder ,@args buffer-file-name)) + +(imalison:copy-buffer-file-path-builder imalison:copy-buffer-file-path-full) +(imalison:copy-buffer-file-path-builder imalison:copy-buffer-file-name + file-name-nondirectory) +(imalison:copy-buffer-file-path-builder imalison:copy-buffer-file-path + car + projectile-make-relative-to-root + list) ++
3.13.2 Copy the current branch using magit
+(imalison:compose-copy-builder imalison:copy-current-git-branch + magit-get-current-branch) ++
3.14 Named Compile
+(defun imalison:named-compile (command) + (interactive + (list + (let ((command (eval compile-command))) + (if (or compilation-read-command current-prefix-arg) + (compilation-read-command command) + command)))) + (compilation-start command nil (lambda (&rest args) + (format "*compilation %s*" command)))) ++
3.15 Replace Escape Sequences
+(defun imalison:replace-escape-sequences () + (interactive) + (shut-up + (let* ((delimited (and transient-mark-mode mark-active)) + (beg (when delimited (region-beginning))) + (end (when delimited (region-end)))) + (save-excursion + (perform-replace "\\t" " " nil nil delimited nil nil beg end nil)) + (save-excursion + (perform-replace "\\n" "\n" nil nil delimited nil nil beg end nil))))) ++
3.16 Download a File Into a Buffer
+(defun imalison:download-to-buffer (uri) + (interactive (list (read-string "Enter uri: "))) + (request uri + :parser 'buffer-string + :success (cl-function + (lambda (&key data &allow-other-keys) + (let ((created-buffer (get-buffer-create uri))) + (with-current-buffer created-buffer + (insert data)) + (switch-to-buffer created-buffer)))))) ++
3.17 Concat With Symbols
+(defun imalison:maybe-symbol-name (arg) + (if (symbolp arg) + (symbol-name arg) + arg)) + +(defun imalison:concat-symbols (&rest args) + (intern (mapconcat 'imalison:maybe-symbol-name args ""))) ++
3.18 Edit a script on PATH
+(defun imalison:get-executables-at-path (filepath) + (when (and (file-exists-p filepath) (f-directory? filepath)) + (--filter (let ((fullpath (imalison:join-paths filepath it))) + (and (file-executable-p fullpath) + (not (f-directory? fullpath)))) + (directory-files filepath)))) + +(defun imalison:get-executables-on-path () + (mapcan 'imalison:get-executables-at-path (eshell-parse-colon-path (getenv "PATH")))) + +(defun imalison:edit-script () + (interactive) + (find-file (executable-find + (ido-completing-read "Select a script to edit: " + (imalison:get-executables-on-path))))) ++
3.19 Toggle lexical binding in the current buffer
+(defun imalison:toggle-lexical-binding () + (interactive) + (let ((new-binding (not lexical-binding))) + (message "Setting lexical-binding to: %s" new-binding) + (setq lexical-binding new-binding))) ++
3.20 Sync kill ring with copyq
+(defun imalison:copyq-get (i) + (imalison:shell-command-to-string (format "copyq eval read(%s)" i))) + +(defun imalison:copyq-sync () + (interactive) + (let ((missing-items (cl-loop for i from 0 to (string-to-number + (imalison:shell-command-to-string "copyq eval size()")) + for item = (imalison:copyq-get i) + when (not (member item kill-ring)) + collect item))) + (setq kill-ring (nconc kill-ring missing-items)))) + +(when (executable-find "copyq") + (run-with-idle-timer 10 nil 'imalison:copyq-sync)) ++
3.21 Other
++The stuff in this section is pretty crusty. I don't think its used anywhere, but +I keep it around just in case I need it. +
+(defun random-choice (choices) + (nth (random (length choices)) choices)) + +(defun display-prefix (arg) + "Display the value of the raw prefix arg." + (interactive "p") + (message "%s" arg)) + +(defun imalison:uuid () + (interactive) + (s-replace "\n" "" (shell-command-to-string "uuid"))) + +(defun imalison:disable-linum-mode () + (linum-mode 0)) + +(defun imalison:disable-smartparens-mode () + (smartparens-mode 0)) + +(defun imalison:insert-uuid () + (interactive) + (insert (imalison:uuid))) + +(defun imalison:compare-int-list (a b) + (when (and a b) + (cond ((> (car a) (car b)) 1) + ((< (car a) (car b)) -1) + (t (imalison:compare-int-list (cdr a) (cdr b)))))) + +(defun get-date-created-from-agenda-entry (agenda-entry) + (org-time-string-to-time + (org-entry-get (get-text-property 1 'org-marker agenda-entry) "CREATED"))) + +(defmacro defvar-setq (name value) + `(if (boundp (quote ,name)) + (setq ,name ,value) + (defvar ,name ,value))) + +(defun eval-region-or-last-sexp () + (interactive) + (if (region-active-p) (call-interactively 'eval-region) + (call-interactively 'eval-last-sexp))) + +(defun undo-redo (&optional arg) + (interactive "P") + (if arg (undo-tree-redo) (undo-tree-undo))) + +(defun up-list-region () + (interactive) + (up-list) (set-mark-command nil) (backward-sexp)) + +(defun up-list-back () + (interactive) + (up-list) (backward-sexp)) + +(defun frame-exists () + (cl-find-if + (lambda (frame) + (assoc 'display (frame-parameters frame))) (frame-list))) + +(defun make-frame-if-none-exists () + (let* ((existing-frame (frame-exists))) + (if existing-frame + existing-frame + (make-frame-on-display (getenv "DISPLAY"))))) + +(defun make-frame-if-none-exists-and-focus () + (make-frame-visible (select-frame (make-frame-if-none-exists)))) + +(defun notification-center (title message) + (cl-flet ((encfn (s) (encode-coding-string s (keyboard-coding-system)))) + (shell-command + (format "osascript -e 'display notification \"%s\" with title \"%s\"'" + (encfn message) (encfn title))))) + +(defun growl-notify (title message) + (shell-command (format "grownotify -t %s -m %s" title message))) + +(defun notify-send (title message) + (shell-command (format "notify-send -u critical %s %s" title message))) + +(defvar notify-function + (cond ((eq system-type 'darwin) 'notification-center) + ((eq system-type 'gnu/linux) 'notify-send))) ++
(emit-prefix-selector imalison:mark-ring + helm-mark-ring + helm-global-mark-ring) ++
3.22 Keyboard Macros
+3.22.1 For editing literate config
+- extract-current-sexp-to-src-block+
+This keyboard macro extracts the current sexp to an emacs-lisp source block of its own +
++ ++(fset 'extract-current-sexp-to-src-block + [?\C-a return ?\C-p ?# ?+ ?E ?N ?D ?_ ?S ?R ?C return ?# ?+ ?B ?E ?G ?I ?N ?_ ?S ?R ?C ? ?e ?m ?a ?c ?s ?- ?l ?i ?s ?p ?\C-a ?\C-p ?\C- ?\C-n ?\C-e ?\M-w ?\C-n ?\C-a ?\C-\M-f return ?\C-y]) +
+
+ - name-source-block-for-use-package-name++ ++
(fset 'name-source-block-for-use-package-name + [?\C-c ?\' ?\M-< ?\C-s ?u ?s ?e ?- ?p ?a ?c ?k return ?\C-\M-f ?\C-f ?\C- ?\C-\M-f ?\M-w ?\C-c ?\' ?\C-r ?B ?E ?G ?I ?N return ?\C-a ?\C-p ?\C-e return ?* ? ?\C-y]) +
+
+ - extract-and-name-use-package-block++ ++
(fset 'extract-and-name-use-package-block + [?\C-a return ?\C-p ?# ?+ ?E ?N ?D ?_ ?S ?R ?C return ?# ?+ ?B ?E ?G ?I ?N ?_ ?S ?R ?C ? ?e ?m ?a ?c ?s ?- ?l ?i ?s ?p ?\C-a ?\C-p ?\C- ?\C-n ?\C-e ?\M-w ?\C-n ?\C-a ?\C-\M-f return ?\C-y ?\C-p ?\C-p ?\C-c ?\' ?\M-< ?\C-s ?u ?s ?e ?- ?p ?a ?c ?k return ?\C-\M-f ?\C-f ?\C- ?\C-\M-f ?\M-w ?\C-c ?\' ?\C-r ?B ?E ?G ?I ?N return ?\C-a ?\C-p ?\C-e return ?* ? ?\C-y]) +
+
4 General
+4.1 User Info
+(setq user-full-name + (replace-regexp-in-string "\n$" "" (shell-command-to-string + "git config --get user.name"))) +(setq user-mail-address + (replace-regexp-in-string "\n$" "" (shell-command-to-string + "git config --get user.email"))) ++
4.2 Sane Defaults
+1: (global-auto-revert-mode) +2: (show-paren-mode 1) +3: (setq reb-re-syntax 'string) +4: (setq ad-redefinition-action 'accept) +5: (setq-default find-file-visit-truename t) +6: (setq large-file-warning-threshold (* 25 1024 1024)) +7: (setq line-move-visual t) +8: (setq require-final-newline t) ++
+This is set because this alias causes annoying messaging at startup. +
+4.3 Line Numbers
+(line-number-mode t) +(column-number-mode t) ++
+Linum can be really slow on large files so it does not make sense to +have it on by default. Its probably safe to turn it on when in a +programming mode. +
+(global-linum-mode -1) +(add-hook 'prog-mode-hook (lambda () (linum-mode t))) ++
4.4 Backups
+4.4.1 Put them all in one directory
+(defconst emacs-tmp-dir + (format "%s/%s%s/" temporary-file-directory "emacs" (user-uid))) +(setq backup-directory-alist `((".*" . ,emacs-tmp-dir))) +(setq auto-save-file-name-transforms `((".*" ,emacs-tmp-dir t))) +(setq auto-save-list-file-prefix emacs-tmp-dir) ++
4.4.2 Completely disable backups
+(setq backup-inhibited t) +(setq make-backup-files nil) +(setq auto-save-default nil) ++
4.5 Prompts
+4.5.1 No popup frames
+(setq ns-pop-up-frames nil) +(setq pop-up-frames nil) ++
4.5.2 boolean (yes-or-no)
+1: (defadvice yes-or-no-p (around prevent-dialog activate) + 2: "Prevent yes-or-no-p from activating a dialog" + 3: (let ((use-dialog-box nil)) + 4: ad-do-it)) + 5: + 6: (defadvice y-or-n-p (around prevent-dialog-yorn activate) + 7: "Prevent y-or-n-p from activating a dialog" + 8: (let ((use-dialog-box nil)) + 9: ad-do-it)) +10: +11: (defalias 'yes-or-no-p 'y-or-n-p) ++
4.5.3 No dialog boxes
+(setq use-dialog-box nil) ++
4.6 Splitting
+(defun split-horizontally-for-temp-buffers () (split-window-horizontally)) +(add-hook 'temp-buffer-setup-hook 'split-horizontally-for-temp-buffers) +(setq split-height-threshold nil) +(setq split-width-threshold 160) ++
4.7 Fill Setup
++Get rid of nags about requiring setences to end with two spaces. +
+(setq sentence-end-double-space nil) ++
+Set the default fill-column +
+(setq-default fill-column 80) ++
4.8 Encoding
++UTF-8 everywhere +
+(defun imalison:set-coding-systems () + (interactive) + (set-language-environment "Latin-1") + (set-default-coding-systems 'utf-8) + (unless (eq system-type 'windows-nt) + (set-selection-coding-system 'utf-8)) + (set-terminal-coding-system 'utf-8) + (setq locale-coding-system 'utf-8) + (prefer-coding-system 'utf-8)) +(imalison:set-coding-systems) ++
+Disable CJK coding/encoding (Chinese/Japanese/Korean characters) +
+(setq utf-translate-cjk-mode nil) ++
4.9 Visible Bell
++This is set to true to disable the annoying audible bell that plays +whenever there is an error. +
+(setq visible-bell t) ++
4.10 Configure vc
+(setq vc-follow-symlinks t) ++
4.11 Time in Mode Line
+(setq display-time-default-load-average nil) +(setq display-time-interval 1) +(setq display-time-format "%a|%m-%d|%r") +(display-time-mode 1) ++
4.12 Kill Ring
+(setq kill-ring-max 1000) ++
4.13 Subword
+
+This makes forward-word
and backward-word
understand snake and camel case.
+
(setq c-subword-mode t) +(global-subword-mode) ++
4.14 Scratch Buffer
+(setq initial-scratch-message "") ++
4.15 Don't prompt about local variables
+(defun risky-local-variable-p (&rest args) + nil) ++
4.16 proced
++proced is an top like utility that runs inside of emacs. The following sets auto updating automatically and makes the update interval faster. +
+(require 'proced) +(setq proced-auto-update-interval 1) +(add-hook 'proced-mode-hook (lambda () (proced-toggle-auto-update +1))) ++
4.17 Set default browser
+(when (equal system-type 'gnu/linux) + (setq browse-url-browser-function 'browse-url-generic + browse-url-generic-program "google-chrome-stable")) ++
4.18 Set epa program
+(setq epg-gpg-program "gpg") ++
4.19 Make files executable
+(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p) ++
4.20 Misc
+(defvar iedit-toggle-key-default nil) +(put 'set-goal-column 'disabled nil) +(auto-fill-mode -1) +(setq indent-tabs-mode nil) + +(setq confirm-nonexistent-file-or-buffer nil) + +;; No prompt for killing a buffer with processes attached. +(setq kill-buffer-query-functions + (remq 'process-kill-buffer-query-function + kill-buffer-query-functions)) + +(setq inhibit-startup-message t + inhibit-startup-echo-area-message t) + +;; This makes it so that emacs --daemon puts its files in ~/.emacs.d/server +;; (setq server-use-tcp t) + +;; Make buffer names unique. +(setq uniquify-buffer-name-style 'forward) + +;; Don't disable commands... +(setq disabled-command-function nil) + +;; Make forward word understand camel and snake case. + +;; Preserve pastes from OS when saving a new item to the kill +;; ring. Why wouldn't this be enabled by default? + +(setq-default cursor-type 'box) +(setq-default cursor-in-non-selected-windows 'bar) + +(when nil ;; Causing too many annoying issues + (add-hook 'after-init-hook '(lambda () (setq debug-on-error t)))) + +;; Make mouse scrolling less jumpy. +(setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) + +(setq ediff-split-window-function 'split-window-horizontally) +(setq ediff-window-setup-function 'ediff-setup-windows-plain) + +;; Disable this per major mode or maybe using file size if it causes +;; performance issues? +(setq imenu-auto-rescan t) +(setq imenu-max-item-length 300) + +(put 'narrow-to-region 'disabled nil) +(put 'narrow-to-page 'disabled nil) + +(setq echo-keystrokes 0.25) + + +;; text mode stuff: +(remove-hook 'text-mode-hook #'turn-on-auto-fill) +(add-hook 'text-mode-hook 'turn-on-visual-line-mode) +(setq sentence-end-double-space nil) + +;; y and n instead of yes and no ++
(setq-default c-basic-offset 4 + tab-width 4 + indent-tabs-mode t) + +(add-hook 'prog-mode-hook (lambda () (auto-fill-mode -1))) +;; (add-hook 'prog-mode-hook 'flyspell-prog-mode) + +;; (add-hook 'prog-mode-hook (lambda () (highlight-lines-matching-regexp +;; ".\\{81\\}" 'hi-blue))) ++
4.21 paradox
+(use-package paradox + :defer 10 + :commands (paradox-upgrade-packages paradox-list-packages) + :config + (progn + (require 'gh) + (setq paradox-execute-asynchronously t + paradox-github-token (gh-auth-get-oauth-token)))) ++
4.22 diminish
+(use-package diminish + :preface + (defvar imalison:packages-to-diminish + '(auto-revert-mode smartparens-mode eldoc-mode tern-mode js2-refactor-mode)) + :config + (progn + (cl-loop for package in imalison:packages-to-diminish + do (diminish package)) + (eval-after-load 'subword '(diminish 'subword-mode)) + (eval-after-load 'simple '(diminish 'visual-line-mode)))) ++
4.23 edit-server
+(use-package edit-server + :commands edit-server-start + :defer 1 + :config + (progn + (edit-server-start) + (setq edit-server-new-frame nil))) ++
4.24 load-dir
+(use-package load-dir + :config + (progn + (setq load-dir-debug nil) + (add-to-list 'load-dirs "~/.emacs.d/load.d") + (defvar site-lisp "/usr/share/emacs24/site-lisp/") + (when (file-exists-p site-lisp) (add-to-list 'load-dirs site-lisp)))) ++
4.25 server
+(use-package server + :config + (progn + (unless (server-running-p) (server-start)))) ++
4.26 list-environment
+(use-package list-environment) ++
4.27 bug-hunter
+(use-package bug-hunter) ++
4.28 shackle
+(use-package shackle + :disabled t + :config + (progn + (diminish 'shackle-mode) + (when nil ; disabled for now + (shackle-mode)) + (setq shackle-inhibit-window-quit-on-same-windows t) + (setq shackle-default-rule '(:same t)))) ++
4.29 beacon
+(use-package beacon + :bind ("C-c b" . beacon-blink) + :config + (beacon-mode 1)) ++
4.30 discover-my-major
+(use-package discover-my-major) ++
4.31 refine
+(use-package refine + :disabled t) ++
4.32 winner
+(use-package winner + :after hydra + :demand t + :commands (winner-undo winner-redo) + :config + (progn + (bind-key + "C-c q" + (defhydra imalison:winner-hydra () + "Winner" + ("p" winner-undo "back") + ("n" winner-redo "forward" :exit t))) + (winner-mode 1))) ++
4.33 eyebrowse
+(use-package eyebrowse) ++
4.34 fill-column-indicator
++This interferes with too many other packages. See +https://github.com/alpaker/Fill-Column-Indicator/issues/21 for more details +
+(use-package fill-column-indicator + :disabled t + :config + (progn + (defun fci-on-off-fci-before-company (command) + (when (string= "show" command) + (turn-off-fci-mode)) + (when (string= "hide" command) + (turn-on-fci-mode))) + (advice-add 'company-call-frontends :before #'fci-on-off-fci-before-company) + (add-hook 'prog-mode-hook 'fci-mode))) ++
4.35 overseer
+(use-package overseer) ++
5 Keybindings
+5.1 bind-key
+(use-package bind-key) ++
5.2 which-key
+(use-package which-key + :config + (progn + (setq which-key-idle-delay .50) + (diminish 'which-key-mode) + (which-key-mode))) ++
5.3 hydra
+(use-package hydra + :demand t + :bind (("C-c f" . imalison:hydra-font-resize/body) + ("C-c y" . imalison:hydra-yank/body) + ("C-c 6" . imalison:compile/body)) + :config + (progn + (defhydra imalison:hydra-font-resize + nil + "Resize Font" + ("-" imalison:font-size-decr "Decrease") + ("d" imalison:font-size-decr "Decrease") + ("=" imalison:font-size-incr "Increase") + ("+" imalison:font-size-incr "Increase") + ("i" imalison:font-size-incr "Increase") + ("h" imalison:set-huge-font-size "Huge") + ("f" set-frame-font "Set Frame Font") + ("0" imalison:font-size-reset "Reset to default size")) + + (defhydra imalison:hydra-yank + nil + "Yank text" + ("p" imalison:copy-buffer-file-path "Projectile path") + ("f" imalison:copy-buffer-file-path-full "Full path") + ("n" imalison:copy-buffer-file-name "File name") + ("b" imalison:copy-current-git-branch "Git Branch")) + + (defun imalison:make-test () + (interactive) + (let ((default-directory (projectile-project-root))) + (imalison:named-compile "make test"))) + + (defun imalison:glide-up () + (interactive) + (imalison:named-compile "glide up")) + + (defhydra imalison:compile nil "Compile" + ("s" helm-command-from-zsh "Select a command from shell history") + ("c" imalison:named-compile "Enter Custom Command") + ("t" imalison:make-test "Test") + ("u" imalison:glide-up "Update Dependencies")))) ++
5.4 kill-emacs
++This ensures that C-x C-c will always kill emacs, even if we are running in server mode. +
+(bind-key "C-x C-c" 'kill-emacs) ++
5.5 imenu
++imenu is the best. This should be a default binding. +
+(bind-key "C-x C-i" 'imenu) ++
5.6 undo
++I can't shake the habit of using this keybinding for undo. I should really use the default of C-/. +
+(bind-key "C--" 'undo) ++
5.7 other-window
++Go the other way when you use capital O. +
+(bind-key "C-x O" (lambda () (interactive) (other-window -1))) ++
5.8 Mark ring
+(bind-key "C-c SPC" 'imalison:mark-ring) ++
5.9 Other bindings
+(bind-key "C-x p" 'pop-to-mark-command) +(setq set-mark-command-repeat-pop t) +(bind-key "C-x C-b" 'buffer-menu) +(bind-key "C-x C-r" (lambda () (interactive) (revert-buffer t t))) +(bind-key "C-x w" 'whitespace-mode) +(bind-key "M-n" 'forward-paragraph) +(bind-key "M-p" 'backward-paragraph) +(bind-key "C-M-<backspace>" 'backward-kill-sexp) +(bind-key "s-<return>" 'toggle-frame-fullscreen) +(bind-key "M-|" 'imalison:shell-command-on-region) +(bind-key "C-x 9" 'previous-buffer) +(bind-key "s-v" 'clipboard-yank) ++
5.10 global-set-key-to-use-package
++This might be useless, but I believe that it is a macro that converts between +bind-key and global-set-key forms. +
+(fset 'global-set-key-to-use-package + (lambda (&optional arg) "Keyboard macro." (interactive "p") + (kmacro-exec-ring-item + (quote ([1 67108896 19 100 6 23 40 19 41 return + backspace 32 46 6 4] 0 "%d")) arg))) ++
5.11 OSX
+(when (equal system-type 'darwin) + (setq mac-option-modifier 'meta) + (setq mac-command-modifier 'super)) ++
6 Navigation
+6.1 zop-to-char
+(use-package zop-to-char + :bind ("M-z" . zop-to-char) + :init + (progn + (setq zop-to-char-kill-keys '(?\C-k)) + (setq zop-to-char-quit-at-point-keys '(?\r)))) ++
6.2 helm
++I use helm for almost all emacs completion +
+1: (use-package helm-config + 2: :ensure helm + 3: :demand t + 4: :bind (("M-y" . helm-show-kill-ring) + 5: ("M-x" . helm-M-x) + 6: ("C-x C-i" . helm-imenu) + 7: ("C-h a" . helm-apropos) + 8: ("C-c C-h" . helm-org-agenda-files-headings) + 9: ("C-c ;" . helm-recentf)) +10: :diminish helm-mode +11: :config +12: (progn +13: (require 'helm-org) +14: (setq helm-split-window-default-side 'same) +15: +16: (cl-defun helm-org-headings-in-buffer () +17: (interactive) +18: (helm :sources (helm-source-org-headings-for-files +19: (list (projectile-completing-read +20: "File to look at headings from: " +21: (projectile-all-project-files)))) +22: :candidate-number-limit 99999 +23: :buffer "*helm org inbuffer*")) +24: +25: (use-package helm-descbinds +26: :demand t +27: :config (helm-descbinds-mode 1)) +28: +29: (use-package helm-ag +30: :bind ("C-c p 1" . imalison:set-helm-ag-extra-options) +31: :preface +32: (progn +33: (defun imalison:set-helm-ag-extra-options () +34: (interactive) +35: (let ((option (read-string "Extra options: " (or helm-ag--extra-options "") +36: 'helm-ag--extra-options-history))) +37: (setq helm-ag--extra-options option)))) +38: :config +39: (progn +40: (setq helm-ag-always-set-extra-option nil))) +41: (helm-mode 1))) ++
+Ensure that helm buffers are started in the window that currently holds the focus +
+6.3 helm-projectile
+(use-package helm-projectile + :commands (helm-projectile-on) + :bind (:map helm-projectile-projects-map + ("M-s" . imalison:switch-to-project-and-search) + ("M-t" . imalison:helm-term-projectile)) + :preface + (progn + (defun imalison:invalidate-cache-and-open-file (_dir) + (projectile-invalidate-cache nil) + (projectile-find-file)) + + (defun imalison:switch-to-project-and-search (dir) + (let ((default-directory dir) + (projectile-require-project-root nil) + (helm-action-buffer "this-buffer-should-not-exist")) + (helm-projectile-ag))) + + (defun imalison:helm-term-projectile (dir) + (let ((default-directory dir) + (projectile-require-project-root nil) + (helm-action-buffer "this-buffer-should-not-exist")) + (term-projectile-forward)))) + :config + (progn + (helm-delete-action-from-source "Search in Project" + helm-source-projectile-projects) + (helm-delete-action-from-source "Open term for project" + helm-source-projectile-projects) + (helm-add-action-to-source "Search in Project" + 'imalison:switch-to-project-and-search + helm-source-projectile-projects) + (helm-add-action-to-source "Open term for project" + 'imalison:helm-term-projectile + helm-source-projectile-projects) + (helm-add-action-to-source "Invalidate Cache and Open File" + 'imalison:invalidate-cache-and-open-file + helm-source-projectile-projects))) ++
6.4 projectile
+(use-package projectile + :demand t + :bind (("C-x f" . projectile-find-file-in-known-projects) + ("C-c p f" . imalison:projectile-find-file)) + :preface + (progn + (defun imalison:do-ag-default-directory () + (interactive) + (helm-do-ag default-directory (car (projectile-parse-dirconfig-file)))) + + (emit-prefix-selector imalison:do-ag + helm-projectile-ag + imalison:do-ag-default-directory + helm-do-ag) + + (emit-prefix-selector imalison:projectile-find-file + projectile-find-file + projectile-find-file-other-window) + + (imalison:let-around imalison:set-options-do-ag + imalison:do-ag + (helm-ag-always-set-extra-option t)) + + (defun imalison:projectile-make-all-subdirs-projects (directory) + (cl-loop for file-info in (directory-files-and-attributes directory) + do (when (nth 1 file-info) + (write-region "" nil + (expand-file-name + (concat directory "/" + (nth 0 file-info) "/.projectile"))))))) + :config + (progn + (use-package persp-projectile + :commands projectile-persp-switch-project) + + (projectile-global-mode) + (setq projectile-require-project-root nil) + (setq projectile-enable-caching nil) + (setq projectile-completion-system 'helm) + (add-to-list 'projectile-globally-ignored-files "Godeps") + (shut-up (helm-projectile-on)) + (diminish 'projectile-mode) + (bind-key* "C-c p s" 'imalison:do-ag) + (bind-key* "C-c p S" 'imalison:set-options-do-ag) + (bind-key* "C-c p f" 'imalison:projectile-find-file))) ++
6.5 ido
+(use-package ido + :commands ido-mode + :config + (progn + (ido-mode 1) + (setq ido-auto-merge-work-directories-length -1) + (setq ido-use-virtual-buffers t) + (setq ido-use-filename-at-point nil) + (setq ido-create-new-buffer 'always) + (ido-everywhere 1) + (setq ido-enable-flex-matching t) + (use-package flx) + (use-package flx-ido + :commands flx-ido-mode + :init (flx-ido-mode 1) + :config + (progn + ;; disable ido faces to see flx highlights. + ;; This makes flx-ido much faster. + (setq gc-cons-threshold 20000000) + (setq ido-use-faces nil))) + (use-package ido-ubiquitous + :disabled t + :commands (ido-ubiquitous-mode)) + (use-package ido-vertical-mode + :config + (progn + (ido-vertical-mode 1) + (setq ido-vertical-define-keys 'C-n-C-p-up-and-down))) + (use-package flx-ido))) ++
6.6 avy
+(use-package avy + :preface + (progn + (emit-prefix-selector imalison:avy + avy-goto-word-1 + avy-goto-char)) + :bind (("C-j" . imalison:avy) + ("M-g l" . avy-goto-line) + ("C-'" . avy-goto-char-2))) ++
6.7 ace-window
+(use-package ace-window + :preface + (emit-prefix-selector imalison:ace-window + ace-select-window + ace-swap-window) + :config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) + :bind ("C-c w" . imalison:ace-window)) ++
6.8 neotree
+(use-package neotree) ++
6.9 jump-char
+(use-package jump-char + :bind (("C-;" . jump-char-forward))) ++
6.9.1 helm-zsh-history
++This was stolen from https://github.com/jwiegley/dot-emacs +
+(defvar helm-c-source-zsh-history + '((name . "Zsh History") + (candidates . helm-c-zsh-history-set-candidates) + (action . (("Execute Command" . helm-c-zsh-history-action))) + (volatile) + (requires-pattern . 3) + (delayed))) + +(defun helm-c-zsh-history-set-candidates (&optional request-prefix) + (let ((pattern (replace-regexp-in-string + " " ".*" + (or (and request-prefix + (concat request-prefix + " " helm-pattern)) + helm-pattern)))) + (with-current-buffer (find-file-noselect "~/.zsh_history" t t) + (auto-revert-mode -1) + (goto-char (point-max)) + (loop for pos = (re-search-backward pattern nil t) + while pos + collect (replace-regexp-in-string + "\\`:.+?;" "" + (buffer-substring (line-beginning-position) + (line-end-position))))))) + +(defun helm-c-zsh-history-action (candidate) + (imalison:named-compile candidate)) + +(defun helm-command-from-zsh () + (interactive) + (require 'helm) + (helm-other-buffer 'helm-c-source-zsh-history "*helm zsh history*")) ++
6.10 flimenu
+(imalison:use-package flimenu + :config + (progn + (flimenu-global-mode))) ++
6.11 swiper
+(use-package swiper + :disabled t + :bind ("C-s" . swiper)) ++
7 Completion
+7.1 company
+(use-package company + :commands company-mode imalison:company + :bind (("C-\\" . imalison:company)) + :config + (progn + (emit-prefix-selector imalison:company + company-complete + company-yasnippet) + + (setq company-idle-delay .25) + (global-company-mode) + (diminish 'company-mode)) + :init + (add-hook 'prog-mode-hook (lambda () (company-mode t)))) ++
7.1.1 company-flx
+(use-package company-flx + :disabled t + :after company + :config + (company-flx-mode +1)) ++
7.2 auto-complete
++I don't use auto-complete at all, so I have set up a hook to automatically disable it whenever it is enabled to avoid creating conflicting popups when company is activated. +
+(use-package auto-complete + :preface + (progn + (defun imalison:auto-complete-hook () + (debug) + (warn "auto-complete-mode was activated, but is being automatically disabled.") + (let ((auto-complete-mode-hook nil)) + (auto-complete-mode -1)))) + :config + (progn + (add-hook 'auto-complete-mode-hook 'imalison:auto-complete-hook))) ++
8 Text Manipulation
+8.1 smartparens
+(use-package smartparens + :demand t + :diminish smartparens-mode + :bind (:map smartparens-mode-map + ("C-)" . sp-forward-slurp-sexp) + ("C-}" . sp-forward-barf-sexp) + ("C-(" . sp-backward-slurp-sexp) + ("C-{" . sp-backward-barf-sexp)) + :config + (progn + (require 'smartparens-config) + (smartparens-global-mode 1) + (sp-use-smartparens-bindings) + (unbind-key "C-M-<backspace>" smartparens-mode-map) + (unbind-key "C-<backspace>" smartparens-mode-map) + (unbind-key "M-<backspace>" smartparens-mode-map))) ++
8.2 multiple-cursors
+(use-package multiple-cursors + :config + (progn + (use-package phi-search-mc + :demand t + :config + (phi-search-mc/setup-keys)) + (use-package mc-extras + :demand t + :config + (define-key mc/keymap (kbd "C-. =") 'mc/compare-chars))) + :bind + (("C-c m a" . mc/mark-all-like-this) + ("C-c m m" . mc/mark-all-like-this-dwim) + ("C-c m l" . mc/edit-lines) + ("C-c m n" . mc/mark-next-like-this) + ("C-c m p" . mc/mark-previous-like-this) + ("C-c m s" . mc/mark-sgml-tag-pair) + ("C-c m d" . mc/mark-all-like-this-in-defun))) ++
8.3 expand-region
+(use-package expand-region + :commands er/expand-region + :config (setq expand-region-contract-fast-key "j") + :bind (("C-c k" . er/expand-region))) ++
8.4 multi-line
+(imalison:use-package multi-line + :bind ("C-c d" . multi-line)) ++
8.5 comment-dwim-2
+(use-package comment-dwim-2 + :bind ("M-;" . comment-dwim-2)) ++
8.6 unfill
+(use-package unfill + :bind ("M-q" . unfill-toggle)) ++
8.7 cliphist
+(use-package cliphist + :config (setq cliphist-use-ivy t)) ++
8.8 electric-operator-mode
+(use-package electric-operator + :config + (add-hook 'python-mode-hook #'electric-operator-mode)) ++
8.9 string-inflection
+(use-package string-inflection + :commands string-inflection-toggle + :bind ("C-c l" . string-inflection-toggle)) ++
8.10 yasnippet
+(use-package yasnippet + :defer 5 + :commands (yas-global-mode) + :config + (progn + (yas-global-mode) + (diminish 'yas-minor-mode) + (add-hook 'term-mode-hook (lambda() (yas-minor-mode -1))) + (setq yas-prompt-functions + (cons 'yas-ido-prompt + (cl-delete 'yas-ido-prompt yas-prompt-functions))))) ++
9 Source Control
+9.1 magit
+(use-package magit + :commands magit-status + :bind (("C-x g" . magit-status)) + :preface + (progn + (defun imalison:after-magit-visit-file (&rest args) + (when (derived-mode-p 'org-mode) + (org-show-context 'magit-goto)))) + :config + (progn + (unbind-key "C-j" magit-status-mode-map) + (unbind-key "C-j" magit-hunk-section-map) + (unbind-key "C-j" magit-file-section-map) + (defvar-setq magit-last-seen-setup-instructions "1.4.0") + (magit-auto-revert-mode) + ;; TODO: Is this necessary now that signing is a git default + (when (bound-and-true-p imalison:gpg-key) + (add-to-list 'magit-commit-arguments + (format "--gpg-sign=%s" imalison:gpg-key))) + + (add-to-list 'org-show-context-detail '(magit-goto . lineage)) + (advice-add 'magit-diff-visit-file :after 'imalison:after-magit-visit-file) + (use-package magit-filenotify + ;; Seems like OSX does not support filenotify. + :disabled t + :if (funcall (emacs-version-predicate 24 4)) + :config + :init (add-hook 'magit-status-mode-hook 'magit-filenotify-mode)))) ++
9.1.1 magithub
+(use-package magithub + :if (executable-find "hub") + :after magit + :disabled t) ++
9.2 git-link
+(use-package git-link + :config + (progn + (setq git-link-use-commit t))) ++
9.3 magit-gitflow
+(use-package magit-gitflow + :diminish magit-gitflow-mode + :after magit + :init + (progn + (setq magit-gitflow-popup-key "C-k")) + :config + (progn + (add-hook 'magit-mode-hook 'turn-on-magit-gitflow))) ++
9.4 git-timemachine
+(use-package git-timemachine + :commands git-timemachine) ++
9.5 git-gutter
+(use-package git-gutter + :config + (progn + (global-git-gutter-mode -1))) ++
9.6 gitolite-clone
+(use-package gitolite-clone + :demand t + :preface + (progn + (defun gitolite-clone-force-refresh () + (interactive) + (gitolite-clone-get-projects nil nil t)))) ++
9.7 gitconfig-mode
+(use-package gitconfig-mode + :mode "\\.?gitconfig.?.*\\'") ++
9.8 gitignore-mode
+(use-package gitignore-mode + :mode "\\.?gitignore.?.*\\'") ++
9.9 github
+9.9.1 github-search
+(imalison:use-package github-search + :commands (github-search-clone-repo github-search-user-clone-repo) + :preface + (progn + (defun imalison:get-appropriate-path-from-gh-repo-for-go (repo) + (require 'go-mode) + (imalison:get-go-src "github.com" (oref (oref repo :owner) :login) + (oref repo :name))) + + (defun imalison:get-projects-directory-target-from-repo (repo) + (let ((prospective-path + (if (equal (oref repo language) "Go") + (imalison:get-appropriate-path-from-gh-repo-for-go repo) + (imalison:join-paths imalison:projects-directory (oref repo :name))))) + (if (file-exists-p prospective-path) + (funcall 'github-search-prompt-for-target-directory repo) + prospective-path)))) + :config + (progn + (setq github-search-get-target-directory-for-repo-function + 'imalison:get-projects-directory-target-from-repo))) ++
9.9.2 github-clone
+(imalison:use-package* github-clone "~/Projects/github-clone.el" + :commands (github-clone-add-parent-remote + github-clone-add-source-remote + github-clone-fork-remote + github-clone-add-existing-remote + github-clone)) ++
9.9.3 github-notifier
++This is disabled because it was causing too many issues with my +modeline and with excessive http requests to github. +
+(use-package github-notifier + :disabled t + :config + (progn + (advice-add 'github-notifier-update :around 'imalison:shut-up-around) + (github-notifier-mode))) ++
9.9.4 github-browse-file
+(use-package github-browse-file + :commands github-browse-file) ++
9.9.5 magit-gh-pulls
+(use-package magit-gh-pulls + :disabled t + :diminish magit-gh-pulls-mode + :after magit + :config + (progn + (add-hook 'magit-mode-hook 'turn-on-magit-gh-pulls))) ++
9.9.6 gist
+(use-package gist + :commands (gist-region gist-region-private gist-buffer gist-buffer-private + gist-region-or-buffer gist-region-or-buffer-private + gist-list-user gist-list gist-fetch gist-star + gist-unstar gist-list-starred gist-fork)) ++
10 Major Modes
+10.1 Programming
+10.1.1 python
+(use-package python + :commands python-mode + :mode ("\\.py\\'" . python-mode) + :preface + (defun imalison:python-mode () + (setq show-trailing-whitespace t) + ;; TODO: This was likely fixed and can probably be removed + ;; Somehow this is sometimes set to jedi:ac-setup which we + ;; don't want. This binding avoids starting auto-complete mode. + (let ((jedi:setup-function nil)) + (jedi:setup)) + + ;; XXX: This has become pretty annoying + ;; (add-hook 'before-save-hook 'pyimport-remove-unused t t) + + ;; Ensure company is active + (company-mode +1) + ;; Only use company-jedi for completion + (set (make-local-variable 'company-backends) '(company-jedi)) + + ;; Remove default python completion, as we are going to rely on + ;; company-jedi. + (remove-hook 'completion-at-point-functions + 'python-completion-complete-at-point 'local)) + :config + (progn + (use-package sphinx-doc) + (unbind-key "C-j" python-mode-map) + (add-hook 'python-mode-hook #'imalison:python-mode))) ++
- pyimport+
+Pyimport is disabled because it may be causing a performance problem. +
++ ++(use-package pyimport + :disabled t + :bind (:map python-mode-map + ("C-c C-i" . pyimport-insert-missing)) + :commands pyimport-remove-unused) +
+
+ - jedi+
+The accepted way to use jedi if you prefer company to auto-complete is +simply to require the company jedi package, which is why we make no +reference to the jedi-core package. +
++ ++(use-package company-jedi + :after python + :commands (jedi:goto-definition jedi-mode company-jedi) + :bind (:map python-mode-map + ("M-." . jedi:goto-definition) + ("M-," . jedi:goto-definition-pop-marker)) + :config + (progn + (setq jedi:complete-on-dot t) + (setq jedi:imenu-create-index-function 'jedi:create-flat-imenu-index))) +
+
10.1.2 go
+(use-package go-mode + :mode (("\\.go\\'" . go-mode)) + :preface + (progn + (defun imalison:glide-novendor () + (projectile-with-default-dir (projectile-project-root) + (shell-command-to-string "glide novendor"))) + + (defun imalison:go-mode-create-imenu-index () + "Create and return an imenu index alist. Unlike the default + alist created by go-mode, this method creates an alist where + items follow a style that is consistent with other prog-modes." + (let* ((patterns '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1))) + (type-index (imenu--generic-function patterns)) + (func-index)) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward go-func-meth-regexp (point-max) t) + (let* ((var (match-string-no-properties 1)) + (func (match-string-no-properties 2)) + (name (if var + (concat (substring var 0 -1) "." func) + func)) + (beg (match-beginning 0)) + (marker (copy-marker beg)) + (item (cons name marker))) + (setq func-index (cons item func-index))))) + (nconc type-index (list (cons "func" func-index))))) + + (defun imalison:go-workspace-path () + (file-relative-name (projectile-project-root) + (concat (file-name-as-directory + (imalison:get-go-path)) "src"))) + + (defun imalison:install-current-go-project () + (interactive) + (start-process + "go install" "go install log" "go" "install" + (concat (file-name-as-directory (imalison:go-workspace-path)) "..."))) + + (defun imalison:get-go-path () + (let ((environment-go-path (getenv "GOPATH"))) + (if environment-go-path + (file-name-as-directory (car (s-split ":" environment-go-path))) + "~/go"))) + + (defmacro imalison:get-go-src (&rest paths) + `(imalison:join-paths (imalison:get-go-path) "src" ,@paths)) + + (imalison:let-advise-around imalison:advise-normal-go-command + (go-command "go")) + + (defun imalison:go-mode-hook () + (go-eldoc-setup) + (set (make-local-variable 'company-backends) '(company-go)) + (make-local-variable 'projectile-globally-ignored-files) + (add-hook 'after-save-hook 'imalison:install-current-go-project nil + 'yes-do-local) + (add-to-list 'projectile-globally-ignored-files + "vendor"))) + :config + (progn + (imalison:use-package* + gotest "~/Projects/gotest.el" + :demand t + :bind (:map go-mode-map + ("C-c t" . imalison:gotest)) + :preface + (progn + (emit-prefix-selector imalison:gotest + go-test-current-test + go-test-current-file) + + (defun imalison:add-expected-test-name-for-suite (suite-name test-name) + (if (> (length suite-name) 0) + (concat " -run Test" suite-name) + ""))) + :config + (progn + (setq go-test-verbose t + go-test-additional-arguments-function + 'imalison:add-expected-test-name-for-suite))) + (use-package company-go + :config (setq company-go-show-annotation t)) + (use-package go-projectile :demand t) + (use-package go-eldoc :demand t) + (use-package go-guru + :demand t + :bind (:map go-mode-map + ("M-." . go-guru-definition) + ("M-," . pop-tag-mark)) + :preface + (progn + (defun imalison:set-go-guru-scope () + (setq go-guru-scope (go-mode-parse-glide-novendor))) + (defun go-mode-parse-glide-novendor () + (s-join "," + (cl-loop for path in (s-split "\n" (imalison:glide-novendor)) + collect (if (string-equal path ".") + (imalison:go-workspace-path) + (s-replace "\./" (imalison:go-workspace-path) path)))))) + :config + (progn + (advice-add 'go-guru--set-scope-if-empty :before 'imalison:set-go-guru-scope) + (advice-add 'go-guru-start :before 'imalison:set-go-guru-scope) + (advice-add 'go-guru-definition :around 'imalison:advise-normal-go-command) + (advice-add 'go-guru-definition :before + (lambda () + (with-no-warnings + (ring-insert find-tag-marker-ring (point-marker))))))) + + (advice-add 'go-import-add :around 'imalison:advise-normal-go-command) + + (setq gofmt-command "goimports") + + (add-hook 'go-mode-hook 'imalison:go-mode-hook) + (add-hook 'before-save-hook 'gofmt-before-save t))) ++
- Show diffs of testify output++ ++
(defvar imalison:testify-ediff-buffers nil) +(defun imalison:purge-ediff-buffers (&rest args) + (cl-loop for buffer in imalison:testify-ediff-buffers + do (kill-buffer buffer)) + (setq imalison:testify-ediff-buffers nil)) + +(add-hook 'ediff-cleanup-hook 'imalison:purge-ediff-buffers) + +(defun imalison:go-testify-show-ediff () + (interactive) + (let ((buffer (get-buffer-create "*Testify JSON*")) + json-result) + (shell-command-on-region (point-min) (point-max) "parse_go_testify_for_emacs.py" buffer) + (with-current-buffer buffer + (goto-char (point-min)) + (setq json-result (json-read))) + (let ((actual-buffer (generate-new-buffer "*Testify Actual*")) + (expected-buffer (generate-new-buffer "*Testify Expected*"))) + (add-to-list 'imalison:testify-ediff-buffers actual-buffer) + (add-to-list 'imalison:testify-ediff-buffers expected-buffer) + (with-current-buffer actual-buffer + (insert (cdr (assoc 'actual json-result))) + (with-current-buffer expected-buffer + (insert (cdr (assoc 'expected json-result))) + (ediff-buffers actual-buffer expected-buffer)))))) + +(defun imalison:go-testify-show-icdiff () + (interactive) + (let ((buffer (get-buffer-create "*Testify Comparison*"))) + (shell-command-on-region (point-min) (point-max) "parse_go_testify_not_equal.py" buffer) + (with-current-buffer buffer + (fundamental-ansi-mode)) + (switch-to-buffer buffer))) +
+
10.1.3 emacs-lisp
+- elisp-slime-nav++ ++
(use-package elisp-slime-nav + :commands elisp-slime-nav-mode + :config + (diminish 'elisp-slime-nav-mode) + :preface + (emit-prefix-selector imalison:elisp-slime-nav + elisp-slime-nav-find-elisp-thing-at-point + elisp-slime-nav-describe-elisp-thing-at-point) + :bind (:map elisp-slime-nav-mode-map + ("M-." . imalison:elisp-slime-nav))) +
+
+ - macrostep+
+Macrostep is an indespensible tool for writing emacs lisp macros. It lets you see pretty printed versions of the result of macro evaluation as the macro is evaluated +
++ ++(use-package macrostep + :bind (:map lisp-mode-shared-map + ("C-c e" . macrostep-expand))) +
+
+ - emr++ ++
(use-package emr + :bind ("M-RET" . emr-show-refactor-menu) + :config + (progn + (add-hook 'prog-mode-hook 'emr-initialize))) +
+
+ - Editing configuration+
+Reduce indentation for some functions +
++ ++(put 'use-package 'lisp-indent-function 1) +
+
+ - Checkdoc++ ++
(setq checkdoc-force-docstrings-flag nil + checkdoc-arguments-in-order-flag nil) +
+
+ - edebug++ ++
(use-package edebug + :config + (progn (setq edebug-trace t))) +
+
+ - Misc++ ++
(defun imenu-elisp-sections () + (setq imenu-prev-index-position-function nil) + (setq imenu-space-replacement nil) + (add-to-list 'imenu-generic-expression + `("Package" + ,"(use-package \\(.+\\)$" 1)) + (add-to-list 'imenu-generic-expression + `("Section" + ,(concat ";\\{1,4\\} =\\{10,80\\}\n;\\{1,4\\} \\{10,80\\}" + "\\(.+\\)$") 1) t)) + +(defun imalison:maybe-remove-flycheck-checkdoc-checker () + (when (s-starts-with? "*" (buffer-name)) + (flycheck-disable-checker 'emacs-lisp-checkdoc))) + +(add-hook 'emacs-lisp-mode-hook 'imenu-elisp-sections) +(add-hook 'emacs-lisp-mode-hook (lambda () + (setq indent-tabs-mode nil) + (setq show-trailing-whitespace t))) +(add-hook 'flycheck-mode-hook 'imalison:maybe-remove-flycheck-checkdoc-checker) +
+
+ - Show result of eval-last-sexp inline+
+Taken from http://endlessparentheses.com/eval-result-overlays-in-emacs-lisp.html +
++ ++(autoload 'cider--make-result-overlay "cider-overlays") + +(defun imalison:eval-overlay (value point) + (cider--make-result-overlay (format "%S" value) + :where point + :duration 'command) + value) + +(advice-add 'eval-region :around + (lambda (f beg end &rest r) + (imalison:eval-overlay + (apply f beg end r) + end))) + +(advice-add 'eval-last-sexp :filter-return + (lambda (r) + (imalison:eval-overlay r (point)))) + +(advice-add 'eval-defun :filter-return + (lambda (r) + (imalison:eval-overlay + r + (save-excursion + (end-of-defun) + (point))))) +
+
+ - Init hook++ ++
(defvar imalison:check-parens nil) + +(defun imalison:maybe-check-parens () + (if imalison:check-parens + (check-parens))) + +(defun imalison:emacs-lisp-hook () + (elisp-slime-nav-mode t) + (add-hook 'write-file-functions 'imalison:maybe-check-parens nil t)) + +(add-hook 'emacs-lisp-mode-hook 'imalison:emacs-lisp-hook) +
+
+ - Keybinds++ ++
(emit-compose imalison:copy-eval-last-sexp + kill-new prin1-to-string eval-last-sexp) + +(emit-prefix-selector imalison:eval-last-sexp + eval-region-or-last-sexp + imalison:copy-eval-last-sexp) + +(define-key lisp-mode-shared-map (kbd "C-c C-c") 'eval-defun) +(define-key lisp-mode-shared-map (kbd "C-c o r") 'up-list-region) +(define-key lisp-mode-shared-map (kbd "C-c o o") 'up-list-back) +(define-key lisp-mode-shared-map (kbd "C-x C-e") 'imalison:eval-last-sexp) +(unbind-key "C-j" lisp-interaction-mode-map) +
+
10.1.4 clojure
++The following is taken from spacemacs. It adds fancification to a clojure mode. +
+(defun imalison:clojure-fancify-symbols (mode) + "Pretty symbols for Clojure's anonymous functions and sets, + like (λ [a] (+ a 5)), ƒ(+ % 5), and ∈{2 4 6}." + (font-lock-add-keywords mode + `(("(\\(fn\\)[\n\[[:space:]]" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "λ")))) + ("(\\(partial\\)[\[[:space:]]" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "Ƥ")))) + ("(\\(comp\\)[\n\[[:space:]]" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "∘")))) + ("\\(#\\)(" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "ƒ")))) + ("\\(#\\){" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "∈"))))))) ++
(use-package clojure-mode + :commands clojure-mode + :preface + (progn + (add-to-list 'magic-mode-alist '("#!.*boot\\s-*$" . clojure-mode)) + (add-to-list 'auto-mode-alist '("\\.boot\\'" . clojure-mode)) + + (defun imalison:clojure-mode-hook () + ;; (cljr-add-keybindings-with-prefix "C-c C-m") + (clj-refactor-mode 1) + ;;for adding require/use/import statements + (yas-minor-mode 1)) + + (defvar imalison:clojure-level-1-symobls + '(describe it))) + :config + (progn + (cl-loop for symbol in imalison:clojure-level-1-symobls + do (put-clojure-indent symbol 1)) + (add-hook 'clojure-mode-hook 'imalison:clojure-mode-hook) + (dolist (m '(clojure-mode clojurescript-mode clojurec-mode clojurex-mode)) + (imalison:clojure-fancify-symbols m)))) ++
- cider++ ++
(use-package cider + :commands (cider-jack-in) + :config + (progn + (setq cider-stacktrace-default-filters '(tooling dup) + cider-repl-pop-to-buffer-on-connect nil + cider-prompt-save-file-on-load nil + cider-repl-use-clojure-font-lock t + cider-prompt-for-symbol nil + cider-preferred-build-tool "boot") + (add-hook 'clojure-mode-hook 'cider-mode))) +
+
+ - clj-refactor++ ++
(use-package clj-refactor + :commands clj-refactor-mode) +
+
10.1.5 scala
+(use-package scala-mode + :mode (("\\.scala\\'" . scala-mode) + ("\\.sc\\'" . scala-mode)) + :config + (progn + (use-package ensime + :pin melpa-stable + :bind (:map ensime-mode-map + ("M-," . ensime-pop-find-definition-stack)) + :commands ensime-mode + :config + (progn + (setq ensime-startup-snapshot-notification nil))) + (add-hook 'scala-mode-hook 'ensime-scala-mode-hook) + (setq scala-indent:align-parameters t))) ++
10.1.6 js
+(defun tape-onlyify () + (interactive) + (save-excursion + (move-end-of-line nil) + (re-search-backward "^test") + (forward-sexp) + (if (looking-at ".only") (progn (zap-to-char 1 (string-to-char "(")) (insert "(")) + (insert ".only")))) + +(use-package js2-mode + :commands (js2-mode) + :mode "\\.js\\'" + :bind + ;; (("C-c b" . web-beautify-js)) TODO: to make this mode specific + ;; and change binding + :preface + (progn + (defvar-setq imalison:identifier-count 0) + (defun imalison:console-log-unique () + (interactive) + (let* ((identifier-string (int-to-string imalison:identifier-count)) + (uuid (imalison:uuid))) + (insert (format "console.log('%s//////////%s//////////');" identifier-string uuid)) + (setq imalison:identifier-count (+ imalison:identifier-count 1)))) + (defun imalison:js2-mode-hook () + ;; Sensible defaults + (setq js2-bounce-indent-p nil + js2-indent-level 4 + js2-basic-offset 4 + js2-highlight-level 3 + js2-include-node-externs t + js2-mode-show-parse-errors nil + js2-mode-show-strict-warnings nil + indent-tabs-mode nil + js2-indent-switch-body t) + ;; (edconf-find-file-hook) ;; Make sure that editorconfig takes precedence + (tern-mode t) + (when nil (skewer-mode)) ;; TODO: reenable + (setq imenu-create-index-function + (lambda () + (imalison:flatten-imenu-index + (js2-mode-create-imenu-index)))))) + :init + (progn + (add-hook 'js2-mode-hook 'imalison:js2-mode-hook) + (add-hook 'js2-mode-hook 'js2-imenu-extras-mode))) + +(use-package js2-refactor + :after js2-mode + :config + (progn + (js2r-add-keybindings-with-prefix "C-c C-m") + (add-hook 'js2-mode-hook #'js2-refactor-mode))) + +(use-package skewer-mode + :commands skewer-mode + :config + (progn + (add-hook 'css-mode-hook #'skewer-css-mode) + (add-hook 'html-mode-hook #'skewer-html-mode))) + +(use-package tern + :commands tern-mode + :config + (use-package company-tern + :config (add-to-list 'company-backends 'company-tern))) + +(defun delete-tern-process () + (interactive) + (delete-process "tern")) ++
10.1.7 rust
+(use-package rust-mode + :mode (("\\.rs\\'" . rust-mode)) + :preface + (progn + (defun imalison:rust-mode-hook () + (racer-mode 1))) + :config + (progn + (use-package flycheck-rust + :demand t + :config + (progn + (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) + (use-package racer + :demand t + :config + (progn + (setq racer-cmd "~/.cargo/bin/racer") + (setq racer-rust-src-path "~/Projects/rust/src"))) + (use-package cargo + :demand t + :config + (progn + (add-hook 'rust-mode-hook 'cargo-minor-mode))) + (add-hook 'rust-mode-hook 'imalison:rust-mode-hook))) ++
10.1.8 haskell
+(use-package haskell-mode + :commands haskell-mode + :bind (:map haskell-mode-map + ("C-c h" . haskell-hoogle)) + :config + (progn + (setq haskell-hoogle-command "hoogle") + (require 'flycheck) + (delq 'haskell-stack-ghc flycheck-checkers) + (add-hook 'haskell-mode-hook 'turn-on-haskell-indent) + (setq haskell-tags-on-save t))) ++
- intero+
+Intero seems to be causing hangs, so it has been disabled +
++ ++(use-package intero + :disabled t + :demand t + :after haskell-mode + :config (add-hook 'haskell-mode-hook 'intero-mode)) +
+
+ - hindent++ ++
(use-package hindent + :after haskell-mode + :config + (add-hook 'haskell-mode-hook 'hindent-mode)) +
+
+ - ghc-mod++ ++
(use-package ghc + :after haskell-mode + :config + (add-hook 'haskell-mode-hook 'ghc-init)) +
+
+ - company-ghc++ ++
(use-package company-ghc + :after ghc + :config + (add-to-list 'company-backend 'company-ghc)) +
+
10.1.9 C/C++
+(use-package cc-mode + :disabled t + :preface + (defun imalison:cc-mode-hook () + (when (derived-mode-p 'c-mode 'c++-mode 'java-mode 'asm-mode) + (ggtags-mode 1))) + :config + (progn + (use-package ggtags + :demand t + :bind (:map ggtags-mode-map + ("C-c g s" . ggtags-find-other-symbol) + ("C-c g h" . ggtags-view-tag-history) + ("C-c g r" . ggtags-find-reference) + ("C-c g f" . ggtags-find-file) + ("C-c g c" . ggtags-create-tags) + ("C-c g u" . ggtags-update-tags) + ("M-," . pop-tag-mark))) + (add-hook 'c-mode-common-hook 'imalison:cc-mode-hook))) ++
10.1.10 C#
+(use-package csharp-mode + :mode "\\.cs\\'") ++
10.1.11 racket
+(use-package racket-mode + :mode "\\.rkt\\'") ++
10.2 Data/Config/Protocol
+10.2.1 thrift
+(use-package thrift + :commands thrift-mode + :mode (("\\.thrift\\'" . thrift-mode))) ++
10.2.2 protobuf
+(use-package protobuf-mode) ++
10.2.3 json-mode
+(use-package json-mode + :mode "\\.json\\'" + :init + (add-hook 'json-mode-hook + (lambda () + (setq indent-tabs-mode nil) + (setq js-indent-level 4)))) ++
10.2.4 yaml-mode
+(use-package yaml-mode + :mode (("\\.yaml\\'" . yaml-mode) + ("\\.yml\\'" . yaml-mode))) ++
10.2.5 es-mode
+(use-package es-mode) ++
10.3 Document
+10.3.1 org
+(use-package org + :ensure org-plus-contrib + :preface + (progn + ;; XXX: These should probably be moved to config, right? + (defvar-setq org-startup-indented nil) + (defvar-setq org-startup-folded t) + (defvar-setq org-edit-src-content-indentation 0) + (defvar-setq org-src-preserve-indentation t) + (defvar-setq org-directory "~/Dropbox/org") + (defvar-setq org-mobile-inbox-for-pull "~/Dropbox/org/flagged.org") + (defvar-setq org-mobile-directory "~/Dropbox/Apps/MobileOrg") + + (setq org-goto-interface 'outline-path-completion + org-goto-max-level 10) + (add-hook 'org-mode-hook 'imalison:disable-linum-mode) + (add-hook 'org-mode-hook (lambda () (setq org-todo-key-trigger t))) + (add-hook 'org-agenda-mode-hook 'imalison:disable-linum-mode) + + (defun org-archive-if (condition-function) + (if (funcall condition-function) + (let ((next-point-marker + (save-excursion (org-forward-heading-same-level 1) (point-marker)))) + (org-archive-subtree) + (setq org-map-continue-from (marker-position next-point-marker))))) + + (defun org-archive-if-completed () + (interactive) + (org-archive-if 'org-entry-is-done-p)) + + (defun org-archive-completed-in-buffer () + (interactive) + (org-map-entries 'org-archive-if-completed)) + + (cl-defun imalison:make-org-template (&key (content "%?")) + (with-temp-buffer + (org-mode) + (insert content) + (org-set-property "CREATED" + (with-temp-buffer + (org-insert-time-stamp + (org-current-effective-time) t t))) + (buffer-substring-no-properties (point-min) (point-max)))) + + (defun imalison:make-org-template-from-file (filename) + (imalison:make-org-template (imalison:get-string-from-file filename))) + + (cl-defun imalison:make-org-todo-template + (&key (content "%?") (creation-state "TODO")) + (with-temp-buffer + (org-mode) + (org-insert-heading) + (insert content) + (org-todo creation-state) + (org-set-property "CREATED" + (with-temp-buffer + (org-insert-time-stamp + (org-current-effective-time) t t))) + (remove-hook 'post-command-hook 'org-add-log-note) + (let ((org-log-note-purpose 'state) + (org-log-note-return-to (point-marker)) + (org-log-note-marker (progn (goto-char (org-log-beginning t)) + (point-marker))) + (org-log-note-state creation-state)) + (org-add-log-note)) + (buffer-substring-no-properties (point-min) (point-max)))) + + (defun org-todo-force-notes () + (interactive) + (let ((org-todo-log-states + (mapcar (lambda (state) + (list state 'note 'time)) + (apply 'append org-todo-sets)))) + (cond ((eq major-mode 'org-mode) (org-todo)) + ((eq major-mode 'org-agenda-mode) (org-agenda-todo))))) + + (defun org-make-habit () + (interactive) + (org-set-property "STYLE" "habit")) + + (defun org-insert-habit () + (interactive) + (org-insert-todo-heading nil) + (org-make-habit)) + + (defun org-todo-at-date (date) + (interactive (list (org-time-string-to-time (org-read-date)))) + (cl-flet ((org-current-effective-time (&rest r) date) + (org-today (&rest r) (time-to-days date))) + (cond ((eq major-mode 'org-mode) (org-todo)) + ((eq major-mode 'org-agenda-mode) (org-agenda-todo))))) + + (defun imalison:make-org-linked-todo-template () + (imalison:make-org-todo-template "%? %A")) + + (defun org-cmp-creation-times (a b) + (let ((a-created (get-date-created-from-agenda-entry a)) + (b-created (get-date-created-from-agenda-entry b))) + (imalison:compare-int-list a-created b-created))) + + (defun org-agenda-done (&optional arg) + "Mark current TODO as done. + This changes the line at point, all other lines in the agenda referring to + the same tree node, and the headline of the tree node in the Org-mode file." + (interactive "P") + (org-agenda-todo "DONE"))) + :commands (org-mode org org-mobile-push org-mobile-pull org-agenda) + :mode ("\\.org\\'" . org-mode) + :bind (("C-c a" . org-agenda) + ("C-c c" . org-capture) + :map org-mode-map + ("C-c n t" . org-insert-todo-heading) + ("C-c n s" . org-insert-todo-subheading) + ("C-c n h" . org-insert-habit) + ("C-c n m" . org-make-habit) + ("C-c n l" . org-store-link) + ("C-c n i" . org-insert-link) + ("C-c C-t" . org-todo) + ("C-c C-S-t" . org-todo-force-notes) + ("M-." . elisp-slime-nav-find-elisp-thing-at-point)) + :config + (progn + (setq org-global-properties + '(quote (("Effort_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00") + ("STYLE_ALL" . "habit")))) + ;; Record changes to todo states + (setq org-todo-keywords + '((sequence "IDEA(i!)" "RESEARCH(r!)" "TODO(t!)" "NEXT(n!)" + "STARTED(s!)" "WAIT(w!)" "BACKLOG(b!)" "|" + "DONE(d!)" "HANDLED(h!)" "EXPIRED(e!)" "CANCELED(c!)"))) + + (defvar-setq helm-org-headings-fontify t) + (setq org-todo-repeat-to-state "TODO") + + (setq org-agenda-span 10) + (setq org-agenda-start-day "-2d") + + (setq org-columns-default-format + "%80ITEM(Task) %10Effort(Effort){:} %10CLOCKSUM") + + (add-to-list 'org-show-context-detail '(org-goto . lineage)) + (sp-local-pair 'org-mode "~" "~") + + (add-to-list + 'org-src-lang-modes '("plantuml" . plantuml)) + + (org-babel-do-load-languages + 'org-babel-load-languages + '((sh . t) + (python . t) + (ruby . t) + (octave . t) + (sqlite . t) + (plantuml . t))) + + (setq org-log-into-drawer t + org-log-reschedule t + org-log-redeadline t + org-treat-insert-todo-heading-as-state-change t) + + (when nil + ;; Enable appointment notifications. + (defadvice org-agenda-to-appt (before wickedcool activate) + "Clear the appt-time-msg-list." + (setq appt-time-msg-list nil)) + (appt-activate) + (defun org-agenda-to-appt-no-message () + (shut-up (org-agenda-to-appt))) + (run-at-time "00:00" 60 'org-agenda-to-appt-no-message)) + + + ;; Override the key definition for org-exit + ;; TODO why does this cause an error + ;; (define-key org-agenda-mode-map "x" #'org-agenda-done) + + ;; org-mode add-ons + (use-package org-present + :commands org-present) + (use-package org-pomodoro + :disabled t) + + ;; variable configuration + (add-to-list 'org-modules 'org-habit) + (add-to-list 'org-modules 'org-expiry) + (add-to-list 'org-modules 'org-notify) + + (setq org-src-fontify-natively t) + (setq org-habit-graph-column 50) + (setq org-habit-show-habits-only-for-today t) + + ;; My priority system: + + ;; A - Absolutely MUST, at all costs, be completed by the provided + ;; due date. TODO: implement some type of extreme nagging + ;; system that alerts in an intrusive way for overdue A + ;; priority tasks. + + ;; B - Should be given immediate attention if the due date is any + ;; time in the next two days. Failure to meet due date would + ;; be bad but not catastrophic. + + ;; C - The highest priority to which tasks for which failure to + ;; complete on time would not have considerable significant + ;; consequences. There is still significant reason to prefer + ;; the completion of these tasks sooner rather than later. + + ;; D - Failure to complete within a few days (or ever) of any + ;; deadline would be completely okay. As such, any deadline + ;; present on such a task is necessarily self imposed. Still + ;; probably worth doing + + ;; E - Potentially not even worth doing at all, but worth taking a + ;; note about in case it comes up again, or becomes more + ;; interesting later. + + ;; F - Almost certainly not worth attempting in the immediate future. + ;; Just brain dump. + + ;; Priorities are somewhat contextual within each category. Things + ;; in the gtd or work categories are generally regarded as much + ;; more important than things with the same priority from the + ;; dotfiles category. + + ;; Items without deadlines or scheduled times of a given priority + ;; can be regarded as less important than items that DO have + ;; deadlines of that same priority. + + (setq org-lowest-priority 69) ;; The character E + (setq org-completion-use-ido t) + (setq org-enforce-todo-dependencies t) + (setq org-deadline-warning-days 0) + (setq org-default-priority ?D) + (setq org-agenda-skip-scheduled-if-done t) + (setq org-agenda-skip-deadline-if-done t) + ;;(add-to-list org-agenda-tag-filter-preset "+PRIORITY<\"C\"") + + (setq org-imenu-depth 10) + + ;; Stop starting agenda from deleting frame setup! + (setq org-agenda-window-setup 'other-window) + (define-key mode-specific-map [?a] 'org-agenda) + (unbind-key "C-j" org-mode-map) + + (use-package org-bullets + :config + (progn + (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))) + + (use-package org-ehtml + :disabled t + :config + (progn + (setq org-ehtml-docroot (expand-file-name "~/Dropbox/org")) + (setq org-ehtml-allow-agenda t) + (setq org-ehtml-editable-headlines t) + (setq org-ehtml-everything-editable t))) + + ;; Agenda setup. + (defvar imalison:org-gtd-file "~/org/gtd.org") + (defvar imalison:org-habits-file "~/org/habits.org") + (defvar imalison:org-calendar-file "~/org/calendar.org") + (defvar imalison:org-inbox-file "~/org/inbox.org") + + (unless (boundp 'org-capture-templates) + (defvar org-capture-templates nil)) + + (imalison:add-to-org-agenda-files + (list imalison:org-gtd-file imalison:org-habits-file + imalison:org-calendar-file imalison:org-inbox-file)) + + (add-to-list 'org-capture-templates + `("t" "GTD Todo (Linked)" entry (file ,imalison:org-gtd-file) + (function imalison:make-org-linked-todo-template))) + + (add-to-list 'org-capture-templates + `("g" "GTD Todo" entry (file ,imalison:org-gtd-file) + (function imalison:make-org-todo-template))) + + (add-to-list 'org-capture-templates + `("y" "Calendar entry (Linked)" entry + (file ,imalison:org-calendar-file) + "* %? %A + :PROPERTIES: + :CREATED: %U + :END: +%^T")) + + (add-to-list 'org-capture-templates + `("c" "Calendar entry" entry + (file ,imalison:org-calendar-file) + "* %? + :PROPERTIES: + :CREATED: %U + :END: +%^T")) + + (add-to-list 'org-capture-templates + `("h" "Habit" entry (file ,imalison:org-habits-file) + "* TODO + SCHEDULED: %^t + :PROPERTIES: + :CREATED: %U + :STYLE: habit + :END:")) + + (let ((this-week-high-priority + ;; The < in the following line works has behavior that is opposite + ;; to what one might expect. + '(tags-todo "+PRIORITY<\"C\"+DEADLINE<\"<+1w>\"DEADLINE>\"<+0d>\"" + ((org-agenda-overriding-header + "Upcoming high priority tasks:")))) + (due-today '(tags-todo + "+DEADLINE=<\"<+0d>\"" + ((org-agenda-overriding-header + "Due today:")))) + (recently-created '(tags-todo + "+CREATED=>\"<-3d>\"" + ((org-agenda-overriding-header "Recently created:") + (org-agenda-cmp-user-defined 'org-cmp-creation-times) + (org-agenda-sorting-strategy '(user-defined-down))))) + (next '(todo "NEXT")) + (started '(todo "STARTED")) + (missing-deadline + '(tags-todo "-DEADLINE={.}/!" + ((org-agenda-overriding-header + "These don't have deadlines:")))) + (missing-priority + '(tags-todo "-PRIORITY={.}/!" + ((org-agenda-overriding-header + "These don't have priorities:"))))) + + (setq org-agenda-custom-commands + `(("M" "Main agenda view" + ((agenda "" + ((org-agenda-overriding-header "Agenda:") + (org-agenda-ndays 5) + (org-deadline-warning-days 0))) + ,due-today + ,next + ,started + ,this-week-high-priority + ,recently-created) + nil nil) + ,(cons "A" (cons "High priority upcoming" this-week-high-priority)) + ,(cons "d" (cons "Overdue tasks and due today" due-today)) + ,(cons "r" (cons "Recently created" recently-created)) + ("h" "A, B priority:" tags-todo "+PRIORITY<\"C\"" + ((org-agenda-overriding-header + "High Priority:"))) + ("c" "At least priority C:" tags-todo "+PRIORITY<\"D\"" + ((org-agenda-overriding-header + "At least priority C:")))))) + + ;; What follows is a description of the significance of each of + ;; the values available in `org-todo-keywords'. All headings with + ;; one of these keywords deal with the concept of the completion + ;; of some task or collection of tasks to bring about a particular + ;; state of affairs. In some cases, the actual tasks involved may + ;; not be known at the time of task creation. + + ;; Incomplete States: + + ;; IDEA - This TODO exists in only the most abstract sense: it is + ;; an imagined state of affairs that requires tasks that are + ;; either not yet known, or have not thoroughly been considered. + + ;; RESEARCH - This TODO needs to be investigated further before + ;; action can be taken to achieve the desired outcome. It is not + ;; known how much time and effort will be consumed in the actual + ;; completion of the task. + + ;; TODO - The scope and work involved in this TODO are well + ;; understood, but for some reason or another, it is not something + ;; that should be attempted in the immediate future. Typically + ;; this is because the task is not considered a top priority, but + ;; it may also be for some other reason. + + ;; NEXT - This TODO is immediately actionable and should be + ;; started in the immediate future. + + ;; STARTED - Work on this TODO has already started, further work + ;; is immediately actionable. + + ;; WAIT - The work involved in this TODO is well understood, but + ;; it is blocked for the time being. + + ;; BACKLOG - While technically actionable, this task is not only + ;; not worth pursuing in the immediate future, but the foreseable + ;; future. It exists as a task mostly as a note/reminder, in case + ;; it becomes higher priority in the future. + + ;; Complete States: + + ;; DONE - This TODO has been completed exactly as imagined. + + ;; HANDLED - This TODO was completed in spirit, though not by the + ;; means that were originally imagined/outlined in the TODO. + + ;; EXPIRED - The owner of this TODO failed to take action on it + ;; within the appropriate time period, and there is now no point in + ;; attempting it. + + ;; CANCELED - For whatever reason, this TODO should no longer be + ;; attempted. This TODO is typically used in contrast to the + ;; EXPIRED TODO to indicate that the owner is not necessarily to + ;; blame. + )) ++
- Correct BG color for org-export++ ++
(use-package org + :config + (progn + (defun imalison:org-inline-css-hook (exporter) + "Insert custom inline css to automatically set the +background of code to whatever theme I'm using's background" + (when (eq exporter 'html) + (let* ((my-pre-bg (face-background 'default)) + (my-pre-fg (face-foreground 'default))) + (setq + org-html-head-extra + (concat + org-html-head-extra + (format "<style type=\"text/css\">\n pre.src {background-color: %s; color: %s;}</style>\n" + my-pre-bg my-pre-fg)))))) + + (add-hook 'org-export-before-processing-hook 'imalison:org-inline-css-hook))) +
+
+ - org-projectile++ ++
(imalison:use-package org-projectile + :after helm + :bind (("C-c n p" . imalison:helm-org-todo)) + :config + (progn + (org-projectile:prompt) + (add-to-list 'org-capture-templates + (org-projectile:project-todo-entry + "l" "* TODO %? %a\n" "Linked Project TODO")) + (add-to-list 'org-capture-templates (org-projectile:project-todo-entry "p")) + (setq org-confirm-elisp-link-function nil) + (imalison:add-to-org-agenda-files (org-projectile:todo-files)) + (require 'helm-source) + (require 'helm-org) + (defun imalison:helm-org-todo (&optional arg) + (interactive "P") + (helm :sources (list (helm-source-org-capture-templates) + (org-projectile:helm-source + (if arg (imalison:make-org-linked-todo-template) + (imalison:make-org-todo-template)))) + :candidate-number-limit 99999 + :buffer "*helm org capture templates*")))) +
+
+ - org-notify++ ++
(use-package org-notify + :disabled t + :after org + :config + (progn + (defun imalison:org-notify-notification-handler (plist) + (sauron-add-event 'org-notify 4 (format "%s, %s.\n" (plist-get plist :heading) + (org-notify-body-text plist)))) + + (setq org-show-notification-handler 'imalison:org-notify-notification-handler) + + (org-notify-add 'default '(:time "1h" :actions imalison:org-notify-notification-handler + :period "2m" :duration 60)) + (org-notify-add 'default '(:time "100m" :actions imalison:org-notify-notification-handler + :period "2m" :duration 60)) + (org-notify-add 'urgent-second '(:time "3m" :actions (-notify/window -ding) + :period "15s" :duration 10)) + (org-notify-add 'minute '(:time "5m" :actions -notify/window + :period "100s" :duration 70)) + (org-notify-add '12hours + '(:time "3m" :actions (-notify/window -ding) + :period "15s" :duration 10) + '(:time "100m" :actions -notify/window + :period "2m" :duration 60) + '(:time "12h" :actions -notify/window :audible nil + :period "10m" :duration 200)) + (org-notify-add '5days + '(:time "100m" :actions -notify/window + :period "2m" :duration 60) + '(:time "2d" :actions -notify/window + :period "15m" :duration 100) + '(:time "5d" :actions -notify/window + :period "2h" :duration 200)) + (org-notify-add 'long-20days + '(:time "2d" :actions -notify/window + :period "15m" :duration 60) + '(:time "5d" :actions -notify/window + :period "2h" :duration 60) + '(:time "20d" :actions -email :period "2d" :audible nil)) + (org-notify-add 'long-50days + '(:time "4d" :actions -notify/window + :period "30m" :duration 100) + '(:time "10d" :actions -notify/window + :period "4h" :duration 200) + '(:time "50d" :actions -email :period "3d" :audible nil)) + (org-notify-add 'long-100days + '(:time "2d" :actions -notify/window + :period "1h" :duration 200) + '(:time "10d" :actions -notify/window + :period "10h" :duration 300) + '(:time "50d" :actions -email :period "3d" :audible nil) + '(:time "100d" :actions -email :period "5d" :audible nil)) + (org-notify-start 10))) +
+
+ - org-reveal++ ++
(use-package ox-reveal + :after org + :config + (setq org-reveal-root + (imalison:join-paths "file://" imalison:projects-directory "reveal.js"))) +
+
+ - org-caldav++ ++
(use-package org-caldav + :defer t + :config + (progn + (setq org-caldav-url "https://www.google.com/calendar/dav" + org-caldav-inbox imalison:org-inbox-file + org-caldav-files (list imalison:org-calendar-file) + org-icalendar-timezone "America/Los_Angeles"))) +
+
10.3.2 TeX
+(use-package tex + :ensure auctex + :commands TeX-mode + :preface + (progn + (defun imalison:TeX-mode-hook () + (turn-on-reftex) + (TeX-source-correlate-mode +1) + (TeX-PDF-mode +1))) + :config + (progn + (unbind-key "C-j" TeX-mode-map) + (TeX-global-PDF-mode) + (setq TeX-auto-save t + TeX-parse-self t + TeX-save-query nil + TeX-PDF-mode t) + (TeX-global-PDF-mode t) + (add-hook 'TeX-mode-hook 'imalison:TeX-mode-hook))) ++
- latex++ ++
(use-package latex + :ensure auctex + :after tex + :config + (progn + (unbind-key "C-j" LaTeX-mode-map))) +
+
+ - auctex-latexmk++ ++
(use-package auctex-latexmk + :after tex + :config + (progn + (setq auctex-latexmk-inherit-TeX-PDF-mode t) + (auctex-latexmk-setup))) +
+
+ - company-auctex++ ++
(use-package company-auctex + :after tex + :config + (company-auctex-init)) +
+
10.3.3 markdown-mode
+(use-package markdown-mode + :init + (progn + (add-hook 'markdown-mode-hook 'imalison:disable-linum-mode))) ++
10.3.4 plantuml-mode
++This mode seems to be better maintained than plantuml-mode +
+(use-package plantuml-mode + :commands plantuml-mode + :mode ("\\.puml\\'" "\\.plantuml\\'") + :preface + (progn + (cond ((equal system-type 'darwin) + (let* ((plantuml-dir + (s-trim (shell-command-to-string "brew --prefix plantuml"))) + (filename + (when (file-exists-p plantuml-dir) + (--first (s-ends-with? ".jar" it) (directory-files plantuml-dir)))) + (filepath (when filename + (imalison:join-paths plantuml-dir filename)))) + (setq plantuml-jar-path filepath + org-plantuml-jar-path filepath))) + ((equal system-type 'gnu/linux) + (let ((filepath "/opt/plantuml/plantuml.jar")) + (setq plantuml-jar-path filepath + org-plantuml-jar-path filepath)))) + (add-to-list + 'org-src-lang-modes '("plantuml" . plantuml)))) ++
10.3.5 wsd-mode
+(use-package wsd-mode + :commands (wsd-mode)) ++
10.4 Utility
+10.4.1 restclient
+(use-package restclient + :mode (("\\.restclient\\'" . restclient-mode)) + :config + (progn + (use-package company-restclient))) ++
10.4.2 jq-mode
+(use-package jq-mode + :mode "\\.jq\\'") ++
11 Programming
+11.1 realgud
++realgud provides debugging support with many external debuggers in emacs +
+(use-package realgud + :defer 10) ++
11.2 emr
++emr (emacs refactor) provides support for refactoring in many programming languages +
+(use-package emr + :bind (:map prog-mode-map + ("M-RET" . emr-show-refactor-menu)) + :config (emr-initialize)) ++
11.3 semantic
+(use-package semantic + :commands semantic-mode + :disabled t + :preface + (progn + (add-hook 'prog-mode-hook 'semantic-mode))) ++
12 Utility
+12.1 term
+(use-package term + :bind (:map term-raw-escape-map + ("M-x" . helm-M-x) + :map term-raw-map + ("M-x" . helm-M-x)) + :config + (progn + (define-key term-raw-map (kbd "C-h") help-map) + (add-hook 'term-mode-hook 'imalison:disable-linum-mode) + (setq term-buffer-maximum-size 0))) ++
12.2 term-manager
+(imalison:use-package term-manager + :defer t + :preface + (progn + (defun imalison:set-escape-char (&rest _args) + (let (term-escape-char) + (term-set-escape-char ?\C-x)))) + :config + (progn + (advice-add + 'term-manager-default-build-term :after 'imalison:set-escape-char))) ++
12.3 term-projectile
+(imalison:use-package* term-projectile "term-manager" + :bind ("C-c 7" . imalison:term-hydra-global/body) + :commands (term-projectile-forward term-projectile-backward + term-projectile-default-directory-forward + term-projectile-default-directory-backward + term-projectile-create-new + term-projectile-create-new-default-directory) + :config + (progn + (emit-prefix-selector imalison:term + term-projectile-forward + term-projectile-create-new) + + (defvar imalison:term-hydra-original-default-directory) + + (defhydra imalison:term-hydra-default-directory + (:body-pre + (term-projectile-default-directory-forward-restored)) + "term - default-directory" + ("s" term-projectile-switch-to) + ("f" term-projectile-default-directory-forward-restored) + ("b" term-projectile-default-directory-backward-restored) + ("c" term-projectile-default-directory-create-new-restored) + ("d" term-projectile-default-directory-forward-restored) + ("g" imalison:term-hydra-global/body-restored :exit t) + ("p" imalison:term-hydra-projectile/body-restored :exit t)) + + (defhydra imalison:term-hydra-projectile + (:body-pre + (progn + (term-projectile-forward-restored))) + "term - projectile" + ("s" term-projectile-switch-to) + ("f" term-projectile-forward-restored) + ("b" term-projectile-backward-restored) + ("c" term-projectile-create-new-restored) + ("d" imalison:term-hydra-default-directory/body-restored :exit t) + ("g" imalison:term-hydra-global/body-restored :exit t) + ("p" term-projectile-forward-restored)) + + + (defhydra imalison:term-hydra-global + (:body-pre + (progn (setq imalison:term-hydra-original-default-directory + default-directory))) + "term - global" + ("s" term-projectile-switch-to) + ("f" term-projectile-global-forward-restored) + ("b" term-projectile-global-backward-restored) + ("c" term-projectile-global-create-new-restored) + ("d" imalison:term-hydra-default-directory/body-restored :exit t) + ("g" term-projectile-global-forward-restored) + ("p" imalison:term-hydra-projectile/body-restored :exit t)) + + (mapcar (lambda (term-projectile-function) + (defalias (imalison:concat-symbols term-projectile-function '-restored) + (lambda (&rest args) + (interactive) + (let ((default-directory imalison:term-hydra-original-default-directory)) + (apply term-projectile-function args))))) + '(term-projectile-default-directory-forward + term-projectile-default-directory-backward + term-projectile-default-directory-create-new + term-projectile-forward + term-projectile-backward + term-projectile-create-new + term-projectile-global-forward + term-projectile-global-backward + term-projectile-global-create-new + imalison:term-hydra-global/body + imalison:term-hydra-projectile/body + imalison:term-hydra-default-directory/body)))) ++
12.4 crux
++crux-reopen-as-root-mode makes it so that any file owned by root will automatically be opened as the root user. +
+(use-package crux + :demand t + :bind (("C-c C-s" . crux-sudo-edit) + ("C-c C-r" . crux-eval-and-replace) + ("C-c o" . crux-open-with)) + :config + (progn + (crux-reopen-as-root-mode))) ++
13 Chat
+13.1 erc
+(use-package erc + :commands erc + :config + (progn + ;; (add-to-list 'erc-modules 'notifications) + ;; logging: + (use-package erc-colorize + :config + (erc-colorize-mode 1)))) ++
13.2 bitlbee
+(use-package bitlbee + :disabled t + :config + (progn + (defvar bitlbee-password "geheim") + (add-hook 'erc-join-hook 'bitlbee-identify) + (defun bitlbee-identify () + "If we're on the bitlbee server, send the identify command to the + &bitlbee channel." + (when (and (string= "localhost" erc-session-server) + (string= "&bitlbee" (buffer-name))) + (erc-message "PRIVMSG" (format "%s identify %s" + (erc-default-target) + bitlbee-password)))))) ++
13.3 slack
+(use-package slack) ++
14 Cooperation
+14.1 togetherly
+(use-package togetherly) ++
14.2 floobits
+(use-package floobits) ++
14.3 rudel
+(use-package rudel + :disabled t) ++
15 Other
+15.1 anzu
+(use-package anzu + :config + (progn + (global-anzu-mode +1) + + (custom-set-variables + '(anzu-mode-lighter "") + '(anzu-deactivate-region t) + '(anzu-search-threshold 1000) + '(anzu-replace-threshold 50) + '(anzu-replace-to-string-separator " => ")) + + (define-key isearch-mode-map [remap isearch-query-replace] + #'anzu-isearch-query-replace) + (define-key isearch-mode-map [remap isearch-query-replace-regexp] + #'anzu-isearch-query-replace-regexp))) ++
15.2 fontawesome
+(use-package fontawesome + :commands helm-fontawesome) ++
15.3 shell-history
++I think that shell-history is causing projectile to be very slow so I have disabled it. +
+(use-package shell-history + :demand t + :disabled t) ++
15.4 iedit
+
+I don't use iedit directly, but it is used by emr and I need to disable iedit-toggle-key-default
or else a buffer pops up complaing that the key has been bound to something else
+
(use-package iedit + :defer t) ++
15.5 tramp
+(use-package tramp + :commands tramp + :config + (setq tramp-default-method "scp")) ++
15.6 flycheck
+(use-package flycheck + :config + (progn + (use-package flycheck-package + :config (flycheck-package-setup)) + + (imalison:use-package flycheck-cask + :after flycheck + :config + (add-hook 'flycheck-mode-hook #'flycheck-cask-setup)) + + (add-to-list 'flycheck-emacs-lisp-checkdoc-variables + 'sentence-end-double-space) + (global-flycheck-mode)) + :diminish flycheck-mode) ++
15.7 narrow-indirect
+(use-package narrow-indirect + :init + (progn + (define-key ctl-x-4-map "nd" 'ni-narrow-to-defun-indirect-other-window) + (define-key ctl-x-4-map "nn" 'ni-narrow-to-region-indirect-other-window) + (define-key ctl-x-4-map "np" 'ni-narrow-to-page-indirect-other-window))) ++
15.8 editorconfig
++I had to disable this mode because something that it does messes with coding settings and makes it so that I have to select the appropriate encoding every time I save gpg encrypted files. +
+(use-package editorconfig + :disabled t + :config + (progn + (add-to-list 'editorconfig-exclude-modes '(org-mode)) + (editorconfig-mode 1))) ++
15.9 dtrt-indent
+(use-package dtrt-indent + :commands 'dtrt-indent-mode + :init (add-hook 'prog-mode-hook 'dtrt-indent-mode) + :config + (progn + (setq dtrt-indent-active-mode-line-info " [⟼]"))) ++
15.10 indent-guide
+(use-package indent-guide + :disabled t + :config + (progn + (indent-guide-global-mode -1) + (setq indent-guide-delay 0.1))) ++
15.11 rainbow-delimiters
+(use-package rainbow-delimiters + :commands rainbow-delimiters-mode + :init + (progn + (add-hook 'prog-mode-hook (lambda () (rainbow-delimiters-mode t))))) ++
15.12 undo-tree
+(use-package undo-tree + :disabled t ;; this has been getting pretty annoying + :bind (("C--" . undo-redo) + ("C-c u" . undo-tree-visualize) + ("C-c r" . undo-tree-redo)) + :config + (diminish 'undo-tree-mode) + :init + (progn + ;;(setq undo-tree-visualizer-diff t) ;; This causes performance problems + (global-undo-tree-mode) + (setq undo-tree-visualizer-timestamps t))) ++
15.13 recentf
+(use-package recentf + :config + (progn + (setq recentf-max-saved-items 1000 + recentf-max-menu-items 1000) + (advice-add 'recentf-cleanup :around 'imalison:shut-up-around) + (recentf-mode 1))) ++
15.14 key-chord
++I have currently disabled key-chord because it may cause typing lag. +
+(use-package key-chord + :disabled t + :preface + (defun imalison:disable-keychord-around (function &rest args) + (let ((key-chord-mode-was-enabled (bound-and-true-p key-chord-mode))) + (when key-chord-mode-was-enabled (key-chord-mode -1)) + (condition-case err (progn (apply function args)) (error)) + (when key-chord-mode-was-enabled (key-chord-mode 1)))) + :config + (progn + (advice-add 'key-chord-mode :around 'imalison:shut-up-around) + (key-chord-mode 1) + (advice-add 'imalison:avy :around 'imalison:disable-keychord-around) + (key-chord-define-global "tg" 'imalison:term-hydra/body) + (key-chord-define-global "pj" 'imalison:projectile-find-file) + (key-chord-define-global "p[" 'projectile-switch-project) + (key-chord-define-global "fj" 'imalison:do-ag) + (key-chord-define-global "jh" 'imalison:avy))) ++
15.15 nodejs-repl
+(use-package nodejs-repl + :commands nodejs-repl) ++
15.16 calc-mode
+(use-package calc-mode + :ensure nil + :commands calc + :config + (progn + (setq calc-context-sensitive-enter t))) ++
15.17 helm-spotify
+(use-package helm-spotify + :commands helm-spotify) ++
15.18 jabber
+(use-package jabber + :commands jabber-connect + :config + (progn + (setq jabber-alert-presence-hooks nil) + (defun jabber-message-content-message (from buffer text) + (when (or jabber-message-alert-same-buffer + (not (memq (selected-window) (get-buffer-window-list buffer)))) + (if (jabber-muc-sender-p from) + (format "%s: %s" (jabber-jid-resource from) text) + (format "%s: %s" (jabber-jid-displayname from) text)))) + (setq jabber-alert-message-function 'jabber-message-content-message))) ++
15.19 htmlize
+(use-package htmlize) ++
15.20 calfw
+(use-package calfw + :config + (progn + (require 'calfw-org))) ++
15.21 clocker
++Not really sure what this is +
+(use-package clocker) ++
15.22 deft
+(use-package deft + :commands deft + :config + (progn + (setq deft-default-extension "org") + (setq deft-extensions '("org")) + (setq deft-use-filter-string-for-filename t) + (setq deft-file-naming-rules '((noslash . "_") + (nospace . "_") + (case-fn . downcase))) + (setq deft-directory "~/SparkleShare/org/notes"))) ++
15.23 epg
+(use-package epg + :after shut-up + :config + (shut-up + (epa-file-enable))) ++
15.24 pinentry
+(use-package pinentry + :defer 5 + :config + (pinentry-start)) ++
15.25 twittering-mode
+(use-package twittering-mode + :commands twittering-mode) ++
15.26 matrix-client
+(use-package matrix-client + :disabled t ;; fails to load eieio on startup + ) ++
15.27 mu4e
+(eval-when-compile + (require 's) + (defvar mu4e-elisp-directory + (s-trim (shell-command-to-string "mu4e_directory")))) +(use-package mu4e + :load-path mu4e-elisp-directory + :ensure nil + :commands (mu4e mu4e-view-message-with-msgid mu4e-update-index email) + :bind ("C-c 0" . email) + :config + (progn + (defun email (&optional arg) + (interactive "P") + (if (string-equal (persp-name persp-curr) "email") + (progn (delete-other-windows) (mu4e)) + (progn + (persp-switch "email") + (when (or (not (mu4e-running-p)) arg) + (delete-other-windows) (mu4e))))) + ;; enable inline images + (setq mu4e-view-show-images t) + ;; show images + (setq mu4e-show-images t) + ;; Try to display html as text + (setq mu4e-view-prefer-html nil) + + (setq mu4e-html2text-command "html2text -width 80 -nobs -utf8") + + ;; use imagemagick, if available + (when (fboundp 'imagemagick-register-types) + (imagemagick-register-types)) + (setq mail-user-agent 'mu4e-user-agent) + (require 'org-mu4e) + (setq mu4e-compose-complete-only-after nil) + (setq mu4e-maildir "~/Mail") + + (setq mu4e-drafts-folder "/[Gmail].Drafts") + (setq mu4e-sent-folder "/[Gmail].Sent Mail") + (setq mu4e-trash-folder "/[Gmail].Trash") + + (setq mu4e-sent-messages-behavior 'delete) + (setq mu4e-headers-skip-duplicates t) + (setq mu4e-update-interval (* 60 20)) + (setq message-kill-buffer-on-exit t) + (setq mail-user-agent 'mu4e-user-agent) ;; make mu4e the default mail client + + ;; don't save message to Sent Messages, Gmail/IMAP takes care of this + (setq mu4e-sent-messages-behavior 'delete) + + ;; allow for updating mail using 'U' in the main view: + (setq mu4e-get-mail-command "timeout 60 offlineimap") + + (add-hook 'mu4e-compose-mode-hook + (defun my-do-compose-stuff () (flyspell-mode))) + + (add-to-list 'mu4e-headers-actions '("view in browser" . mu4e-action-view-in-browser)) + (add-to-list 'mu4e-view-actions '("view in browser" . mu4e-action-view-in-browser)) + + (defun mu4e-view (msg headersbuf) + "Display the message MSG in a new buffer, and keep in sync with HDRSBUF. + 'In sync' here means that moving to the next/previous message in + the the message view affects HDRSBUF, as does marking etc. + + As a side-effect, a message that is being viewed loses its 'unread' + marking if it still had that." + (let* ((embedded ;; is it as an embedded msg (ie. message/rfc822 att)? + (when (gethash (mu4e-message-field msg :path) + mu4e~path-parent-docid-map) t)) + (buf + (if embedded + (mu4e~view-embedded-winbuf) + (get-buffer-create mu4e~view-buffer-name)))) + ;; note: mu4e~view-mark-as-read will pseudo-recursively call mu4e-view again + ;; by triggering mu4e~view again as it marks the message as read + (with-current-buffer buf + (switch-to-buffer buf) + (setq mu4e~view-msg msg) + ;;(or embedded (not (mu4e~view-mark-as-read msg))) + (when (or (mu4e~view-mark-as-read msg) t) + (let ((inhibit-read-only t)) + (erase-buffer) + (mu4e~delete-all-overlays) + (insert (mu4e-view-message-text msg)) + (goto-char (point-min)) + (mu4e~fontify-cited) + (mu4e~fontify-signature) + (mu4e~view-make-urls-clickable) + (mu4e~view-show-images-maybe msg) + (setq + mu4e~view-buffer buf + mu4e~view-headers-buffer headersbuf) + (when embedded (local-set-key "q" 'kill-buffer-and-window)) + (mu4e-view-mode)))))) + + (require 'smtpmail) + + ;; alternatively, for emacs-24 you can use: + (setq message-send-mail-function 'smtpmail-send-it + smtpmail-stream-type 'starttls + smtpmail-default-smtp-server "smtp.gmail.com" + smtpmail-smtp-server "smtp.gmail.com" + smtpmail-smtp-service 587))) ++
15.28 gmail-message-mode
++This is useful with server mode when editing gmail messages. I think that it is not currently working, or it may need to be manually enabled. +
+(use-package gmail-message-mode + :demand t) ++
15.29 ham-mode
+(use-package ham-mode + :config + (progn + (setq ham-mode-html-to-markdown-command '("pandoc" "--from" "html" "--to" "markdown" file)))) ++
15.30 alert
+(use-package alert + :config + (progn + (defun alert-notifier-notify (info) + (if alert-notifier-command + (let ((args + (list "-title" (alert-encode-string (plist-get info :title)) + "-activate" "org.gnu.Emacs" + "-message" (alert-encode-string (plist-get info :message)) + "-execute" (format "\"%s\"" (switch-to-buffer-command (plist-get info :buffer)))))) + (apply #'call-process alert-notifier-command nil nil nil args)) + (alert-message-notify info))) + + (defun switch-to-buffer-command (buffer-name) + (emacsclient-command (format "(switch-to-buffer \\\"%s\\\")" buffer-name))) + + (defun emacsclient-command (command) + (format "emacsclient --server-file='%s' -e '%s'" server-name command)) + + (setq alert-default-style 'notifier))) ++
15.31 sauron
+(use-package sauron + :defer 5 + :commands (sauron-start sauron-start-hidden) + :init + (progn + (when (eq system-type 'darwin) + (setq sauron-modules '(sauron-erc sauron-org sauron-notifications + sauron-twittering sauron-jabber sauron-identica)) + (defun sauron-dbus-start () + nil) + (makunbound 'dbus-path-emacs))) + :config + (progn + (sauron-start-hidden) + ;; This should really check (featurep 'dbus) but for some reason + ;; this is always true even if support is not there. + (setq sauron-prio-sauron-started 2) + (setq sauron-min-priority 3) + ;; (setq sauron-dbus-cookie t) ;; linux only? + (setq sauron-separate-frame nil) + (setq sauron-nick-insensitivity 1) + (defun sauron:jabber-notify (origin priority message &optional properties) + (funcall notify-function "gtalk" message)) + (defun sauron:erc-notify (origin priority message &optional properties) + (let ((event (plist-get properties :event))) + (funcall notify-function "IRC" message))) + (defun sauron:mu4e-notify (origin priority message &optional properties) + nil) + (defun sauron:dbus-notify (origin priority message &optional properties) + (funcall notify-function "GMail" message)) + (defun sauron:dispatch-notify (origin priority message &optional properties) + (let ((handler (cond ((string= origin "erc") 'sauron:erc-notify) + ((string= origin "jabber") 'sauron:jabber-notify) + ((string= origin "mu4e") 'sauron:mu4e-notify) + ((string= origin "dbus") 'sauron:dbus-notify) + (t (lambda (&rest r) nil))))) + (funcall handler origin priority message properties))) + ;; Prefering alert.el for now ;; (add-hook 'sauron-event-added-functions 'sauron:dispatch-notify) + (sauron-start-hidden) + (add-hook 'sauron-event-added-functions 'sauron-alert-el-adapter))) ++
15.32 screenshot
+(use-package screenshot) ++
15.33 libmpdee
+(use-package libmpdee) ++
15.34 flyspell
+(use-package flyspell + :disabled t ; kind of annoying + :preface (setq flyspell-issue-welcome-flag nil) + :config + (progn + (diminish 'flyspell-mode) + (bind-key "M-s" 'flyspell-correct-word-before-point flyspell-mode-map) + (unbind-key "C-;" flyspell-mode-map) + (defun flyspell-emacs-popup-textual (event poss word) + "A textual flyspell popup menu." + (let* ((corrects (if flyspell-sort-corrections + (sort (car (cdr (cdr poss))) 'string<) + (car (cdr (cdr poss))))) + (cor-menu (if (consp corrects) + (mapcar (lambda (correct) + (list correct correct)) + corrects) + '())) + (affix (car (cdr (cdr (cdr poss))))) + show-affix-info + (base-menu (let ((save (if (and (consp affix) show-affix-info) + (list + (list (concat "Save affix: " + (car affix)) + 'save) + '("Accept (session)" session) + '("Accept (buffer)" buffer)) + '(("Save word" save) + ("Accept (session)" session) + ("Accept (buffer)" buffer))))) + (if (consp cor-menu) + (append cor-menu (cons "" save)) + save))) + (menu (mapcar + (lambda (arg) (if (consp arg) (car arg) arg)) + base-menu))) + (cadr (assoc (popup-menu* menu :scroll-bar t) base-menu)))) + (fset 'flyspell-emacs-popup 'flyspell-emacs-popup-textual))) ++
15.35 web-mode
+(use-package web-mode + :mode (("\\.tmpl\\'" . web-mode) + ("\\.cql\\'" . web-mode)) + :config + (progn + (defvar-setq web-mode-content-types-alist + '(("gtl" . "\\.tmpl\\'") + ("gtl" . "\\.cql\\'"))))) ++
15.36 helm-themes
+(use-package helm-themes) ++
15.37 helm-swoop
+(use-package helm-swoop + :bind ("C-S-s" . helm-swoop) + :commands helm-swoop) ++
15.38 perspective
++I've disabled perspective because I just don't use it much. +
+(use-package perspective + :disabled t + :demand t + :config + (progn + (persp-mode) + (defun persp-get-perspectives-for-buffer (buffer) + "Get the names of all of the perspectives of which `buffer` is a member." + (cl-loop for perspective being the hash-value of perspectives-hash + if (member buffer (persp-buffers perspective)) + collect (persp-name perspective))) + + (defun persp-pick-perspective-by-buffer (buffer) + "Select a buffer and go to the perspective to which that buffer + belongs. If the buffer belongs to more than one perspective + completion will be used to pick the perspective to switch to. + Switch the focus to the window in which said buffer is displayed + if such a window exists. Otherwise display the buffer in whatever + window is active in the perspective." + (interactive (list (funcall persp-interactive-completion-function + "Buffer: " (mapcar 'buffer-name (buffer-list))))) + (let* ((perspectives (persp-get-perspectives-for-buffer (get-buffer buffer))) + (perspective (if (> (length perspectives) 1) + (funcall persp-interactive-completion-function + (format "Select the perspective in which you would like to visit %s." + buffer) + perspectives) + (car perspectives)))) + (if (string= (persp-name persp-curr) perspective) + ;; This allows the opening of a single buffer in more than one window + ;; in a single perspective. + (switch-to-buffer buffer) + (progn + (persp-switch perspective) + (if (get-buffer-window buffer) + (set-frame-selected-window nil (get-buffer-window buffer)) + (switch-to-buffer buffer)))))) + + (defun persp-mode-switch-buffers (arg) + (interactive "P") + (if arg (call-interactively 'ido-switch-buffer) + (call-interactively 'persp-pick-perspective-by-buffer))) + + (define-key persp-mode-map (kbd "C-x b") 'persp-mode-switch-buffers)) + :bind ("C-c 9" . persp-switch)) ++
15.39 smex
+(use-package smex + ;; Using helm-M-x instead + :disabled t + :commands smex + ;; This is here because smex feels like part of ido + :bind ("M-x" . smex)) ++
15.40 java
+(add-hook 'java-mode-hook + (lambda () + (setq c-basic-offset 4 + tab-width 4 + indent-tabs-mode t))) ++
15.41 android-mode
+(use-package android-mode + :after s + :config + (progn + (setq android-mode-sdk-dir + (s-trim (shell-command-to-string "android_sdk_directory"))))) ++
15.42 gradle-mode
+(use-package gradle-mode) ++
15.43 jsx-mode
+(use-package jsx-mode + :mode "\\.jsx\\'") ++
15.44 css
+(eval-after-load 'css-mode + '(define-key css-mode-map (kbd "C-c b") 'web-beautify-css)) ++
15.45 robe
+(use-package robe + :commands robe-mode + :init + (progn (add-hook 'ruby-mode-hook 'robe-mode))) ++
15.46 rinari
+(use-package rinari + :after ruby-mode) ++
15.47 helm-gtags
+(use-package helm-gtags + :config + (progn + (setq helm-gtags-ignore-case t + helm-gtags-auto-update t + helm-gtags-use-input-at-cursor t + helm-gtags-pulse-at-cursor t + helm-gtags-prefix-key "\C-cg" + helm-gtags-suggested-key-mapping t) + (cl-loop for hook in '(dired-mode-hook eshell-mode-hook c-mode-hook + c++-mode-hook asm-mode-hook) + do (add-hook hook 'helm-gtags-mode))) + :bind (:map helm-gtags-mode-map + ("C-c g a" . helm-gtags-tags-in-this-function) + ("C-j" . helm-gtags-select) + ("M-." . helm-gtags-dwim) + ("M-," . helm-gtags-pop-stack) + ("C-c <" . helm-gtags-previous-history) + ("C-c >" . helm-gtags-next-history))) ++
15.48 sgml-mode
+(use-package sgml-mode + ;; :bind ("C-c b" . web-beautify-html) TODO: mode specific, change binding + :commands sgml-mode) ++
15.49 evil
+(use-package evil :commands (evil-mode)) ++
16 Appearance
+16.1 Basic Config
+(setq inhibit-startup-screen t) +(blink-cursor-mode -1) ++
16.2 Themes
++Ensure all themes that I use are installed: +
+(use-package solarized-theme + :init + (progn + (setq solarized-high-contrast-mode-line t))) + +(defvar-setq packages-appearance + '(monokai-theme solarized-theme zenburn-theme base16-theme molokai-theme + tango-2-theme gotham-theme sublime-themes rainbow-delimiters waher-theme + ample-theme material-theme zerodark-theme color-theme-modern leuven-theme + spacemacs-theme gruvbox-theme forest-blue-theme flatland-theme afternoon)) + +(ensure-packages-installed packages-appearance) ++
16.3 all-the-icons
+(use-package all-the-icons + :demand t) ++
16.4 spaceline
+16.4.1 Disable sRGB colorspace to make powerline separators work
+(setq ns-use-srgb-colorspace nil) ++
16.4.2 config
+(use-package spaceline-config + :ensure spaceline + :commands spaceline-compile + :preface + (progn + (defun spaceline-gh-notifier-disable-default-notifier-modeline (&rest args) + (delq 'github-notifier-mode-line global-mode-string))) + :config + (progn + (advice-add 'github-notifier-mode :after + 'spaceline-gh-notifier-disable-default-notifier-modeline) + (advice-add 'github-notifier-update :after + 'spaceline-gh-notifier-disable-default-notifier-modeline) + + (setq powerline-default-separator (random-choice '(butt slant wave))) + (setq spaceline-workspace-numbers-unicode t + spaceline-window-numbers-unicode t) + + (if (display-graphic-p) + (setq-default powerline-default-separator 'wave) + (setq-default powerline-default-separator 'utf-8)) + + (spaceline-define-segment imalison:muni + "Display the number of minutes until the next muni train comes" + (format "🚇%s" (imalison:get-cached-muni-time)) + :when active) + + (spaceline-define-segment spaceline-gh-notifier + "Display the number of github notifications the user has" + (format "✉%s" github-notifier-unread-count) + :when (> github-notifier-unread-count 0)) + + (advice-add 'pl/separator-height :around + (lambda (function &rest args) + (+ (apply function args) 10))) + + ;; This needs to be executed after setting the font because the separators + ;; need to get regenerated + (advice-add 'imalison:set-font-size :after 'spaceline-compile) + + (spaceline-helm-mode) + ;; 'spaceline-gh-notifier and 'imalison:muni disabled for now + (spaceline-spacemacs-theme))) ++
16.5 helm-themes
++helm-themes provides an easy way to switch between emacs-themes. +
+(use-package helm-themes + :after helm) ++
16.6 window-number
+(use-package window-number + :defer t) ++
16.7 Whitespace Setup
++Make whitespace-mode use just basic coloring: +
+(setq whitespace-style + '(spaces tabs newline space-mark tab-mark newline-mark)) ++
+Set the character used to represent spaces to ·, and the character used for tabs to be ▷. +
+(setq whitespace-display-mappings + '((space-mark 32 [183] [46]) + (tab-mark 9 [9655 9] [92 9]))) ++
16.8 Colorize Compliation Buffers
++This automatically applies ansi-color interpretation of terminal escape sequences to compilation buffers +
+(defun colorize-compilation-buffer () + (read-only-mode) + (ansi-color-apply-on-region (point-min) (point-max)) + (read-only-mode)) +(add-hook 'compilation-filter-hook 'colorize-compilation-buffer) ++
16.9 Automatic Theme Changer
++Disabled for now +
+(use-package theme-changer + :disabled t + :config + (progn + (destructuring-bind (latitude longitude) + (imalison:get-lat-long) + (setq calendar-latitude latitude) + (setq calendar-longitude longitude)))) ++
16.10 Fix ansi-term
Colors
+
+For some reason, loading certain themes can cause colors in
+ansi-term-color-vector
to be undefined. The following code handles restoring
+the original ansi-term-color-vector
state. The code is exectued in a
+load-theme hook (See the heading below).
+
(require 'term) +(defvar imalison:ansi-term-color-vector ansi-term-color-vector) + +(defun imalison:ansi-term-color-vector-broken? () + (--some (or (eq it 'unspecified) (not (symbolp it))) + (append ansi-term-color-vector nil))) + +(defun imalison:restore-ansi-term-color-vector (&optional force) + (when (or force (imalison:ansi-term-color-vector-broken?)) + (setq ansi-term-color-vector imalison:ansi-term-color-vector))) ++
16.11 After load-theme
hook
+(defvar imalison:light-theme 'solarized-light) +(defvar imalison:dark-theme 'material) + +(defun imalison:after-load-theme (&rest _args) + (when (fboundp 'powerline-reset) + (powerline-reset)) + (set-face-background 'fringe (face-background 'default)) + (imalison:restore-ansi-term-color-vector)) + +(advice-add 'load-theme :after #'imalison:after-load-theme) ++
16.12 Frame Initialization
+(defvar imalison:linum-format) + +(defun imalison:format-linum (line-text) + (propertize (format imalison:linum-format line-text) 'face 'linum)) + +(make-variable-buffer-local 'imalison:linum-format) +(defun imalison:linum-before-numbering-hook () + (setq imalison:linum-format + (concat "%" (number-to-string + (max (length + (number-to-string + (count-lines (point-min) (point-max)))) 3)) "d"))) + +(defun imalison:remove-fringe-and-hl-line-mode (&rest _stuff) + (interactive) + (if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1)) + (if (fboundp 'tool-bar-mode) (tool-bar-mode -1)) + (if (fboundp 'menu-bar-mode) (menu-bar-mode -1)) + (defvar-setq linum-format 'imalison:format-linum) + (add-hook 'linum-before-numbering-hook 'imalison:linum-before-numbering-hook) + (setq left-margin-width 0) + (defvar-setq hl-line-mode nil)) + +(defun imalison:appearance (&optional frame) + (interactive (list nil)) + (if (display-graphic-p) + (progn + (condition-case _ignored + (set-face-attribute 'default nil :font "Source Code Pro") + ('error nil)) + (set-face-attribute 'default nil :weight 'semi-bold) + (set-face-attribute + 'default nil :height imalison:default-font-size-pt)) + (progn + (load-theme 'source-code-pro t) + (message "not setting font"))) + (setq powerline-default-separator (if (display-graphic-p) 'wave 'utf-8)) + (load-theme imalison:dark-theme t) + (spaceline-compile) + (imalison:remove-fringe-and-hl-line-mode)) + +;; This is needed because you can't set the font or theme at daemon start-up. +;; (when (display-graphic-p) (imalison:appearance)) +(add-hook 'after-init-hook 'imalison:appearance) +(add-hook 'after-make-frame-functions 'imalison:appearance) +;; TODO/XXX: why do we immediately remove this hook? +(remove-hook 'after-make-frame-functions 'imalison:appearance) ++
17 Post Init Custom
+(when (file-exists-p custom-after-file) (load custom-after-file)) +(when (file-exists-p machine-custom) (load machine-custom)) ++