about summary refs log tree commit diff
path: root/emacs.d/wpc/functions.el
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2018-04-25T17·26-0400
committerWilliam Carroll <wpcarro@gmail.com>2018-07-19T16·00-0400
commit3c8e6f0cc5eac51e369b8ffbd0441366cdc6da40 (patch)
treee1c98f5b22dd258e4ae331c0591e0527fe5233a1 /emacs.d/wpc/functions.el
parent56a7b9fa41c6edbb960686ccffb7a8949d242eab (diff)
Support updated emacs
Finally ported my up-to-date emacs configuration here. I was putting
this off for a long while, unsure of how to handle all of the work. All
it took was my laptop being fried to force me to do this. So... voila!
Diffstat (limited to 'emacs.d/wpc/functions.el')
-rw-r--r--emacs.d/wpc/functions.el227
1 files changed, 227 insertions, 0 deletions
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