diff options
Diffstat (limited to 'emacs.d/wpc')
-rw-r--r-- | emacs.d/wpc/casing.el | 39 | ||||
-rw-r--r-- | emacs.d/wpc/functions.el | 227 | ||||
-rw-r--r-- | emacs.d/wpc/macros.el | 33 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-clojure.el | 63 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-company.el | 24 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-dired.el | 18 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-docker.el | 18 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-flycheck.el | 14 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-git.el | 17 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-haskell.el | 32 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-javascript.el | 87 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-keybindings.el | 131 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-lisp.el | 37 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-misc.el | 155 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-org.el | 45 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-package.el | 32 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-slack.el | 65 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-terminal.el | 19 | ||||
-rw-r--r-- | emacs.d/wpc/packages/wpc-ui.el | 136 | ||||
-rw-r--r-- | emacs.d/wpc/string-functions.el | 41 | ||||
-rw-r--r-- | emacs.d/wpc/variables.el | 18 |
21 files changed, 1251 insertions, 0 deletions
diff --git a/emacs.d/wpc/casing.el b/emacs.d/wpc/casing.el new file mode 100644 index 000000000000..0592d9dddb08 --- /dev/null +++ b/emacs.d/wpc/casing.el @@ -0,0 +1,39 @@ +;; casing.el --- Helper functions for formatting text -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; These functions are intended to be bound to KBDs for daily use and +;; refactoring. + +;;; Code: + +(require 's) +(require 'dash) + +;; todo - grab the string at point and replace it with the output of +;; each fn + +(defun caps->kebab (x) + "Change the casing of X from CAP_CASE to kebab-case." + (->> x + s-downcase + (s-replace "_" "-"))) + +(defun kebab->caps (x) + "Change the casing of X from CAP_CASE to kebab-case." + (->> x + s-upcase + (s-replace "-" "_"))) + +;;; Tests: + +(ert-deftest caps->kebab-test () + (should (string= (caps->kebab "CAPS_CASE_STRING") + "caps-case-string"))) + +(ert-deftest kebab->caps-test () + (should (string= (kebab->caps "kebab-case-string") + "KEBAB_CASE_STRING"))) + +(provide 'casing) +;;; casing.el ends here diff --git a/emacs.d/wpc/functions.el b/emacs.d/wpc/functions.el new file mode 100644 index 000000000000..f2514a1bed85 --- /dev/null +++ b/emacs.d/wpc/functions.el @@ -0,0 +1,227 @@ +;; functions.el --- Helper functions for my Emacs development -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This file hopefully contains friendly APIs that making ELisp development more enjoyable. + +;;; Code: + +;; TODO: clean up this file so this isn't necessary +(setq evil-want-integration nil) +(require 'evil) + +(require 'projectile) +(require 'paredit) +(require 'term) +(require 'f) +(require 'yasnippet) +(require 'ido) + +(defun wpc/evil-window-vsplit-right () + (interactive) + (evil-window-vsplit) + (windmove-right)) + +(defun wpc/evil-window-split-down () + (interactive) + (evil-window-split) + (windmove-down)) + +(defun wpc/reindent-defun-and-align-clojure-map () + (interactive) + (call-interactively #'paredit-reindent-defun) + (call-interactively #'clojure-align)) + +(defun wpc/find-file () + "Prefer project-based file-finding if inside of project; otherwise gracefully fallback." + (interactive) + (with-current-buffer (current-buffer) + (if (projectile-project-p) + (call-interactively #'projectile-find-file) + (call-interactively #'find-file)))) + +(defun wpc/find-or-create-js-test () + (->> buffer-file-name + (s-chop-suffix ".js") + (s-append ".test.js") + (find-file))) + +(defun wpc/find-or-create-js-module () + (->> buffer-file-name + (s-chop-suffix ".test.js") + (s-append ".js") + (find-file))) + +(defun wpc/find-or-create-js-store () + (->> buffer-file-name + (s-replace "index.js" "store.js") + (find-file))) + +(defun wpc/find-or-create-js-component () + (->> buffer-file-name + (s-replace "store.js" "index.js") + (find-file))) + +(defun wpc/bind-ido-keys () + "Adds custom KBDs for ido. This function is recommended in the ido source code." + (define-key ido-completion-map (kbd "<tab>") #'ido-next-match) + (define-key ido-completion-map (kbd "<backtab>") #'ido-prev-match)) + +(defun wpc/toggle-between-js-test-and-module () + "Toggle between a Javascript test or module." + (interactive) + (if (s-ends-with? ".test.js" buffer-file-name) + (wpc/find-or-create-js-module) + (if (s-ends-with? ".js" buffer-file-name) + (wpc/find-or-create-js-test) + (message "Not in a Javascript file. Exiting...")))) + +(defun wpc/toggle-between-js-component-and-store () + "Toggle between a React component and its Redux store." + (interactive) + (if (s-ends-with? "index.js" buffer-file-name) + (wpc/find-or-create-js-store) + (if (or (s-ends-with? "store.js" buffer-file-name) + (s-ends-with? "store.test.js" buffer-file-name)) + (wpc/find-or-create-js-component) + (message "Not in a React/Redux file. Exiting...")))) + +(defun wpc/read-file-as-string (filename) + (with-temp-buffer + (insert-file-contents filename) + (s-trim (buffer-string)))) + +(defun wpc/create-snippet () + "Creates a window split and then opens the Yasnippet editor." + (interactive) + (evil-window-vsplit) + (call-interactively #'yas-new-snippet)) + +(defun wpc/edit-init-el () + "Creates a window split and then edits the init.el file." + (interactive) + (evil-window-vsplit) + (find-file "~/.emacs.d/init.el")) + +(defun wpc/set-flow-executable () + (interactive) + (let* ((root (locate-dominating-file buffer-file-name "node_modules/flow-bin")) + (executable (car (file-expand-wildcards + (concat root "node_modules/flow-bin/*osx*/flow"))))) + (setq-local company-flow-executable executable) + ;; These are not necessary for this package, but a good idea if you use + ;; these other packages + (setq-local flow-minor-default-binary executable) + (setq-local flycheck-javascript-flow-executable executable))) + +(defun wpc/jump-to-parent-file () + "Jumps to a React store or component's parent file. Useful for store or index file." + (interactive) + (-> buffer-file-name + f-dirname + (f-join "..") + (f-join (f-filename buffer-file-name)) + find-file)) + +(defun wpc/tmux-emacs-windmove (dir) + "Move windows in a Tmux-friendly way." + (let* ((dir->opts '((left . ("-L" . windmove-left)) + (right . ("-R" . windmove-right)) + (above . ("-U" . windmove-up)) + (below . ("-D" . windmove-down)))) + (opts (alist-get dir dir->opts)) + (tmux-opt (car opts)) + (emacs-fn (cdr opts))) + (if (window-in-direction dir) + (funcall emacs-fn) + (shell-command (format "tmux select-pane %s" tmux-opt))))) + +(defun wpc/tmux-emacs-windmove-left () + (interactive) + (wpc/tmux-emacs-windmove 'left)) + +(defun wpc/tmux-emacs-windmove-right () + (interactive) + (wpc/tmux-emacs-windmove 'right)) + +(defun wpc/tmux-emacs-windmove-up () + (interactive) + (wpc/tmux-emacs-windmove 'above)) + +(defun wpc/tmux-emacs-windmove-down () + (interactive) + (wpc/tmux-emacs-windmove 'below)) + +(defun wpc/get-window-by-buffername (buffername) + "Finds a window by the name of the buffer it's hosting." + (let ((buffer (get-buffer buffername))) + (when buffer + (get-buffer-window buffer)))) + +(defun wpc/add-earmuffs (x) + "Returns X surrounded by asterisks." + (format "*%s*" x)) + +(defun wpc/get-default-shell () + (or explicit-shell-file-name + (getenv "SHELL") + (getenv "ESHELL"))) + +(defun wpc/find-terminal-buffer () + (get-buffer (wpc/add-earmuffs wpc/terminal-name))) + +(defun wpc/find-terminal-window () + (wpc/get-window-by-buffername (wpc/add-earmuffs wpc/terminal-name))) + +(defun wpc/create-terminal-session () + (wpc/evil-window-vsplit-right) + (ansi-term (wpc/get-default-shell) wpc/terminal-name)) + +(defun wpc/toggle-terminal () + "Toggles a custom terminal session in Emacs." + (interactive) + (let ((window (wpc/find-terminal-window))) + (if window + (delete-window window) + (wpc/find-or-create-terminal)))) + +(defun wpc/find-or-create-terminal () + (let ((buffer (wpc/find-terminal-buffer))) + (if buffer + (display-buffer buffer) + (wpc/create-terminal-session)))) + +(defun wpc/put-file-name-on-clipboard () + "Put the current file name on the clipboard" + (interactive) + (let ((filename (if (equal major-mode 'dired-mode) + default-directory + (buffer-file-name)))) + (when filename + (with-temp-buffer + (insert filename) + (clipboard-kill-region (point-min) (point-max))) + (message filename)))) + +(defun wpc/evil-replace-under-point () + "Faster than typing %s//thing/g" + (interactive) + (save-excursion + (evil-ex (concat "%s/\\b" (symbol-name (symbol-at-point)) "\\b/")))) + +(defun wpc/disable-linum-mode () + "Convenience function defined to make adding hooks easier without a lambda." + (linum-mode -1)) + +(defun wpc/disable-company-mode () + "Convenience function defined to make adding hooks easier without a lambda." + (company-mode -1)) + +(defun wpc/toggle-term-mode () + "Toggle between term-line-mode and temr-char-mode." + (if (term-in-line-mode) + (term-char-mode) + (term-line-mode))) + +(provide 'functions) +;;; functions.el ends here diff --git a/emacs.d/wpc/macros.el b/emacs.d/wpc/macros.el new file mode 100644 index 000000000000..aedd6f5b3cb9 --- /dev/null +++ b/emacs.d/wpc/macros.el @@ -0,0 +1,33 @@ +;;; macros.el --- Helpful variables for making my ELisp life more enjoyable -*- lexical-binding: t -*- +;; Authpr: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This file contains helpful variables that I use in my ELisp development. + +;;; Code: + +(require 'dash) +(require 's) +(require 'string-functions) + +(defmacro xi (&rest FORMS) + `(lambda ,(--filter (s-contains? (symbol-name it) + (prin1-to-string FORMS)) + '(x1 x2 x3 x4 x5)) + ,FORMS)) + +(defmacro enable (mode) + "Helper for enabling MODE. Useful in `add-hook' calls." + `#'(lambda nil (,mode 1))) + +(defmacro disable (mode) + "Helper for disabling MODE. Useful in `add-hook' calls." + `#'(lambda nil (,mode -1))) + +(defmacro add-hooks (modes) + "Add multiple MODES for the CALLBACK." + `(dolist (mode ,modes) + (add-hook (symbol/ensure-hookified mode) ,callback))) + +(provide 'macros) +;;; macros.el ends here diff --git a/emacs.d/wpc/packages/wpc-clojure.el b/emacs.d/wpc/packages/wpc-clojure.el new file mode 100644 index 000000000000..3644f76a70e2 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-clojure.el @@ -0,0 +1,63 @@ +;;; clojure.el --- My Clojure preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosting my Clojure tooling preferences + +;;; Code: + +;; Helper functions +(defun wpc/buffer-name-for-clojure-mode (mode) + (let* ((project-name (projectile-project-name)) + (cljs-name (concat "*cider-repl CLJS " project-name "*")) + (clj-name (concat "*cider-repl " project-name "*"))) + (cond ((eq mode 'clojurescript-mode) cljs-name) + ((eq mode 'clojure-mode) clj-name) + ((eq mode 'clojurec-mode) cljs-name)))) + +(defun wpc/repl-function-for-clojure-mode (mode) + (let ((project-name (projectile-project-name)) + (cljs-fn #'cider-jack-in-clojurescript) + (clj-fn #'cider-jack-in)) + (cond ((eq mode 'clojurescript-mode) cljs-fn) + ((eq mode 'clojure-mode) clj-fn) + ((eq mode 'clojurec-mode) cljs-fn)))) + +(defun wpc/find-or-create-clojure-or-clojurescript-repl () + (interactive) + (with-current-buffer (current-buffer) + (let ((buffer-name (wpc/buffer-name-for-clojure-mode major-mode)) + (repl-function (wpc/repl-function-for-clojure-mode major-mode))) + (if (get-buffer buffer-name) + (switch-to-buffer buffer-name) + (funcall repl-function))))) + +;; (defun wpc/evil-leader/set-key-for-clojure-modes (kbd callback) +;; (evil-leader/set-key-for-mode 'clojure-mode kbd callback) +;; (evil-leader/set-key-for-mode 'clojurec-mode kbd callback) +;; (evil-leader/set-key-for-mode 'clojurescript-mode kbd callback)) + +;; ;; clojure +;; (wpc/evil-leader/set-key-for-clojure-modes "d" #'cider-doc) +;; (wpc/evil-leader/set-key-for-clojure-modes "e" #'cider-eval-defun-at-point) +;; (wpc/evil-leader/set-key-for-clojure-modes "r" #'wpc/find-or-create-clojure-or-clojurescript-repl) + +(use-package cider + :general + (cider-repl-mode-map + "C-l" 'cider-repl-clear-buffer + "C-u" 'kill-whole-line + "<up>" 'cider-repl-previous-input + "<down>" 'cider-repl-next-input + "C-c 'j" 'wpc/find-or-create-clojure-or-clojurescript-repl) + (n + "M-." 'cider-find-var) + :config + (setq cider-cljs-lein-repl + "(do (require 'figwheel-sidecar.repl-api) + (figwheel-sidecar.repl-api/start-figwheel!) + (figwheel-sidecar.repl-api/cljs-repl))" + cider-prompt-for-symbol nil)) + +(provide 'wpc-clojure) +;;; wpc-clojure.el ends here diff --git a/emacs.d/wpc/packages/wpc-company.el b/emacs.d/wpc/packages/wpc-company.el new file mode 100644 index 000000000000..ec96bdf90b3e --- /dev/null +++ b/emacs.d/wpc/packages/wpc-company.el @@ -0,0 +1,24 @@ +;;; company.el --- Autocompletion package, company, preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosts my company mode preferences + +;;; Code: + +;; autocompletion client +(use-package company + :general + (company-active-map + "C-j" 'company-select-next + "C-n" 'company-select-next + "C-k" 'company-select-previous + "C-p" 'company-select-previous + "C-d" 'company-show-doc-buffer) + :config + (setq company-idle-delay 0) + (setq company-minimum-prefix-length 2) + (global-company-mode)) + +(provide 'wpc-company) +;;; company.el ends here diff --git a/emacs.d/wpc/packages/wpc-dired.el b/emacs.d/wpc/packages/wpc-dired.el new file mode 100644 index 000000000000..1c45ec35e2b4 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-dired.el @@ -0,0 +1,18 @@ +;;; dired.el --- My dired preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosts my attempts at configuring dired + +;;; Code: + +(require 'dired) +(general-def 'dired-mode-map + "c" 'find-file + "f" 'wpc/find-file + "-" 'dired-up-directory) +(general-add-hook 'dired-mode-hook (list (enable dired-hide-details-mode) + #'auto-revert-mode)) + +(provide 'wpc-dired) +;;; dired.el ends here diff --git a/emacs.d/wpc/packages/wpc-docker.el b/emacs.d/wpc/packages/wpc-docker.el new file mode 100644 index 000000000000..586878fdeacd --- /dev/null +++ b/emacs.d/wpc/packages/wpc-docker.el @@ -0,0 +1,18 @@ +;;; docker.el --- Docker preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; My Docker preferences and configuration + +;;; Code: + +(use-package docker + :config + (setenv "DOCKER_TLS_VERIFY" "1") + (setenv "DOCKER_HOST" "tcp://10.11.12.13:2376") + (setenv "DOCKER_MACHINE_NAME" "name")) + +(use-package dockerfile-mode) + +(provide 'wpc-docker) +;;; docker.el ends here diff --git a/emacs.d/wpc/packages/wpc-flycheck.el b/emacs.d/wpc/packages/wpc-flycheck.el new file mode 100644 index 000000000000..66314af9877c --- /dev/null +++ b/emacs.d/wpc/packages/wpc-flycheck.el @@ -0,0 +1,14 @@ +;;; flycheck.el --- My flycheck configuration -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosts my Flycheck preferences + +;;; Code: + +(use-package flycheck + :config + (global-flycheck-mode)) + +(provide 'wpc-flycheck) +;;; flycheck.el ends here diff --git a/emacs.d/wpc/packages/wpc-git.el b/emacs.d/wpc/packages/wpc-git.el new file mode 100644 index 000000000000..f07040fffb64 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-git.el @@ -0,0 +1,17 @@ +;;; git.el --- My version control preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Things related to git, magit, etc belong here + +;;; Code: + +(use-package git-timemachine) + +(use-package magit) + +(use-package magit-gh-pulls + :ghook ('magit-mode-hook #'turn-on-magit-gh-pulls)) + +(provide 'wpc-git) +;;; git.el ends here diff --git a/emacs.d/wpc/packages/wpc-haskell.el b/emacs.d/wpc/packages/wpc-haskell.el new file mode 100644 index 000000000000..a37a84030f14 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-haskell.el @@ -0,0 +1,32 @@ +;;; haskell.el --- My Haskell preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosts my Haskell development preferences + +;;; Code: + +;; Haskell support +(use-package intero + :config + (intero-global-mode 1)) + +;; text objects for Haskell +(quelpa '(evil-text-objects-haskell + :fetcher github + :repo "urbint/evil-text-objects-haskell")) +(require 'evil-text-objects-haskell) + +(use-package haskell-mode + :gfhook #'evil-text-objects-haskell/install + :after (intero evil-text-objects-haskell) + :config + (flycheck-add-next-checker 'intero 'haskell-hlint) + (let ((m-symbols + '(("`mappend`" . "⊕") + ("<>" . "⊕")))) + (dolist (item m-symbols) (add-to-list 'haskell-font-lock-symbols-alist item))) + (setq haskell-font-lock-symbols t)) + +(provide 'wpc-haskell) +;;; haskell.el ends here diff --git a/emacs.d/wpc/packages/wpc-javascript.el b/emacs.d/wpc/packages/wpc-javascript.el new file mode 100644 index 000000000000..5dcd5937b11d --- /dev/null +++ b/emacs.d/wpc/packages/wpc-javascript.el @@ -0,0 +1,87 @@ +;;; javascript.el --- My Javascript preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This module hosts my Javascript tooling preferences + +;;; Code: + +;; Helper functions +(defun wpc/indium-setup (url) + "Setup the indium environment using URL." + (indium-eval (format "window.dispatchEvent(new CustomEvent('patch', {detail: {url: %s}}" url))) + +(defun wpc/insert-flow-annotation () + "Insert a flow type annotation to the beginning of a buffer." + (interactive) + (save-excursion + (goto-char (point-min)) + (insert "// @flow\n"))) + +;; ;; javascript +;; (evil-leader/set-key-for-mode 'rjsx-mode "t" #'wpc/toggle-between-js-test-and-module) +;; (evil-leader/set-key-for-mode 'rjsx-mode "x" #'wpc/toggle-between-js-component-and-store) +;; (evil-leader/set-key-for-mode 'rjsx-mode "u" #'wpc/jump-to-parent-file) + +;; javascript setup +(use-package indium + :hook (indium-update-script-source . wpc/indium-setup)) + +;; javascript text objects +(quelpa '(evil-text-objects-javascript + :fetcher github + :repo "urbint/evil-text-objects-javascript")) +(require 'evil-text-objects-javascript) + +;; Flow for Javascript +(use-package flow-minor-mode + :hook js2-mode + :requires evil-leader + :config + (evil-leader/set-key-for-mode 'rjsx-mode "F" #'wpc/insert-flow-annotation)) + +(use-package company-flow + :after (company) + :hook (rjsx-mode . wpc/set-flow-executable) + :config + (add-to-list 'company-flow-modes 'rjsx-mode) + (add-to-list 'company-backends 'company-flow)) + +(use-package flycheck-flow + :after (flycheck) + :config + (flycheck-add-mode 'javascript-flow 'rjsx-mode) + (flycheck-add-mode 'javascript-flow 'flow-minor-mode) + (flycheck-add-mode 'javascript-eslint 'flow-minor-mode) + (flycheck-add-next-checker 'javascript-flow 'javascript-eslint)) + +;; front-end indentation +(setq js-indent-level 2 + css-indent-offset 2) + +;; eslint integration with flycheck +(setq flycheck-javascript-eslint-executable "~/urbint/grid-front-end/node_modules/.bin/eslint") + +;; JS autoformatting +(use-package prettier-js + :after (rjsx-mode) + :ghook ('(rjsx-mode-hook + js2-mode-hook + json-mode-hook + css-mode-hook))) + +;; JSX highlighting +(use-package rjsx-mode + :after (evil-text-objects-javascript) + :general + (general-unbind rjsx-mode-map "<" ">" "C-d") + (n rjsx-mode-map + "K" 'flow-minor-type-at-pos) + :gfhook #'evil-text-objects-javascript/install + :mode "\\.js\\'" + :config + (setq js2-mode-show-parse-errors nil + js2-mode-show-strict-warnings nil)) + +(provide 'wpc-javascript) +;;; wpc-javascript.el ends here diff --git a/emacs.d/wpc/packages/wpc-keybindings.el b/emacs.d/wpc/packages/wpc-keybindings.el new file mode 100644 index 000000000000..0e74ce68bacb --- /dev/null +++ b/emacs.d/wpc/packages/wpc-keybindings.el @@ -0,0 +1,131 @@ +;;; keybindings.el --- My Evil preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This module hosts my Evil preferences + +;;; Code: + +(quelpa + '(general + :repo "noctuid/general.el" + :fetcher github)) +(general-evil-setup t) + +;; vim... +(use-package evil + :general + (m + "RET" 'evil-goto-line + "H" 'evil-first-non-blank + "L" 'evil-end-of-line + "-" 'dired-jump + "sl" 'wpc/evil-window-vsplit-right + "sh" 'evil-window-vsplit + "sk" 'evil-window-split + "sj" 'wpc/evil-window-split-down + "sj" 'wpc/evil-window-split-down) + (general-unbind m "M-." "C-p") + (general-unbind n "s" "M-.") + (general-unbind i "C-d" "C-a" "C-e" "C-n" "C-p" "C-k") + (evil-ex-map + "M-p" 'previous-complete-history-element + "M-n" 'next-complete-history-element) + :init + (setq evil-want-integration nil) + :config + (setq evil-symbol-word-search t) + (evil-mode 1)) + +;; evil keybindings +(use-package evil-collection + :after evil + :config + (evil-collection-init)) + +;; expose a leader key +(use-package evil-leader + :after (evil counsel) + :config + (global-evil-leader-mode) + (evil-leader/set-leader "<SPC>") + ;; global + (evil-leader/set-key + "i" #'counsel-semantic-or-imenu + "j" #'jump-to-register + "h" #'help + "a" #'wpc/toggle-terminal + "p" #'counsel-git-grep + "P" #'counsel-git-grep + "f" #'wpc/find-file + "N" #'smerge-next + "P" #'smerge-prev + "s" #'slack-send-code-snippet + "S" #'slack-select-unread-rooms + "b" #'ivy-switch-buffer + "gs" #'magit-status + "es" #'wpc/create-snippet + "ev" #'wpc/edit-init-el + "B" #'magit-blame + "w" #'save-buffer + "x" #'evil-save-and-close + "W" #'save-all-buffers + "r" #'wpc/evil-replace-under-point + )) + +;; create comments easily +(use-package evil-commentary + :after (evil) + :config + (evil-commentary-mode)) + +;; evil surround +(use-package evil-surround + :after (evil) + :config + (global-evil-surround-mode 1)) + +;; Custom minor mode that ensures that my kbds are available no matter which major +;; or minor modes are active. +(add-hook 'after-load-functions #'ensure-william-carroll-kbds) + +(defun ensure-william-carroll-kbds (_ignore) + "Try to ensure that my keybindings retain priority over other minor modes." + (unless (eq (caar minor-mode-map-alist) 'wpc/kbds-minor-mode) + (let ((mykbds (assq 'wpc/kbds-minor-mode minor-mode-map-alist))) + (assq-delete-all 'wpc/kbds-minor-mode minor-mode-map-alist) + (add-to-list 'minor-mode-map-alist mykbds)))) + +(defvar wpc/kbds + (let ((map (make-sparse-keymap))) + (bind-keys :map map + ("M-q" . delete-window) + ("C-x C-;" . comment-or-uncomment-region) + ("C-x h" . help) + ("<s-return>" . toggle-frame-fullscreen) + ("<down-mouse-1>" . ffap-other-window) + ("M-h" . wpc/tmux-emacs-windmove-left) + ("M-l" . wpc/tmux-emacs-windmove-right) + ("M-k" . wpc/tmux-emacs-windmove-up) + ("M-j" . wpc/tmux-emacs-windmove-down) + ("M--" . split-window-below) + ("M-\\" . split-window-right) + ("M-q" . delete-window)) + map) + "William Carroll's keybindings that should have the highest precedence.") + +(define-minor-mode wpc/kbds-minor-mode + "A minor mode so that my key settings override annoying major modes." + :init-value t + :lighter " wpc/kbds" + :keymap wpc/kbds) + +;; allow jk to escape +(use-package key-chord + :after (evil) + :config + (key-chord-mode 1) + (key-chord-define evil-insert-state-map "jk" 'evil-normal-state)) + +(provide 'wpc-keybindings) +;;; wpc-keybindings.el ends here diff --git a/emacs.d/wpc/packages/wpc-lisp.el b/emacs.d/wpc/packages/wpc-lisp.el new file mode 100644 index 000000000000..487201d47625 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-lisp.el @@ -0,0 +1,37 @@ +;;; lisp.el --- Generic LISP preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This hosts things like Paredit settings + +;;; Code: + +(defconst wpc/lisp-mode-hooks + '(emacs-lisp-mode-hook + clojure-mode-hook + clojurescript-mode-hook)) + +;; Elisp +(use-package elisp-slime-nav + :ghook + 'emacs-lisp-mode + 'ielm-mode) + +;; paredit LISP editing +(use-package paredit + :general + (general-unbind paredit-mode-map "C-j" "M-q") + (n paredit-mode-map + ">)" 'paredit-forward-slurp-sexp + "<(" 'paredit-backward-slurp-sexp + "<)" 'paredit-forward-barf-sexp + ">(" 'paredit-backward-barf-sexp + ">e" 'paredit-move-forward + "<e" 'paredit-move-backward + ">f" 'paredit-move-backward + "<f" 'paredit-move-backward + "go" 'paredit-raise-sexp) + :ghook (wpc/lisp-mode-hooks #'enable-paredit-mode)) + +(provide 'wpc-lisp) +;;; lisp.el ends here diff --git a/emacs.d/wpc/packages/wpc-misc.el b/emacs.d/wpc/packages/wpc-misc.el new file mode 100644 index 000000000000..d621f83d2101 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-misc.el @@ -0,0 +1,155 @@ +;;; misc.el --- Hosting miscellaneous configuration -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This is the home of any configuration that couldn't find a better home. + +;;; Code: + +;; disable custom variable entries from being written to ~/.emacs.d/init.el +(setq custom-file "~/.emacs.d/custom.el") +(load custom-file 'noerror) + +;; transparently edit compressed files +(auto-compression-mode t) + +;; change emacs prompts from "yes or no" -> "y or n" +(fset 'yes-or-no-p 'y-or-n-p) + +;; open photos in Emacs +(auto-image-file-mode 1) + +;; disable line-wrapping +(setq-default truncate-lines 1) + +;; shell file indentation +(setq sh-basic-offset 2) +(setq sh-indentation 2) + +;; create file bookmarks +(set-register ?e '(file . "~/.emacs.d/wpc/packages")) +(set-register ?u '(file . "~/urbint")) +(set-register ?d '(file . "~/dotfiles")) +(set-register ?D '(file . "~/Dropbox")) +(set-register ?o '(file . "~/Dropbox/org/")) +(set-register ?c '(file . "~/Dropbox/org/chains.org")) +(set-register ?b '(file . "~/Dropbox/org/backlog.org")) +(set-register ?p '(file . "~/urbint/grid-front-end")) + +;; persist history etc b/w Emacs sessions +(setq desktop-save 'if-exists) +(desktop-save-mode 1) +(setq desktop-globals-to-save + (append '((extended-command-history . 30) + (file-name-history . 100) + (grep-history . 30) + (compile-history . 30) + (minibuffer-history . 50) + (query-replace-history . 60) + (read-expression-history . 60) + (regexp-history . 60) + (regexp-search-ring . 20) + (search-ring . 20) + (shell-command-history . 50) + tags-file-name + register-alist))) + +;; config Emacs to use $PATH values +(use-package exec-path-from-shell + :if (memq window-system '(mac ns)) + :config + (exec-path-from-shell-initialize)) + +;; Emacs autosave, backup, interlocking files +(setq auto-save-default nil + make-backup-files nil + create-lockfiles nil) + +;; ensure code wraps at 80 characters by default +(setq fill-column 80) + +(put 'narrow-to-region 'disabled nil) + +;; trim whitespace on save +(add-hook 'before-save-hook #'delete-trailing-whitespace) + +;; use tabs instead of spaces +(setq-default indent-tabs-mode nil) + +;; automatically follow symlinks +(setq vc-follow-symlinks t) + +;; fullscreen settings +(setq ns-use-native-fullscreen nil) + +;; auto-close parens, brackets, quotes +(electric-pair-mode 1) + +(use-package oauth2 + :init + ;; necessary to remove warnings: https://emacs.stackexchange.com/questions/37036/where-are-these-variables-defined-bytecomp-warnings + (defvar url-http-extra-headers ()) + (defvar oauth--token-data ()) + (defvar url-callback-function ()) + (defvar url-callback-arguments ())) + +(use-package smex + :general + ("M-x" 'smex) + :ghook ('ido-setup-hook #'wpc/bind-ido-keys) + :config + (smex-initialize)) + +(use-package flx-ido + :after (smex) + :config + (flx-ido-mode 1) + (setq ido-enable-flex-matching t + ido-use-faces nil)) + +(use-package swiper + :general + ("C-s" 'swiper + "C-r" 'swiper)) + +(use-package yasnippet + :config + (yas-global-mode 1)) + +(use-package ace-window + :general + ("C-x o" 'ace-window) + :config + (setq aw-keys '(?a ?s ?d ?f ?j ?k ?k ?\;))) + +(use-package projectile + :config + (projectile-mode t)) + +(use-package counsel + :config + (defun wpc/counsel-git-grep () + (interactive) + (let ((maybe-symbol (wpc/string-symbol-at-point))) + (if (string= maybe-symbol "nil") + (counsel-git-grep) + (counsel-git-grep nil maybe-symbol))))) + +;; projectile intergration with ivy +(use-package counsel-projectile) + +;; search Google, Stackoverflow from within Emacs +(use-package engine-mode + :config + (defengine google + "http://www.google.com/search?ie=utf-8&oe=utf-8&q=%s" + :keybinding "g") + (defengine stack-overflow + "https://stackoverflow.com/search?q=%s" + :keybinding "s")) + +(use-package markdown-mode) +(use-package yaml-mode) + +(provide 'wpc-misc) +;;; misc.el ends here diff --git a/emacs.d/wpc/packages/wpc-org.el b/emacs.d/wpc/packages/wpc-org.el new file mode 100644 index 000000000000..28f1f9308dee --- /dev/null +++ b/emacs.d/wpc/packages/wpc-org.el @@ -0,0 +1,45 @@ +;;; org.el --- My org preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosts my org mode preferences + +;;; Code: + +;; Griffin's org clubhouse integration +;;(load-file "~/.emacs.d/vendor/org-clubhouse.el") +;;(setq org-clubhouse-auth-token (wpc/read-file-as-string "~/dotfiles/configs/secrets/clubhouse_token.txt") +;; org-clubhouse-team-name "urbint") +;;(add-hook 'org-mode-hook #'org-clubhouse-mode) + +(use-package org + :ghook (nil (disable linum-mode)) + :general + (:prefix "C-c" + "l" 'org-store-link + "a" 'org-agenda + "c" 'org-capture) + :preface + (defconst wpc-org-directory + "~/Dropbox/org") + (defconst ub-org-directory + "~/Dropbox/sprint-planning-staging") + (defun wpc/org-file (file) + (f-join wpc-org-directory (f-swap-ext file "org"))) + (defun ub/org-file (file) + (f-join ub-org-directory (f-swap-ext file "org"))) + :config + (setq org-default-notes-file (wpc/org-file "notes")) + (setq org-log-done 'time) + (setq org-agenda-files (list (wpc/org-file "work") + (wpc/org-file "personal"))) + (setq org-capture-templates + `(("t" "Todo" entry (file+heading ,(ub/org-file "index") "Ideas") + "* TODO %?\n %i")))) + +(use-package org-bullets + :after (org) + :ghook ('org-mode-hook (enable org-bullets-mode))) + +(provide 'wpc-org) +;;; org.el ends here diff --git a/emacs.d/wpc/packages/wpc-package.el b/emacs.d/wpc/packages/wpc-package.el new file mode 100644 index 000000000000..472f9df623a4 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-package.el @@ -0,0 +1,32 @@ +;;; package.el --- My package configuration -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This module hosts all of the settings required to work with ELPA, +;; MELPA, QUELPA, and co. + +;;; Code: + +(require 'package) +(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) +(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t) +(package-initialize) + +(if (require 'quelpa nil t) + (quelpa-self-upgrade) + (with-temp-buffer + (url-insert-file-contents "https://raw.github.com/quelpa/quelpa/master/bootstrap.el") + (eval-buffer))) + +(require 'use-package) +(setq use-package-always-ensure t) +;; Remove this line once general integration with use-package calls +;; with-eval-after-load 'use-package-core instead of 'use-package +(require 'general) + +(add-to-list 'load-path "~/.emacs.d/vendor/") +(add-to-list 'load-path "~/.emacs.d/wpc/") +(add-to-list 'load-path "~/.emacs.d/wpc/packages") + +(provide 'wpc-package) +;;; package.el ends here diff --git a/emacs.d/wpc/packages/wpc-slack.el b/emacs.d/wpc/packages/wpc-slack.el new file mode 100644 index 000000000000..912cd14572b4 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-slack.el @@ -0,0 +1,65 @@ +;;; slack.el --- Slack settings -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Wrangling the Slack client in Emacs + +;;; Code: + +;; Griffin's Slack plugin +;;(defconst slack/token (wpc/read-file-as-string "~/dotfiles/configs/secrets/slack_token.txt")) +;;(defconst wpc/slack-client-secret (wpc/read-file-as-string "~/dotfiles/configs/secrets/slack-client-secret")) +(defconst wpc/slack-client-secret "uncomment above line one day") +(load-file "~/.emacs.d/vendor/slack-snippets.el") + +;; Slack client +(use-package slack + :general + (n slack-info-mode-map + :prefix "," + "u" 'slack-room-update-messages) + (n slack-mode-map + :prefix "," + "c" 'slack-buffer-kill + "ra" 'slack-message-add-reaction + "rr" 'slack-message-remove-reaction + "rs" 'slack-message-show-reaction-users + "pl" 'slack-room-pins-list + "pa" 'slack-message-pins-add + "pr" 'slack-message-pins-remove + "mm" 'slack-message-write-another-buffer + "me" 'slack-message-edit + "md" 'slack-message-delete + "u" 'slack-room-update-messages + "2" 'slack-message-embed-mention + "3" 'slack-message-embed-channel) + (n slack-mode-map + "C-n" 'slack-buffer-goto-next-message + "C-p" 'slack-buffer-goto-prev-message) + (n slack-edit-message-mode-map + :prefix "," + "k" 'slack-message-cancel-edit + "s" 'slack-message-send-from-buffer + "2" 'slack-message-embed-mention + "3" 'slack-message-embed-channel) + :commands (slack-start) + :init + (setq slack-buffer-emojify t) ;; if you want to enable emoji, default nil + (setq slack-prefer-current-team t) + :config + (add-hook 'slack-mode-hook (disable company-mode)) + (setq slack-buffer-function #'switch-to-buffer) + (slack-register-team + :name "urbint" + :default t + :client-id "william@urbint.com" + :client-secret wpc/slack-client-secret + :token slack-token + :subscribed-channels '(dev dev_questions general random recruiting) + :full-and-display-names t)) + +(use-package circe) +(use-package emojify) + +(provide 'wpc-slack) +;;; wpc-slack.el ends here diff --git a/emacs.d/wpc/packages/wpc-terminal.el b/emacs.d/wpc/packages/wpc-terminal.el new file mode 100644 index 000000000000..36a24bbb3c46 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-terminal.el @@ -0,0 +1,19 @@ +;;; terminal.el --- My cobbled together terminal -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; My attempts at creating a sane Emacs terminal + +;;; Code: + +(setq wpc/terminal-name "wpc/terminal") + +;; 256 color support in term (instead of 8) +(use-package xterm-color) + +(use-package term + :config + (setq explicit-shell-file-name "/bin/zsh")) + +(provide 'wpc-terminal) +;;; terminal.el ends here diff --git a/emacs.d/wpc/packages/wpc-ui.el b/emacs.d/wpc/packages/wpc-ui.el new file mode 100644 index 000000000000..fff2db3e1160 --- /dev/null +++ b/emacs.d/wpc/packages/wpc-ui.el @@ -0,0 +1,136 @@ +;;; ui.el --- Any related to the UI/UX goes here -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Hosts font settings, scrolling, color schemes. + +;;; Code: + +;; increase line height +(setq-default line-spacing 4) + +;; change font +(add-to-list 'default-frame-alist '(font . "Operator Mono-10")) + +;; smooth scrolling settings +(setq scroll-step 1 + scroll-conservatively 10000) + +;; theme mgt +(use-package cycle-themes + :after (doom-themes) + :config + ;; NOTE: may want to use `defconst' here + (setq wpc/doom-themes + (->> (custom-available-themes) + (-map #'symbol-name) + (-filter (-partial #'s-starts-with? "doom-")) + (-map #'intern))) + (setq cycle-themes-theme-list wpc/doom-themes)) + +;; clean up modeline +(use-package diminish + :after (yasnippet ivy which-key) + :config + (diminish 'evil-commentary-mode) + (diminish 'flycheck-mode "Flycheck") + (diminish 'company-mode "Company") + (diminish 'auto-revert-mode) + (diminish 'which-key-mode) + (diminish 'yas-minor-mode) + (diminish 'ivy-mode)) + +;; disable startup screen +(setq inhibit-startup-screen t) + +;; disable toolbar +(tool-bar-mode -1) + +;; enable line numbers +(general-add-hook '(prog-mode-hook + text-mode-hook + conf-mode-hook) + (enable linum-mode)) +;;(add-hook 'after-init-hook (lambda () (set-face-foreground 'linum "#da5468"))) + +;; set default buffer for Emacs +(setq initial-buffer-choice "~/urbint/grid-front-end") + +;; transparent Emacs +(set-frame-parameter (selected-frame) 'alpha '(100 . 100)) +(add-to-list 'default-frame-alist '(alpha . (100 . 100))) + +;; premium Emacs themes +(use-package doom-themes + :config + (setq doom-themes-enable-bold t + doom-themes-enable-italic t) + (load-theme 'doom-solarized-light t) + (doom-themes-visual-bell-config) + (doom-themes-org-config)) + +;; kbd discovery +(use-package which-key + :config + (setq which-key-idle-delay 0.25) + (which-key-mode)) + +;; completion framework +(use-package ivy + :config + (ivy-mode t)) + +;; icons for Ivy +(use-package all-the-icons-ivy + :after (ivy) + :config + (all-the-icons-ivy-setup)) + +;; disable menubar +(menu-bar-mode -1) +(when (string-equal system-type "darwin") + (setq ns-auto-hide-menu-bar t)) + +;; highlight lines that are over 100 characters long +(use-package whitespace + :config + (setq whitespace-line-column 100) + (setq whitespace-style '(face lines-tail))) + +;; disable GUI scrollbars +(when (display-graphic-p) + (scroll-bar-mode -1)) + +;; rebalance emacs windows after splits are created +(defadvice split-window-below (after rebalance-windows activate) + (balance-windows)) + +(defadvice split-window-right (after rebalance-windows activate) + (balance-windows)) + +(defadvice delete-window (after rebalance-window activate) + (balance-windows)) + +;; dirname/filename instead of filename<dirname> +(setq uniquify-buffer-name-style 'forward) + +;; highlight matching parens, brackets, etc +(show-paren-mode 1) + +;; GUI alerts in emacs +(use-package alert + :commands (alert) + :config + (setq alert-default-style 'notifier)) + +;; focus mode +(quelpa '(zen-mode + :fetcher github + :repo "aki237/zen-mode")) +(require 'zen-mode) + +;; focus mode +(use-package writeroom-mode) + +(provide 'wpc-ui) +;;; ui.el ends here diff --git a/emacs.d/wpc/string-functions.el b/emacs.d/wpc/string-functions.el new file mode 100644 index 000000000000..91b46b5b409e --- /dev/null +++ b/emacs.d/wpc/string-functions.el @@ -0,0 +1,41 @@ +;; functions.el --- String helper functions for my Emacs development -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; String & Symbol helpers! + +;;; Code: + +(require 'dash) +(require 's) + +;; Strings +(defun string/hookify (x) + "Append \"-hook\" to X." + (s-append "-hook" x)) + +(defun string/ensure-hookified (x) + "Ensure that X has \"-hook\" appended to it." + (if (s-ends-with? "-hook" x) + x + (string/hookify x))) + +;; Symbols +(defun symbol/as-string (callback x) + "Treat the symbol, X, as a string while applying CALLBACK to it. +Coerce back to a symbol on the way out." + (->> x + symbol-name + callback + intern)) + +(defun symbol/hookify (x) + "Append \"-hook\" to X when X is a symbol." + (symbol/as-string #'string/hookify x)) + +(defun symbol/ensure-hookified (x) + "Ensure that X has \"-hook\" appended to it when X is a symbol." + (symbol/as-string #'string/ensure-hookified x)) + +(provide 'string-functions) +;;; string-functions.el ends here diff --git a/emacs.d/wpc/variables.el b/emacs.d/wpc/variables.el new file mode 100644 index 000000000000..af6bfde45a41 --- /dev/null +++ b/emacs.d/wpc/variables.el @@ -0,0 +1,18 @@ +;;; variables.el --- Helpful variables for making my ELisp life more enjoyable -*- lexical-binding: t -*- +;; Authpr: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This file contains helpful variables that I use in my ELisp development. + +;;; Code: + +(defvar wpc/mouse-kbds + '([mouse-1] [down-mouse-1] [drag-mouse-1] [double-mouse-1] [triple-mouse-1] + [mouse-2] [down-mouse-2] [drag-mouse-2] [double-mouse-2] [triple-mouse-2] + [mouse-3] [down-mouse-3] [drag-mouse-3] [double-mouse-3] [triple-mouse-3] + [mouse-4] [down-mouse-4] [drag-mouse-4] [double-mouse-4] [triple-mouse-4] + [mouse-5] [down-mouse-5] [drag-mouse-5] [double-mouse-5] [triple-mouse-5]) + "This variable stores all of the mouse-related keybindings that Emacs recognizes.") + +(provide 'variables) +;;; variables.el ends here |