diff options
Diffstat (limited to 'emacs.d/wpc/functions.el')
-rw-r--r-- | emacs.d/wpc/functions.el | 227 |
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 |