From 6b456c1b7a4f6899f063a6e65355af51901d9c7a Mon Sep 17 00:00:00 2001 From: William Carroll Date: Wed, 9 Oct 2019 12:13:56 +0100 Subject: Massive configuration overhaul Currently paying the price of months of non-diligent git usage. Here's what has changed. - Theming support in Gvcci and wpgtk - Dropping support for i3 - Supporting EXWM - Many Elisp modules - Collapsed redundant directories in ./configs --- .../shared/.emacs.d/wpc/packages/wpc-clojure.el | 85 +++++++++ .../shared/.emacs.d/wpc/packages/wpc-company.el | 28 +++ configs/shared/.emacs.d/wpc/packages/wpc-dired.el | 39 ++++ configs/shared/.emacs.d/wpc/packages/wpc-docker.el | 16 ++ configs/shared/.emacs.d/wpc/packages/wpc-elixir.el | 13 ++ .../shared/.emacs.d/wpc/packages/wpc-flycheck.el | 14 ++ .../shared/.emacs.d/wpc/packages/wpc-haskell.el | 56 ++++++ configs/shared/.emacs.d/wpc/packages/wpc-java.el | 42 +++++ .../shared/.emacs.d/wpc/packages/wpc-javascript.el | 61 ++++++ .../.emacs.d/wpc/packages/wpc-keybindings.el | 206 ++++++++++++++++++++ configs/shared/.emacs.d/wpc/packages/wpc-lisp.el | 114 +++++++++++ configs/shared/.emacs.d/wpc/packages/wpc-misc.el | 209 +++++++++++++++++++++ configs/shared/.emacs.d/wpc/packages/wpc-nix.el | 12 ++ configs/shared/.emacs.d/wpc/packages/wpc-ocaml.el | 51 +++++ configs/shared/.emacs.d/wpc/packages/wpc-org.el | 78 ++++++++ .../shared/.emacs.d/wpc/packages/wpc-package.el | 27 +++ configs/shared/.emacs.d/wpc/packages/wpc-python.el | 17 ++ .../shared/.emacs.d/wpc/packages/wpc-reasonml.el | 29 +++ configs/shared/.emacs.d/wpc/packages/wpc-rust.el | 34 ++++ configs/shared/.emacs.d/wpc/packages/wpc-shell.el | 15 ++ .../shared/.emacs.d/wpc/packages/wpc-terminal.el | 70 +++++++ configs/shared/.emacs.d/wpc/packages/wpc-ui.el | 185 ++++++++++++++++++ 22 files changed, 1401 insertions(+) create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-clojure.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-company.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-dired.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-docker.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-elixir.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-flycheck.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-haskell.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-java.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-javascript.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-keybindings.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-lisp.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-misc.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-nix.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-ocaml.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-org.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-package.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-python.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-reasonml.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-rust.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-shell.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-terminal.el create mode 100644 configs/shared/.emacs.d/wpc/packages/wpc-ui.el (limited to 'configs/shared/.emacs.d/wpc/packages') diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-clojure.el b/configs/shared/.emacs.d/wpc/packages/wpc-clojure.el new file mode 100644 index 000000000000..d9262cdda8eb --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-clojure.el @@ -0,0 +1,85 @@ +;;; clojure.el --- My Clojure preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; 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))))) + +(use-package clojure-mode + :config + ;; from Ryan Schmukler: + (setq cljr-magic-require-namespaces + '(("io" . "clojure.java.io") + ("sh" . "clojure.java.shell") + ("jdbc" . "clojure.java.jdbc") + ("set" . "clojure.set") + ("time" . "java-time") + ("str" . "cuerdas.core") + ("path" . "pathetic.core") + ("walk" . "clojure.walk") + ("zip" . "clojure.zip") + ("async" . "clojure.core.async") + ("component" . "com.stuartsierra.component") + ("http" . "clj-http.client") + ("url" . "cemerick.url") + ("sql" . "honeysql.core") + ("csv" . "clojure.data.csv") + ("json" . "cheshire.core") + ("s" . "clojure.spec.alpha") + ("fs" . "me.raynes.fs") + ("ig" . "integrant.core") + ("cp" . "com.climate.claypoole") + ("re-frame" . "re-frame.core") + ("rf" . "re-frame.core") + ("re" . "reagent.core") + ("reagent" . "reagent.core") + ("u.core" . "utopia.core") + ("gen" . "clojure.spec.gen.alpha")))) + +(use-package cider + :config + (general-define-key + :keymaps 'cider-repl-mode-map + "C-l" #'cider-repl-clear-buffer + "C-u" #'kill-whole-line + "" #'cider-repl-previous-input + "" #'cider-repl-next-input + ;; "C-c 'j" #'wpc/find-or-create-clojure-or-clojurescript-repl + ) + ;; (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/configs/shared/.emacs.d/wpc/packages/wpc-company.el b/configs/shared/.emacs.d/wpc/packages/wpc-company.el new file mode 100644 index 000000000000..1152f496c2b7 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-company.el @@ -0,0 +1,28 @@ +;;; company.el --- Autocompletion package, company, preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Hosts my company mode preferences + +;;; Code: + +;; autocompletion client +(use-package company + :config + (general-define-key + :keymaps '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) + (setq company-tooltip-align-annotations t) + (setq company-idle-delay 0) + (setq company-show-numbers t) + (setq company-minimum-prefix-length 2) + (setq company-dabbrev-downcase nil + company-dabbrev-ignore-case t) + (global-company-mode)) + +(provide 'wpc-company) +;;; wpc-company.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-dired.el b/configs/shared/.emacs.d/wpc/packages/wpc-dired.el new file mode 100644 index 000000000000..13aed975d2a5 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-dired.el @@ -0,0 +1,39 @@ +;;; dired.el --- My dired preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; File management in Emacs, if learned and configured properly, should be +;; capable to reduce my dependency on the terminal. + +;;; Code: + +;; TODO: Ensure sorting in dired is by type. + +;; TODO: Rename wpc-dired.el to file-management.el + +(progn + (require 'dired) + (setq dired-recursive-copies 'always + dired-recursive-deletes 'top + dired-dwim-target t) + (general-define-key + :keymaps 'dired-mode-map + :states 'normal + "s" nil + "q" (lambda () (interactive) (kill-buffer nil)) + "c" #'find-file + "f" #'wpc/find-file + "-" (lambda () (interactive) (find-alternate-file ".."))) + (general-add-hook 'dired-mode-hook + (list (enable dired-hide-details-mode) + #'auto-revert-mode))) + +(progn + (require 'locate) + (general-define-key + :keymaps 'locate-mode-map + :states 'normal + "o" #'dired-display-file)) + +(provide 'wpc-dired) +;;; wpc-dired.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-docker.el b/configs/shared/.emacs.d/wpc/packages/wpc-docker.el new file mode 100644 index 000000000000..270eaec6fe4c --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-docker.el @@ -0,0 +1,16 @@ +;;; docker.el --- Docker preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; 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")) + +(provide 'wpc-docker) +;;; wpc-docker.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-elixir.el b/configs/shared/.emacs.d/wpc/packages/wpc-elixir.el new file mode 100644 index 000000000000..e64abe70fc36 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-elixir.el @@ -0,0 +1,13 @@ +;;; wpc-elixir.el --- Elixir / Erland configuration -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; My preferences for working with Elixir / Erlang projects + +;;; Code: +(use-package elixir-mode + :config + (add-hook-before-save 'elixir-mode-hook #'elixir-format)) + +(provide 'wpc-elixir) +;;; wpc-elixir.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-flycheck.el b/configs/shared/.emacs.d/wpc/packages/wpc-flycheck.el new file mode 100644 index 000000000000..d7bb834a6257 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-flycheck.el @@ -0,0 +1,14 @@ +;;; flycheck.el --- My flycheck configuration -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Hosts my Flycheck preferences + +;;; Code: + +(use-package flycheck + :config + (global-flycheck-mode)) + +(provide 'wpc-flycheck) +;;; wpc-flycheck.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-haskell.el b/configs/shared/.emacs.d/wpc/packages/wpc-haskell.el new file mode 100644 index 000000000000..e8ab16e585b7 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-haskell.el @@ -0,0 +1,56 @@ +;;; haskell.el --- My Haskell preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Hosts my Haskell development preferences + +;;; Code: + +;; Haskell support + +;; font-locking, glyph support, etc +(use-package haskell-mode + :config + (let ((m-symbols + '(("`mappend`" . "⊕") + ("<>" . "⊕")))) + (dolist (item m-symbols) (add-to-list 'haskell-font-lock-symbols-alist item))) + (setq haskell-font-lock-symbols t) + (add-hook-before-save 'haskell-mode #'haskell-align-imports)) + +;; LSP support +(use-package lsp-haskell + :after (haskell-mode) + :config + (setq lsp-haskell-process-path-hie "hie-wrapper") + (add-hook 'haskell-mode-hook #'lsp-haskell-enable) + (add-hook 'haskell-mode-hook #'flycheck-mode)) + +;; Test toggling +(defun haskell/module->test () + "Jump from a module to a test." + (let ((filename (->> buffer-file-name + (s-replace "/src/" "/test/") + (s-replace ".hs" "Test.hs") + find-file))) + (make-directory (f-dirname filename) t) + (find-file filename))) + +(defun haskell/test->module () + "Jump from a test to a module." + (let ((filename (->> buffer-file-name + (s-replace "/test/" "/src/") + (s-replace "Test.hs" ".hs") + ))) + (make-directory (f-dirname filename) t) + (find-file filename))) + +(defun haskell/test<->module () + "Toggle between test and module in Haskell." + (interactive) + (if (s-contains? "/src/" buffer-file-name) + (haskell/module->test) + (haskell/test->module))) + +(provide 'wpc-haskell) +;;; wpc-haskell.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-java.el b/configs/shared/.emacs.d/wpc/packages/wpc-java.el new file mode 100644 index 000000000000..4f33ba962e5d --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-java.el @@ -0,0 +1,42 @@ +;;; wpc-java.el --- Java configuration -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; When life gets you down, and you find yourself writing Java, remember: at +;; least you're using Emacs. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dependencies +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'prelude) +(require 'macros) + +(prelude/assert + (prelude/executable-exists? "google-java-format")) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; TODO: Troubleshoot why this isn't running. +(add-hook-before-save + 'java-mode-hook + (lambda () + (call-interactively + #'google-java-format))) + +(add-hook 'java-mode-hook + (lambda () + (setq c-basic-offset 2 + tab-width 2))) + +;; TODO: Figure out whether I should use this or google-emacs. +;; (use-package lsp-java +;; :config +;; (add-hook 'java-mode-hook #'lsp)) + +(provide 'wpc-java) +;;; wpc-java.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-javascript.el b/configs/shared/.emacs.d/wpc/packages/wpc-javascript.el new file mode 100644 index 000000000000..b55e03e00c07 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-javascript.el @@ -0,0 +1,61 @@ +;; wpc-javascript.el --- My Javascript preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; This module hosts my Javascript tooling preferences +;; +;; Depends +;; - yarn global add prettier + +;;; Code: + +;; Constants +(defconst wpc/js-hooks + '(js-mode-hook js2-mode-hook rjsx-mode-hook) + "All of the commonly used hooks for Javascript buffers.") + +(defconst wpc/frontend-hooks + (-insert-at 0 'css-mode-hook wpc/js-hooks) + "All of the commonly user hooks for frontend development.") + + +;; frontend indentation settings +(setq js-indent-level 2 + css-indent-offset 2) + +;; ;; 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) + +;; Flow for Javascript +(use-package add-node-modules-path + :config + (general-add-hook wpc/js-hooks #'add-node-modules-path)) + +(use-package web-mode + :mode "\\.html\\'" + :config + (setq web-mode-css-indent-offset 2) + (setq web-mode-code-indent-offset 2) + (setq web-mode-markup-indent-offset 2)) + +;; JSX highlighting +(use-package rjsx-mode + :mode "\\.js\\'" + :config + (general-unbind rjsx-mode-map "<" ">" "C-d") + (general-nmap + :keymaps 'rjsx-mode-map + "K" #'flow-minor-type-at-pos) + (setq js2-mode-show-parse-errors nil + js2-mode-show-strict-warnings nil)) + +;; JS autoformatting +(use-package prettier-js + :after (rjsx-mode) + :config + (general-add-hook wpc/frontend-hooks #'prettier-js-mode)) + +(provide 'wpc-javascript) +;;; wpc-javascript.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-keybindings.el b/configs/shared/.emacs.d/wpc/packages/wpc-keybindings.el new file mode 100644 index 000000000000..fb9c78f0e765 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-keybindings.el @@ -0,0 +1,206 @@ +;;; keybindings.el --- My Evil preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; This module hosts my Evil preferences +;; +;; Wish List: +;; - drop support for `evil-leader' library in favor of `general.el' +;; - restore support for concise (n ) instead of `general-mmap' +;; - restore support for `general-unbind' + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Packages +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; This may be contraversial, but I never use the prefix key, and I'd prefer to +;; have to bound to the readline function that deletes the entire line. +(general-unbind "C-u") + +(use-package evil + :init + ;; Should remove the warning messages on init. + (setq evil-want-integration t) + ;; TODO: Troubleshoot why this binding causes the following warning: + ;; "Warning (evil-collection): `evil-want-keybinding' was set to nil but not + ;; before loading evil." + (setq evil-want-keybinding nil) + (general-evil-setup) + :config + ;; Ensure that evil's command mode behaves with readline bindings. + (general-define-key + :keymaps 'evil-ex-completion-map + "C-a" #'move-beginning-of-line + "C-e" #'move-end-of-line + "C-k" #'kill-line + "C-u" #'evil-delete-whole-line + "C-v" #'evil-paste-after + "C-d" #'delete-char + "C-f" #'forward-char + "M-b" #'backward-word + "M-f" #'forward-word + "M-d" #'kill-word + "M-DEL" #'backward-kill-word + "C-b" #'backward-char) + ;; TODO: Ensure all of my custom keybindings end up in a single map that is + ;; easy to enable or disable. + (general-mmap + :keymaps 'override + "RET" #'evil-goto-line + "H" #'evil-first-non-blank + "L" #'evil-end-of-line + "_" #'ranger + "-" #'dired-jump + "sl" #'wpc/evil-window-vsplit-right + "sh" #'evil-window-vsplit + "sk" #'evil-window-split + "sj" #'wpc/evil-window-split-down) + (general-nmap + :keymaps 'override + "gd" #'xref-find-definitions + ;; Wrapping `xref-find-references' in the `let' binding to prevent xref from + ;; prompting. There are other ways to handle this variable, such as setting + ;; it globally with `setq' or buffer-locally with `setq-local'. For now, I + ;; prefer setting it with `let', which should bind it in the dynamic scope + ;; for the duration of the `xref-find-references' function call. + "gx" (lambda () + (interactive) + (let ((xref-prompt-for-identifier nil)) + (call-interactively #'xref-find-references)))) + (general-unbind 'motion "M-." "C-p") + (general-unbind 'normal "s" "M-." "C-p" "C-n") + (general-unbind 'insert "C-v" "C-d" "C-a" "C-e" "C-n" "C-p" "C-k") + (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) + :config + (global-evil-leader-mode 1) + (evil-leader/set-leader "") + (evil-leader/set-key + "i" #'counsel-semantic-or-imenu + "I" #'ibuffer + "hk" #'helpful-callable + "hf" #'helpful-function + "hm" #'helpful-macro + "hc" #'helpful-command + "hk" #'helpful-key + "hv" #'helpful-variable + "hp" #'helpful-at-point + "s" #'flyspell-mode + "S" #'sort-lines + "a" #'wpc-terminal/toggle + "=" #'align + "p" #'flycheck-previous-error + "f" #'wpc/find-file + "n" #'flycheck-next-error + "N" #'smerge-next + "b" #'ivy-switch-buffer + "W" #'balance-windows + "gs" #'magit-status + + "es" #'wpc/create-snippet + ;; TODO: Replace with `macros/ilambda' when that is working again. + "ev" (lambda () (interactive) (wpc/find-file-split "~/.config/nvim/init.vim")) + "ee" (lambda () (interactive) (wpc/find-file-split "~/.emacs.d/init.el")) + "ez" (lambda () (interactive) (wpc/find-file-split "~/.zshrc")) + "ea" (lambda () (interactive) (wpc/find-file-split "~/aliases.zsh")) + "ef" (lambda () (interactive) (wpc/find-file-split "~/functions.zsh")) + "el" (lambda () (interactive) (wpc/find-file-split "~/variables.zsh")) + "ex" (lambda () (interactive) (wpc/find-file-split "~/.Xresources")) + "ei" (lambda () (interactive) (wpc/find-file-split "~/.config/i3/config.shared")) + "em" (lambda () (interactive) (wpc/find-file-split "~/.tmux.conf")) + + "l" #'locate + "L" #'list-packages + "B" #'magit-blame + "w" #'save-buffer + "r" #'wpc/evil-replace-under-point + "R" #'deadgrep)) + +;; 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)) + +;; I expect in insert mode: +;; C-a: beginning-of-line +;; C-e: end-of-line +;; C-b: backwards-char +;; C-f: forwards-char + +;; TODO: Move these KBD constants to kbd.el. + +(defconst wpc/up-kbds + '("C-p" "C-k" "" "") + "The keybindings that I expect to work for moving upwards in lists.") + +(defconst wpc/down-kbds + '("C-n" "C-j" "" "") + "The keybindings that I expect to work for moving downwards in lists.") + +(defconst wpc/left-kbds + '("C-b" "") + "The keybindings that I expect to move leftwards in insert-like modes.") + +(defconst wpc/right-kbds + '("C-f" "") + "The keybindings that I expect to move rightwards in insert-like modes.") + +(defun wpc/ensure-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)))) + +;; Custom minor mode that ensures that my kbds are available no matter which +;; major or minor modes are active. +(add-hook 'after-load-functions #'wpc/ensure-kbds) + +;; TODO: Prefer using general and 'override maps to implement this. +(defvar wpc/kbds + (let ((map (make-sparse-keymap))) + (bind-keys :map map + ("M-q" . delete-window) + ("" . toggle-frame-fullscreen) + ("M-h" . windmove-left) + ("M-l" . windmove-right) + ("M-k" . windmove-up) + ("M-j" . windmove-down) + ("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/configs/shared/.emacs.d/wpc/packages/wpc-lisp.el b/configs/shared/.emacs.d/wpc/packages/wpc-lisp.el new file mode 100644 index 000000000000..553dff1acbd9 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-lisp.el @@ -0,0 +1,114 @@ +;;; lisp.el --- Generic LISP preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;; parent (up) +;; child (down) +;; prev-sibling (left) +;; next-sibling (right) + +;;; Code: + +(defconst wpc/lisp-mode-hooks + '(lisp-mode-hook + emacs-lisp-mode-hook + clojure-mode-hook + clojurescript-mode-hook + racket-mode-hook) + "List of LISP modes.") + +(use-package racket-mode + :config + (general-define-key + :keymaps 'racket-mode-map + :states 'normal + :prefix "" + "x" #'racket-send-definition) + (general-define-key + :keymaps 'racket-mode-map + :states 'normal + :prefix "" + "X" #'racket-run) + (general-define-key + :keymaps 'racket-mode-map + :states 'normal + :prefix "" + "d" #'racket-describe) + (setq racket-program "~/.nix-profile/bin/racket")) + +(use-package lispyville + :init + (defconst lispyville-key-themes + '(c-w + operators + text-objects + ;; Disabling this because I don't enjoy the way it moves around comments. + ;; atom-motions + prettify + commentary + slurp/barf-cp + wrap + additional + additional-insert + additional-wrap + escape) + "All available key-themes in Lispyville.") + :config + (general-add-hook wpc/lisp-mode-hooks #'lispyville-mode) + (lispyville-set-key-theme lispyville-key-themes) + (progn + ;; + (general-define-key + :keymaps 'lispyville-mode-map + :states 'motion + ;; first unbind + "M-h" nil + "M-l" nil) + (general-define-key + :keymaps 'lispyville-mode-map + :states 'normal + ;; first unbind + "M-j" nil + "M-k" nil + ;; second rebind + ;; TODO: Rebind to something that doesn't conflict with window resizing. + ;; "C-M-h" #'lispyville-drag-backward + ;; "C-M-l" #'lispyville-drag-forward + ))) + +;; deletes all bindings of f->kbd +;; binds kbd-> +;; (kbd/bind-function->key +;; :keymap 'lispyville-mode-map +;; :states 'motion +;; #'lispyville-drag-backward "H") + +;; Elisp +(use-package elisp-slime-nav + :config + (general-add-hook 'emacs-lisp-mode #'ielm-mode)) + +;; TODO: Should I be using `general-define-key' or `evil-leader/set-key'? My +;; gut say `general-define-key'. +(general-define-key + :keymaps 'emacs-lisp-mode-map + :states 'normal + :prefix "" + "x" #'eval-defun) + +(general-define-key + :keymaps 'emacs-lisp-mode-map + :states 'normal + :prefix "" + "X" #'eval-buffer) + +(general-define-key + :keymaps 'emacs-lisp-mode-map + :states 'normal + :prefix "" + "d" (lambda () + (interactive) + (with-current-buffer (current-buffer) + (helpful-function (symbol-at-point))))) + +(provide 'wpc-lisp) +;;; wpc-lisp.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-misc.el b/configs/shared/.emacs.d/wpc/packages/wpc-misc.el new file mode 100644 index 000000000000..3ddfe0b3e49b --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-misc.el @@ -0,0 +1,209 @@ +;;; misc.el --- Hosting miscellaneous configuration -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; This is the home of any configuration that couldn't find a better home. + +;;; Code: + +;; Display time in the modeline +;; TODO: Save preferred date format strings and cycle through them since I waver +;; about which is my favorite. +(setq display-time-format "%R %a %d %b [%U of 52 weeks]") +(display-time-mode 1) + +;; disable custom variable entries from being written to ~/.emacs.d/init.el +(setq custom-file "~/.emacs.d/custom.el") +(load custom-file 'noerror) + +;; integrate Emacs with X11 clipboard +(setq select-enable-primary t) +(setq select-enable-clipboard t) +(general-def 'insert + "s-v" #'clipboard-yank + "C-S-v" #'clipboard-yank) + +;; transparently edit compressed files +(auto-compression-mode t) + +;; autowrap when over the fill-column +(setq-default auto-fill-function #'do-auto-fill) + +;; link to Emacs source code +;; TODO: Update this link. +(setq find-function-C-source-directory + "~/Dropbox/programming/emacs/src") + +;; 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) + +;; disable company mode when editing markdown +;; TODO: move this out of wpc-misc.el and into a later file to call +;; `(disable company-mode)' +(use-package markdown-mode + :config + ;; TODO: Add assertion that pandoc is installed and it is accessible from + ;; Emacs. + (setq markdown-command "pandoc") + (setq markdown-split-window-direction 'right) + (add-hook 'markdown-mode-hook #'markdown-live-preview-mode)) + +;; Required by some google-emacs package commands. +(use-package deferred) + +;; git integration +(use-package magit) + +;; http +(use-package request) + +;; perl-compatible regular expressions +(use-package pcre2el) + +;; alternative to help +(use-package helpful) + +;; 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-default fill-column constants/fill-column) + +(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 +(defvar ns-use-native-fullscreen nil) + +;; auto-close parens, brackets, quotes +(electric-pair-mode 1) + +(use-package yasnippet + :config + (yas-global-mode 1)) + +(use-package projectile + :config + (projectile-mode t)) + +(use-package deadgrep + :config + (general-define-key + :keymaps 'deadgrep-mode-map + :states 'normal + "o" #'deadgrep-visit-result-other-window) + (advice-add + 'deadgrep--format-command + :filter-return + (lambda (cmd) + (replace-regexp-in-string + "^rg " "rg --hidden " cmd)))) + +;; TODO: Do I need this when I have swiper? +(use-package counsel) + +(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")) + +;; EGlot (another LSP client) +(use-package eglot) + +;; Microsoft's Debug Adapter Protocol (DAP) +(use-package dap-mode + :after lsp-mode + :config + (dap-mode 1) + (dap-ui-mode 1)) + +;; Microsoft's Language Server Protocol (LSP) +(use-package lsp-ui + :config + (add-hook 'lsp-mode-hook #'lsp-ui-mode)) + +(use-package company-lsp + :config + (push 'company-lsp company-backends)) + +;; Wilfred/suggest.el - Tool for discovering functions basesd on declaring your +;; desired inputs and outputs. +(use-package suggest) + +;; Malabarba/paradox - Enhances the `list-packages' view. +(use-package paradox + :config + (paradox-enable)) + +;; TODO: Consider supporting a wpc-elisp.el package for Elisp tooling. +;; The following functions are quite useful for Elisp development: +;; - `emr-el-find-unused-definitions' +(use-package emr + :config + (define-key prog-mode-map (kbd "M-RET") #'emr-show-refactor-menu)) + +(defun wpc/frame-name () + "Return the name of the current frame." + (frame-parameter nil 'name)) + +;; Even if I resolved the socket-name resolution issue, I couldn't find an +;; elegant way to reuse GUI frames. GUIs for me have the advantage of supporting +;; True Color, support additional keys for KBDs (i.e. super), and aren't limited +;; by the terminal for rendering certain things. +(require 'server) +(when (not (server-running-p)) + (server-start)) + +(provide 'wpc-misc) +;;; wpc-misc.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-nix.el b/configs/shared/.emacs.d/wpc/packages/wpc-nix.el new file mode 100644 index 000000000000..af439c442d63 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-nix.el @@ -0,0 +1,12 @@ +;;; wpc-nix.el --- Nix support -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Configuration to support working with Nix. + +;;; Code: +(use-package nix-mode + :mode "\\.nix\\'") + +(provide 'wpc-nix) +;;; wpc-nix.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-ocaml.el b/configs/shared/.emacs.d/wpc/packages/wpc-ocaml.el new file mode 100644 index 000000000000..3b898d32be54 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-ocaml.el @@ -0,0 +1,51 @@ +;;; wpc-ocaml.el --- My OCaml preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Tooling support for OCaml development. +;; +;; Dependencies: +;; - `opam install tuareg` +;; - `opam install merlin` +;; - `opam install user-setup` +;; - `opam install ocamlformat` + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dependencies +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'prelude) +(require 'f) + +(prelude/assert + (prelude/executable-exists? "opam")) + +(defvar opam-installs "~/.opam/4.08.0/share/emacs/site-lisp" + "Path to the Ocaml PAckage Manager installations.") + +(defvar opam-user-setup "~/.emacs.d/opam-user-setup.el" + "File for the OPAM Emacs integration.") + +(prelude/assert + (f-file? opam-user-setup)) + +(prelude/assert + (f-dir? opam-installs)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(use-package tuareg + :config + (add-hook-before-save 'tuareg-mode-hook #'ocamlformat-before-save)) + +;; ocamlformat +(require 'opam-user-setup "~/.emacs.d/opam-user-setup.el") +(require 'ocamlformat) +(add-to-list 'load-path opam-installs) + +(provide 'wpc-ocaml) +;;; wpc-ocaml.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-org.el b/configs/shared/.emacs.d/wpc/packages/wpc-org.el new file mode 100644 index 000000000000..d1d981a3ea25 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-org.el @@ -0,0 +1,78 @@ +;;; org.el --- My org preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Hosts my org mode preferences + +;;; Code: + +;; TODO: figure out how to nest this in (use-package org ...) +(setq org-capture-templates + `( + + ("w" "work" entry (file+headline + ,(f-join (getenv "ORG_DIRECTORY") "work.org") + "Tasks") + "* TODO %?") + + ("p" "personal" entry (file+headline + ,(f-join (getenv "ORG_DIRECTORY") "personal.org") + "Tasks") + "* TODO %? ") + + ("i" "ideas" entry (file+headline + ,(f-join (getenv "ORG_DIRECTORY") "ideas.org") + "Tasks") + "* %? ") + + ("s" "shopping list" entry (file+headline + ,(f-join (getenv "ORG_DIRECTORY") "shopping.org") + "Items") + "* TODO %? ") + + )) +(evil-set-initial-state 'org-mode 'normal) + +(use-package org + :config + (general-add-hook 'org-mode-hook + ;; TODO: consider supporting `(disable (list linum-mode company-mode))' + (list (disable linum-mode) + (disable company-mode))) + (general-define-key :prefix "C-c" + "l" #'org-store-link + "a" #'org-agenda + "c" #'org-capture) + (setq org-startup-folded nil) + (setq org-todo-keywords + '((sequence "TODO" "BLOCKED" "DONE"))) + (setq org-default-notes-file (f-join (getenv "ORG_DIRECTORY") "notes.org")) + (setq org-agenda-files (list (f-join (getenv "ORG_DIRECTORY") "work.org") + (f-join (getenv "ORG_DIRECTORY") "personal.org"))) + ;; TODO: troubleshoot why `wpc/kbds-minor-mode', `wpc/ensure-kbds' aren't + ;; enough to override the following KBDs. See this discussion for more context + ;; on where the idea came from: + ;; https://stackoverflow.com/questions/683425/globally-override-key-binding-in-emacs + (general-unbind 'normal org-mode-map "M-h" "M-j" "M-k" "M-l")) + +(use-package org-bullets + :after (org) + :config + (general-add-hook 'org-mode-hook (enable org-bullets-mode))) + +;; i3, `org-mode' integration +;; Heavily influenced by: https://somethingsomething.us/post/i3_and_orgmode/ +;; TODO: Consider generalizing this since we're using "floating". +(defadvice org-switch-to-buffer-other-window + (after supress-window-splitting activate) + "Delete the extra window if we're in a capture frame." + (if (equal "floating" (wpc/frame-name)) + (delete-other-windows))) + +(add-hook 'org-capture-after-finalize-hook + (lambda () + (when (equal "floating" (wpc/frame-name)) + (delete-frame)))) + +(provide 'wpc-org) +;;; wpc-org.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-package.el b/configs/shared/.emacs.d/wpc/packages/wpc-package.el new file mode 100644 index 000000000000..6f43330ecb1a --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-package.el @@ -0,0 +1,27 @@ +;;; package.el --- My package configuration -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; 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" . "http://melpa.org/packages/")) +(package-initialize) + +(unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) +(eval-when-compile + (require 'use-package)) +(setq use-package-always-ensure t) +(use-package 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) +;;; wpc-package.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-python.el b/configs/shared/.emacs.d/wpc/packages/wpc-python.el new file mode 100644 index 000000000000..d0c6dd0d3e42 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-python.el @@ -0,0 +1,17 @@ +;;; wpc-python.el --- Python configuration -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; My Python configuration settings +;; +;; Depends +;; - `apti yapf` + +;;; Code: + +(use-package py-yapf + :config + (add-hook 'python-mode-hook #'py-yapf-enable-on-save)) + +(provide 'wpc-python) +;;; wpc-python.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-reasonml.el b/configs/shared/.emacs.d/wpc/packages/wpc-reasonml.el new file mode 100644 index 000000000000..909c33d121f7 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-reasonml.el @@ -0,0 +1,29 @@ +;;; wpc-reasonml.el --- My ReasonML preferences -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Tooling support for ReasonML development. +;; +;; Dependencies: +;; - `opam install tuareg` +;; - `opam install merlin` +;; - `opam install user-setup` +;; - `opam install ocamlformat` + +;;; Code: + +;; ReasonML configuration +(use-package reason-mode + :config + (add-hook-before-save 'reason-mode-hook #'refmt-before-save)) + +;; ReasonML LSP configuration +(lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection (f-full "~/programming/dependencies/reason-language-server")) + :major-modes '(reason-mode) + :notification-handlers (ht ("client/registerCapability" 'ignore)) + :priority 1 + :server-id 'reason-ls)) + +(provide 'wpc-reasonml) +;;; wpc-reasonml.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-rust.el b/configs/shared/.emacs.d/wpc/packages/wpc-rust.el new file mode 100644 index 000000000000..fafa27d18c77 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-rust.el @@ -0,0 +1,34 @@ +;;; wpc-rust.el --- Support Rust language -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Supports my Rust work. +;; +;; Dependencies: +;; - `rustup` +;; - `rustup component add rust-src` +;; - `rustup toolchain add nightly && cargo +nightly install racer` + + +;;; Code: +(use-package racer + :config + (setq rust-sysroot (->> "~/.cargo/bin/rustc --print sysroot" + shell-command-to-string + s-trim-right)) + (setq racer-rust-src-path (f-join rust-sysroot "lib/rustlib/src/rust/src")) + (add-hook 'racer-mode-hook #'eldoc-mode)) + +(use-package rust-mode + :config + (add-hook 'rust-mode-hook #'racer-mode) + (add-hook-before-save 'rust-mode-hook #'rust-format-buffer) + (define-key rust-mode-map + (kbd "TAB") + #'company-indent-or-complete-common) + (define-key rust-mode-map + (kbd "M-d") + #'racer-describe)) + +(provide 'wpc-rust) +;;; wpc-rust.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-shell.el b/configs/shared/.emacs.d/wpc/packages/wpc-shell.el new file mode 100644 index 000000000000..14d0489030da --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-shell.el @@ -0,0 +1,15 @@ +;;; wpc-shell.el --- POSIX Shell scripting support -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Helpers for my shell scripting. Includes bash, zsh, etc. + +;;; Code: + +(use-package flymake-shellcheck + :commands flymake-shellcheck-load + :init + (add-hook 'sh-mode-hook #'flymake-shellcheck-load)) + +(provide 'wpc-shell) +;;; wpc-shell.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-terminal.el b/configs/shared/.emacs.d/wpc/packages/wpc-terminal.el new file mode 100644 index 000000000000..c232bb85a7b7 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-terminal.el @@ -0,0 +1,70 @@ +;;; terminal.el --- My cobbled together terminal -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; My attempts at creating a sane Emacs terminal. Most of this work was created +;; before I discovered and fully adopted EXWM. Prior to this, the appeal of +;; having terminals inside of Emacs was appealing. So appealing in fact that I +;; was willing to work with inferior alternatives to non-Emacs terminals +;; (e.g. `ansi-term') instead of GUI alternatives like `alacritty` because the +;; productivity gains of having a terminal inside of Emacs might outweigh the +;; shortcomings of that particular terminal. +;; +;; All of this changed, however, after discovering EXWM, since I can embed X11 +;; GUI windows inside of Emacs. Therefore, most of this module is maintained +;; for historical purposes. +;; +;; Benefits of `ansi-term': +;; - Color scheme remains consistent between Emacs and terminal. +;; - Same applies to my fonts. +;; +;; Downsides of `ansi-term': +;; - Paging feels sluggish with programs like `cat` and `less`. +;; - KBDs don't provide 100% coverage of what I expect from a terminal since +;; they were created to cooperate with Emacs. + +;;; Code: + +(require 'window) +(require 'buffer) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Library +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; TODO: Model all open terminals within a dictionary. + +(defconst wpc-terminal/name + "wpc/terminal" + "The name of my terminal buffers.") + +(defun wpc-terminal/find-window () + "Return a reference to an existing terminal window or nil." + (->> wpc-terminal/name + wpc/add-earmuffs + window/find)) + +(defun wpc-terminal/find-buffer () + "Return a reference to an existing terminal buffer." + (->> wpc-terminal/name + wpc/add-earmuffs + buffer/find)) + +(defun wpc-terminal/find-or-create () + "Find or create a terminal window." + (let ((buffer (wpc-terminal/find-buffer))) + (if buffer + (buffer/show buffer) + (ansi-term "/usr/bin/zsh" wpc-terminal/name)))) + +;; TODO: Focus terminal after toggling it. +(defun wpc-terminal/toggle () + "Toggle a custom terminal session in Emacs." + (interactive) + (let ((window (wpc-terminal/find-window))) + (if window + (window/delete window) + (wpc-terminal/find-or-create)))) + +(provide 'wpc-terminal) +;;; wpc-terminal.el ends here diff --git a/configs/shared/.emacs.d/wpc/packages/wpc-ui.el b/configs/shared/.emacs.d/wpc/packages/wpc-ui.el new file mode 100644 index 000000000000..4c850e5b4b40 --- /dev/null +++ b/configs/shared/.emacs.d/wpc/packages/wpc-ui.el @@ -0,0 +1,185 @@ +;;; wpc-ui.el --- Any related to the UI/UX goes here -*- lexical-binding: t -*- +;; Author: William Carroll + +;;; Commentary: +;; Hosts font settings, scrolling, color schemes. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dependencies +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'prelude) +(require 'alist) +(require 'wallpaper) +(require 'fonts) +(require 'themes) +(require 'window-manager) +(require 'device) +(require 'laptop-battery) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; increase line height +(setq-default line-spacing 4) + +;; Ensure that buffers update when their contents change on disk. +(global-auto-revert-mode t) + +;; smooth scrolling settings +(setq scroll-step 1 + scroll-conservatively 10000) + +;; clean up modeline +(use-package diminish + :config + (diminish 'emacs-lisp-mode "elisp") + (diminish 'evil-commentary-mode) + (diminish 'flycheck-mode) + (diminish 'auto-revert-mode) + (diminish 'which-key-mode) + (diminish 'yas-minor-mode) + (diminish 'lispyville-mode) + (diminish 'undo-tree-mode) + (diminish 'company-mode) + (diminish 'projectile-mode) + (diminish 'eldoc-mode) + ;; This is how to diminish `auto-fill-mode'. + (diminish 'auto-fill-function) + (diminish 'counsel-mode) + (diminish 'ivy-mode)) + +;; disable startup screen +(setq inhibit-startup-screen t) + +;; disable toolbar +(tool-bar-mode -1) + +;; TODO: Re-enable `linum-mode' when I figure out why the theming is so ugly. +;; enable line numbers +;; (general-add-hook '(prog-mode-hook +;; text-mode-hook +;; conf-mode-hook) +;; (enable linum-mode)) + +;; set default buffer for Emacs +(setq initial-buffer-choice constants/current-project) + +;; integration with wpgtk (in vendor directory) +;; TODO: Re-enable this when base16-wpgtk are looking better. +;; (require 'wpgtk-theme) + +;; base-16 themes to integrate with wpgtk +;; (use-package base16-theme +;; :config +;; (require 'wpgtk) +;; (colorscheme/set 'base16-wpgtk)) + +;; premium Emacs themes +(use-package doom-themes + :config + (setq doom-themes-enable-bold t + doom-themes-enable-italic t) + (doom-themes-visual-bell-config) + (doom-themes-org-config)) + +;; file browsing +(use-package neotree + :config + (global-set-key [f8] #'neotree-toggle)) + +;; kbd discovery +(use-package which-key + :config + (setq which-key-idle-delay 0.25) + (which-key-mode)) + +;; completion framework +(use-package ivy + ;; TODO: Restore behavior where `counsel' is used everywhere. + :config + (counsel-mode t) + (alist/set! #'counsel-M-x "" ivy-initial-inputs-alist) + ;; prefer using `helpful' variants + (progn + (setq counsel-describe-function-function #'helpful-callable) + (setq counsel-describe-variable-function #'helpful-variable)) + (general-define-key + :keymaps 'ivy-minibuffer-map + ;; prev + "C-k" #'ivy-previous-line + "" #'ivy-previous-line + ;; next + "C-j" #'ivy-next-line + "" #'ivy-next-line)) + +(use-package ivy-prescient + :config + (ivy-prescient-mode 1) + (prescient-persist-mode 1)) + +;; all-the-icons +(use-package all-the-icons + :config + ;; Only run this once after installing. + ;; (all-the-icons-install-fonts) + ) + +;; icons for Ivy +(use-package all-the-icons-ivy + :after (ivy all-the-icons) + :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)) + +;; reduce noisiness of auto-revert-mode +(setq auto-revert-verbose nil) + +;; highlight lines that are over 100 characters long +(use-package whitespace + :config + (setq whitespace-line-column constants/fill-column) + (setq whitespace-style '(face lines-tail)) + (add-hook 'prog-mode-hook #'whitespace-mode)) + +;; 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 +(setq uniquify-buffer-name-style 'forward) + +;; highlight matching parens, brackets, etc +(show-paren-mode 1) + +;; hide the scroll-bars in the GUI +(scroll-bar-mode -1) + +;; GUI alerts in emacs +(use-package alert + :commands (alert) + :config + (setq alert-default-style 'notifier)) + +;; TODO: Should `device/work-laptop?' be a function or a constant that gets set +;; during initialization? +(when (device/work-laptop?) + (laptop-battery/display)) + +;; Load a theme +(->> (themes/random) + themes/set) + +(provide 'wpc-ui) +;;; wpc-ui.el ends here -- cgit 1.4.1