Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
2038 lines (1629 sloc) 80.5 KB

jwinder emacs config

introduction

getting started

I prefer to clone this repository as $HOME/emacs-config and symlink it to $HOME/.emacs.d

git clone git@github.com:jwinder/emacs-config.git $HOME/emacs-config
ln -s $HOME/emacs-config $HOME/.emacs.d

You can also create symlinks to a private directory or private.org file in a safe place, containing private or personal settings. This works well for irc passwords, tramp helpers, etc.

ln -s /path/to/your/safe/directory $HOME/emacs-config/private # directory of elisp files
ln -s /path/to/your/safe/private.org $HOME/emacs-config/private.org # file containing elisp segments

Now, start emacs.

org configs

personal info

(defconst jw-config-author-name "Joe Winder")
(defconst jw-config-author-url "http://jwinder.github.io")
(defconst jw-config-github-url "https://github.com/jwinder/emacs-config")

dependencies

packages

common

(use-package afternoon-theme :pin melpa)

(use-package dash :pin melpa)
(use-package f :pin melpa)
(use-package s :pin melpa
  :config (progn
            (defalias 's-empty? 's-blank?)
            (defalias 's-nonempty? 's-present?)
            (defalias 's-nonempty-or-nil 's-presence)))

(use-package scratch :pin melpa
  :config (progn
            (defalias 'tmp-scratch-buffer 'scratch)))

(use-package ob-http)
(use-package ob-translate)
(use-package ob-async :pin melpa)

(use-package org-pomodoro)
(use-package interleave)

(use-package htmlize)

(use-package magit
  :config (global-magit-file-mode t))

(use-package browse-at-remote :pin melpa
  :config (progn
            (defalias 'git-browse-at-remote 'browse-at-remote)
            (defalias 'github-browse-file 'browse-at-remote)))

(use-package gist
  :config (setq gist-view-gist t))

(use-package expand-region)

(use-package multiple-cursors
  :config (progn
            (defun mc/prompt-for-inclusion-in-whitelist (original-command)
              "Rewrite of `mc/prompt-for-inclusion-in-whitelist' to not ask yes/no for every newly seen command."
              (add-to-list 'mc/cmds-to-run-for-all original-command)
              (mc/save-lists)
              t)))

(use-package smartparens
  :config (progn (require 'smartparens-config)
                 (smartparens-global-mode t)))

(use-package company
  :config (progn (global-company-mode t)
                 (setq company-idle-delay nil
                       company-tooltip-idle-delay nil)))

(use-package flycheck
  :pin melpa-stable
  :config (progn (setq flycheck-standard-error-navigation nil
                       flycheck-display-errors-function nil)
                 (global-flycheck-mode)))

(use-package yasnippet)
(use-package yasnippet-snippets)

(use-package helm)
(use-package helm-ag)
(use-package helm-projectile)
(use-package helm-flycheck)
(use-package helm-flyspell :pin melpa)
(use-package helm-descbinds)

(use-package wgrep
  :config (setq wgrep-auto-save-buffer t))

(use-package wgrep-helm)

(use-package docker)

(use-package dumb-jump
  :config (setq dumb-jump-selector 'helm))

(use-package xah-math-input :pin melpa
  :config (progn
            (xah-math-input--add-to-hash [ ["def" ""] ["pm" "±"] ["cdot" "·"] ["wedge" ""] ["doublesharp" "𝄪"]])
            (xah-math-input--add-cycle ["" ""])
            (xah-math-input--add-cycle ["" "" "" ""])
            (xah-math-input--add-cycle ["" "" "" "" "" ""])))

;; not working well after emacs 26 upgrade
;; (use-package ess
;;   :config (setq save-abbrevs 'silently)) ;; ess R sets some abbrevs when installed

languages

(use-package yaml-mode)

(use-package markdown-mode)

(use-package dockerfile-mode)

(use-package scala-mode)
(use-package sbt-mode)

(use-package inf-ruby)

(use-package go-mode
  :config (add-hook 'before-save-hook 'gofmt-before-save))

(use-package haskell-mode
  :config (add-hook 'haskell-mode-hook 'turn-on-haskell-indent))

(use-package coffee-mode
  :config (setq coffee-tab-width 2))

(use-package terraform-mode
  :mode ("\\.tfstate$" . js-mode))

(use-package protobuf-mode)

(use-package groovy-mode
  :mode ("Jenkinsfile$" . groovy-mode))

(use-package markdown-mode
  :mode (("\\.md$" . gfm-mode)
         ("\\.markdown$" . gfm-mode)))

;; (use-package graphviz-dot-mode) ;; does not work after emacs 26.1 upgrade

helper functions

These are non-interactive library functions useful in other parts of this config

(require 'dash)
(require 's)
(require 'f)
(require 'vc)

(defconst jw--mode-line-color "#22083397778B")

(defun jw--font-name (&optional size)
  (if size (concat "Monaco " size) "Monaco"))

(defun jw--set-font-size (size)
  (set-face-attribute 'default nil :font (jw--font-name size)))

(defun jw--login-shell ()
  (file-name-nondirectory (getenv "SHELL")))

(defun jw--all-minor-modes ()
  (sort minor-mode-list 's-less-p))

(defun jw--all-major-modes ()
  (sort (-distinct (mapcar 'cdr (-filter '(lambda (entry) (and (cdr entry) (atom (cdr entry)))) auto-mode-alist))) 's-less-p))

(defmacro jw--define-menu (name doc &rest args)
  (declare (indent defun))
  (require 'magit-popup)
  `(progn (magit-define-popup ,name ,doc ,@args)))

(defmacro jw--save-current-message (&rest body)
  "Saves `current-message', executes the body, then `message' the saved message to the echo area. Any `message' calls within the body will likely not be seen."
  (declare (indent defun))
  `(let ((msg (current-message)))
     (progn ,@body)
     (message msg)))

(defun jw--write-to-file (string file &optional append)
  (jw--save-current-message
    (let ((file-dir (file-name-directory file)))
      (unless (f-exists? file-dir) (make-directory file-dir 'mk-parents)))
    (if append (f-append string 'utf-8 file) (f-write string 'utf-8 file))))

(defun jw--make-uuid ()
  (downcase (shell-command-to-string "uuidgen | tr -d '\n'")))

(defun jw--pwd ()
  (file-truename default-directory))

(defun jw--vc-root-dir ()
  (let ((vc-root-dir (ignore-errors (vc-call-backend (vc-responsible-backend (jw--pwd)) 'root (jw--pwd)))))
    (if vc-root-dir (file-truename vc-root-dir) nil)))

(defun jw--git-root-dir ()
  (let ((git-root-dir (ignore-errors (vc-find-root (jw--pwd) ".git"))))
    (if git-root-dir (file-truename git-root-dir) nil)))

(defun jw--git-config-get (key)
  (s-presence (s-trim (shell-command-to-string (format "git config --get %s 2>/dev/null" key)))))

(defun jw--iso-current-time-string ()
  (concat (format-time-string "%Y-%m-%dT%T")
          ((lambda (x) (concat (substring x 0 3) ":" (substring x 3 5))) (format-time-string "%z"))))

(defun jw--current-date-string ()
  (format-time-string "%Y-%m-%d"))

(defun jw--http-get-request-to-string (url)
  (with-current-buffer (url-retrieve-synchronously url)
    (goto-char url-http-end-of-headers)
    (delete-region (point-min) (point))
    (s-trim (buffer-string))))

(defun jw--do-when-process-finishes (process fn)
  "Invoke function `fn' after process `process' finishes or exits. `fn' is a one-arg function providing the finished process."
  (when process
    (set-process-sentinel process
                          `(lambda (proc change)
                             (when (string-match "\\(?:finished\\|exited\\)" change)
                               (funcall ,fn proc))))))

(setq jw--run-cmd-shell "bash")

(defun jw--run-cmd (command &optional process-name before-process-creation after-process-creation after-process-finish delete-tmp-script-after)
  "A wrapper around `make-comint-in-buffer'.

For commands that have already finished, this will clean up the process buffer and re-run the command.
For long running processes, this will always toggle back and forth between the process buffer and the other buffer as long as the process is alive.

`process-name' can be used to override the automatic naming of the process & buffer (from the `command').
`before-process-creation' is an optional zero-arg function that is run before the process is started.
`after-process-creation' is an optional one-arg function (providing the process an arg) that is run after the process is started.
`after-process-finish' is an optional one-arg function (providing the process as an arg) that is run after the process finishes."
  (require 'comint)
  (let* ((prepared-cmd (string-trim command))
         (cmd-process-name (or process-name (s-collapse-whitespace (s-left 100 prepared-cmd))))
         (cmd-buffer-name (format "*%s*" cmd-process-name)))
    (if (s-empty? prepared-cmd)
        (message "Empty command! Doing nothing.")
      (if (process-live-p (get-process cmd-process-name))
          (if (string= (buffer-name) cmd-buffer-name) (switch-to-buffer (other-buffer)) (switch-to-buffer cmd-buffer-name))
        (let* ((tmp-script-dir "/tmp/emacs-jw-run-cmd/")
               (tmp-script-rel-filename (replace-regexp-in-string "[^a-zA-Z0-9]+" "-" cmd-process-name))
               (tmp-script-abs-filename (concat tmp-script-dir tmp-script-rel-filename))
               (tmp-script-sh-executable (or (ignore-errors (executable-find jw--run-cmd-shell))
                                             (executable-find (jw--login-shell))))
               (tmp-script-contents (format "#!%s\n\ncd %s\n\n%s" tmp-script-sh-executable (jw--pwd) prepared-cmd)))
          (when (get-buffer cmd-buffer-name) (kill-buffer cmd-buffer-name))
          (jw--write-to-file tmp-script-contents tmp-script-abs-filename)
          (unless (file-executable-p tmp-script-abs-filename) (chmod tmp-script-abs-filename #o744))
          (let ((process-buffer (get-buffer-create cmd-buffer-name)))
            (when before-process-creation (funcall before-process-creation))
            (apply 'make-comint-in-buffer cmd-process-name process-buffer tmp-script-abs-filename nil nil)
            (let ((proc (get-buffer-process process-buffer)))
              (when after-process-creation (funcall after-process-creation proc))
              (when after-process-finish (jw--do-when-process-finishes proc `(lambda (proc) (funcall ,after-process-finish proc))))
              (when delete-tmp-script-after (jw--do-when-process-finishes proc `(lambda (proc) (f-delete ,tmp-script-abs-filename 'force)))))
            (switch-to-buffer process-buffer)))))))

(defun jw--run-cmd-tmux (command tmux-session)
  "Create session `tmux-session' if needed, and send `command' to it."
  (call-process "tmux" nil nil nil "new-session" "-d" "-s" tmux-session) ;; this does nothing if the session already exists
  (call-process "tmux" nil nil nil "send-keys" "-t" tmux-session command "C-m"))

(defun jw--sql-pretty-print (begin end)
  "Formats SQL on region between `begin' and `end' using underlying sql-formatter-cli."
  (if (executable-find "sql-formatter-cli")
      (shell-command-on-region begin end "sql-formatter-cli" nil 'replace)
    (message "Formatter not found. Please run: npm install -g sql-formatter-cli")))

A macro to set keybindings from an org table

(defmacro keybinding-org-table (org-table)
  "Sets up key bindings from an org table like:

      | Key   | Function | Scope           | Hook          | Notes     |
      |-------+----------+-----------------+---------------+-----------|
      | C-c a | fn-1     |                 |               | fun notes |
      | C-c b | fn-2     | local           | org-mode-hook |           |
      | C-c c | fn-3     | eshell-mode-map |               |           |
      | C-c d | nil      |                 |               |           |
      | C-c e | nil      | local           |               |           |
      | C-c f | nil      | eshell-mode-map |               |           |

- C-c a gets set to fn-1 in the global map.
- C-c b gets set to fn-2 in the current local map, run during the org-mode-hook.
- C-c c gets set to fn-3 in the eshell-mode-map.
- C-c d gets unbound in the global map.
- C-c e gets unbound in the current local map.
- C-c f gets unbound in the eshell-mode-map.

- For a global binding, an empty cell or the value \"global\" can be provided in the Scope column.
- When unsetting a keybinding, an empty table cell can be provided instead of nil in the Function column.
- It is safe to leave out the Scope & Hook columns if only global keybindings are necessary.
- The ordering of the 4 columns cannot be changed (extra columns after the Hook column are ignored)."

  (declare (indent defun))
  `(let* ((org-table-name (symbol-name ,org-table))
          (rows (symbol-value ,org-table))
          (keys-var-name (format "jw-%s" org-table-name))
          (keys-setter-def-name (format "jw-%s-set-bindings" org-table-name))
          (keys-setter-def-symbol (intern keys-setter-def-name)))

     ;; add keys to their own variable: jw-[org-table]
     (eval `(setq ,(intern keys-var-name) rows))

     ;; append keys to jw-all-custom-keys variable
     (unless (boundp 'jw-all-keys) (setq jw-all-keys nil))
     (-each rows (lambda (row) (add-to-list 'jw-all-keys row 'append)))

     ;; create interactive jw-[org-table]-set-bindings function to set all keys
     (eval `(defun ,keys-setter-def-symbol ()
              ,(format "Auto-created function to set keybindings defined in the org table: %s\n\nOrg table keybindings cached in `%s'\n\nAll custom keybindings cached in `jw-all-keys'\n\nThis function is also stored in `jw-all-keys-set-bindings-functions', and `jw-all-keys-set-bindings' evaluates every function in this list." org-table-name (intern keys-var-name))
              (interactive)
              (-each ,(intern keys-var-name) ;; must call the dynamic jw-[org-table] var here, not the lexical rows var
                (lambda (row)
                  (let* ((key (car row))
                         (command (if (cadr row) (intern (cadr row)) nil))
                         (scope (s-presence (nth 2 row)))
                         (hook-name (s-presence (nth 3 row))))

                    ;; yucky but the functions must be setup differently inside of hooks
                    ;; being explicit about the various cases is best

                    (cond
                     ((and hook-name (s-equals? scope "local"))
                      (add-hook (intern hook-name)
                                `(lambda () (local-set-key (kbd ,key) (quote ,command)))))

                     ((and hook-name (or (s-blank-str? scope) (s-equals? scope "global")))
                      (add-hook (intern hook-name)
                                `(lambda () (global-set-key (kbd ,key) (quote ,command)))))

                     ((and hook-name (boundp (intern scope)))
                      (add-hook (intern hook-name)
                                `(lambda () (define-key ,(intern scope) (kbd ,key) (quote ,command)))))

                     ((s-equals? scope "local") (local-set-key (kbd key) command))

                     ((or (s-blank-str? scope) (s-equals? scope "global")) (global-set-key (kbd key) command))

                     ((boundp (intern scope)) (define-key (eval (intern scope)) (kbd key) command))

                     (t (message "Unable to set command %s to keybinding %s from org table. Silently skipping." command key))
                     )
                    )
                  ))
              ))

     ;; append jw-[org-table]-set-bindings to jw-all-keys-set-bindings-functions variable
     (unless (boundp 'jw-all-keys-set-bindings-functions) (setq jw-all-keys-set-bindings-functions nil))
     (add-to-list 'jw-all-keys-set-bindings-functions `,keys-setter-def-symbol 'append)

     ;; create jw-set-all-bindings to eval every function created with this macro
     (unless (fboundp 'jw-all-keys-set-bindings)
       (defun jw-all-keys-set-bindings ()
         "Evaluate every function in `jw-all-keys-set-bindings-functions'."
         (interactive)
         (-each jw-all-keys-set-bindings-functions 'funcall)))

     ;; go ahead and eval jw-[org-table]-set-bindings
     (eval `(,keys-setter-def-symbol))
     ))

customization

env

(require 'eshell)

(defun jw-env-set ()
  (interactive)
  (let* ((cmd (format "%s -l -i -c env" (jw--login-shell)))
         (env-big-str (shell-command-to-string cmd))
         (lines (split-string env-big-str "\n")))
    (dolist (line lines)
      (unless (= 0 (length line))
        (let* ((tokens (split-string line "="))
               (name (car tokens))
               (value (mapconcat 'identity (cdr tokens) "=")))
          (setenv name value)
          (when (string= name "PATH")
            (setq exec-path (split-string value ":"))
            (setq eshell-path-env value))))))
  (setenv "EDITOR" "emacsclient"))

(jw-env-set)
(add-to-list 'eshell-mode-hook 'jw-env-set)

style

(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)

(load-theme 'afternoon t)
(set-cursor-color "dark grey")
(set-background-color "black")
(set-face-background 'fringe nil)

(jw--set-font-size "14")

(set-face-attribute 'mode-line nil :font (jw--font-name "14") :background jw--mode-line-color :foreground "#7db5d6" :box '(:style released-button))
(set-face-attribute 'mode-line-inactive nil :background "#263238" :foreground "gray" :box '(:style released-button))
(set-face-attribute 'mode-line-buffer-id nil :foreground "white")
(set-face-attribute 'mode-line-highlight nil :foreground "#7db5d6")
(set-face-attribute 'header-line nil :background "#005858" :foreground "white")

(setq-default mode-line-format '(" " mode-line-buffer-identification (vc-mode vc-mode) " " mode-line-misc-info))

(setq frame-title-format nil)

(when (eq system-type 'darwin)
  (add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
  (add-to-list 'default-frame-alist '(ns-appearance . dark))
  (setq ns-use-proxy-icon nil))

(setq inhibit-startup-message t
      initial-scratch-message ""
      initial-major-mode 'org-mode)

fix for cursor color in clients falling back to the default theme copied from stackoverflow

(require 'frame)

(defun fix-colors-for-emacs-clients (frame)
  (modify-frame-parameters frame (list (cons 'cursor-color "dark grey")))
  (modify-frame-parameters frame (list (cons 'background-color "black"))))

(add-hook 'after-make-frame-functions 'fix-colors-for-emacs-clients)

settings

(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file 'noerror)

(setq jw-org-scratch-file (f-expand "scratch.org" user-emacs-directory))

(setq enable-local-variables :all)

(ansi-color-for-comint-mode-on)

(show-paren-mode t)

(fset 'yes-or-no-p 'y-or-n-p)

(setq create-lockfiles nil)

(setq save-silently t)

(setq suggest-key-bindings nil)

(setq kill-whole-line t)

(global-auto-revert-mode 1)

(setq global-auto-revert-non-file-buffers t
      auto-revert-verbose nil)

(setq-default indent-tabs-mode nil)

(setq tab-width 2)
(setq js-indent-level 2)

(delete-selection-mode t)

(winner-mode t)

(global-subword-mode t)

(put 'dired-find-alternate-file 'disabled nil)

(setq wdired-allow-to-change-permissions 'advanced)

(setq dired-listing-switches "-alh")

(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)

(add-hook 'before-save-hook 'delete-trailing-whitespace)

(add-hook 'next-error-hook 'delete-other-windows)

(setq uniquify-buffer-name-style 'forward)

(setq ring-bell-function 'ignore)

(setq enable-recursive-minibuffers t)

(add-to-list 'auto-mode-alist '("\\.scss$" . css-mode))
(add-to-list 'auto-mode-alist '("Gemfile$" . ruby-mode))
(add-to-list 'auto-mode-alist '("Rakefile$" . ruby-mode))
(add-to-list 'auto-mode-alist '("Vagrantfile$" . ruby-mode))
(add-to-list 'auto-mode-alist '("Berksfile$" . ruby-mode))
(add-to-list 'auto-mode-alist '("\\.irbrc$" . ruby-mode))

(add-hook 'text-mode-hook 'flyspell-mode)

(setq ediff-window-setup-function 'ediff-setup-windows-plain)

(put 'narrow-to-region 'disabled nil)

;; (setq calc-angle-mode 'rad)
(setq calc-angle-mode 'deg)

(setq tramp-default-method "ssh")

;; comint doesn't recognize a password prompt in one of my scripts. consider reporting this as a bug.
(setq comint-password-prompt-regexp (concat comint-password-prompt-regexp "\\|^.*Password:\\s *\\'"))

(defun shell-command--advice--ignore-message-with-no-output (&rest args)
  (when (and (current-message) (string-match "Shell command succeeded with no output" (current-message))) (message nil)))
(advice-add 'shell-command-on-region :after 'shell-command--advice--ignore-message-with-no-output)

(setq user-auto-save-directory (expand-file-name "auto-saves/" user-emacs-directory ))
(unless (file-exists-p user-auto-save-directory) (make-directory user-auto-save-directory)) ;; auto-save won't create directories
(setq auto-save-file-name-transforms `((".*" ,user-auto-save-directory t)))

(setq user-backup-directory (expand-file-name "backups/" user-emacs-directory))
(unless (file-exists-p user-backup-directory) (make-directory user-backup-directory))

(setq version-control t
      vc-make-backup-files t
      kept-new-versions 10
      kept-old-versions 0
      backup-by-copying t ;; deep copy of symlinks
      delete-old-versions t)

(setq backup-directory-alist `(("." . ,user-backup-directory)))

(setq delete-by-moving-to-trash t)

(when (eq system-type 'gnu/linux)
  (setq interprogram-paste-function 'x-cut-buffer-or-selection-value
        browse-url-browser-function 'browse-url-generic
        browse-url-generic-program "google-chrome"))

(when (eq system-type 'darwin)
  (setq ns-command-modifier 'meta
        browse-url-browser-function 'browse-url-default-macosx-browser
        ispell-program-name "aspell"
        trash-directory "~/.Trash"))

functions

common

(defalias 'life-is-too-much 'save-buffers-kill-terminal)
(defalias 'filter-lines 'keep-lines)
(defalias 'filter-out-lines 'flush-lines)
(defalias 'elisp-shell 'ielm)

(defun font-size-normal ()
  (interactive)
  (jw--set-font-size "14"))

(defun font-size-big ()
  (interactive)
  (jw--set-font-size "18"))

(defun font-size-set (size)
  (interactive "sSize: ")
  (jw--set-font-size size))

(defun ns-raise-chrome ()
  (interactive)
  (when (fboundp 'ns-do-applescript)
    (ns-do-applescript "tell application \"Google Chrome\" to activate")))

(defun kill-ring-cleanup-last-kill (&optional in-major-mode)
  "Cleans whitespace and reindents the text in the head of the kill ring as if in the major mode.
NOTICE: Sometimes this acts funky, e.g. after removing items from the kill ring via helm."
  (interactive)
  (with-temp-buffer
    (jw--save-current-message
      (let ((mode (or in-major-mode (completing-read "Major mode to mimic: " (jw--all-major-modes) nil t))))
        (yank)
        (funcall (intern-soft mode))
        (indent-region (point-min) (point-max))
        (whitespace-cleanup)
        (kill-new (buffer-substring (point-min) (point-max)) t)))))

(defun kill-ring-save-region-or-line (arg)
  (interactive "P")
  (let ((cleanup-kill arg))
    (if (region-active-p)
        (kill-ring-save (mark) (point))
      (kill-ring-save (line-beginning-position) (line-end-position)))
    (when cleanup-kill (kill-ring-cleanup-last-kill major-mode))))

(defun kill-region-or-line (arg)
  (interactive "P")
  (let ((cleanup-kill arg))
    (if (region-active-p)
        (kill-region (mark) (point))
      (progn (beginning-of-line) (kill-line)))
    (when cleanup-kill (kill-ring-cleanup-last-kill major-mode))))

(defun kill-save-file-or-buffer-name (arg)
  "Kill ring save the current file name. With prefix arg, save the fully qualified path + file name. If the buffer is not visiting a file, use the buffer name."
  (interactive "P")
  (if buffer-file-name
      (if arg
          (kill-new buffer-file-name)
        (kill-new (f-filename buffer-file-name)))
    (kill-new (buffer-name))))

(defun unique-lines ()
  (interactive)
  (if (region-active-p)
      (delete-duplicate-lines (region-beginning) (region-end))
    (delete-duplicate-lines (point-min) (point-max))))

(defun date (&optional arg)
  "Display current date time.
With default prefix arg (e.g. C-u M-x date), also display calendar around current date.
With prefix arg of 4 (e.g. C-u 4 M-x date), also prompt for year/month for calendar display."
  (interactive "P")
  (when arg (calendar (if (equal arg 4) arg nil)))
  (message (current-time-string)))

(defun computer-power-status ()
  "Alternative to the default battery functions, which currently don't extract the information correctly on macOS."
  (interactive)
  (case system-type
    ('darwin (shell-command "pmset -g ps"))
    (t (message "This is only setup for macOS."))))

(defun iso-date ()
  (interactive)
  (message (jw--iso-current-time-string)))

(defun insert-iso-date ()
  (interactive)
  (insert (jw--iso-current-time-string)))

(defun insert-date ()
  (interactive)
  (insert (jw--current-date-string)))

(defun weather ()
  (interactive)
  (jw--run-cmd "curl wttr.in" "weather"))

(defun scratch-buffer ()
  "Save the scratch buffer in a file."
  (interactive)
  (find-file jw-org-scratch-file)
  (when (get-buffer "*scratch*") (kill-buffer "*scratch*")))

(defun toggle-scratch-buffer ()
  (interactive)
  (if (s-equals? (buffer-name) (f-filename jw-org-scratch-file))
      (progn
        (save-buffer)
        (switch-to-buffer (other-buffer)))
    (scratch-buffer)))

(defun ping-google ()
  (interactive)
  (ping "google.com"))

(defun uuid ()
  (interactive)
  (insert (jw--make-uuid)))

(defun json-prettify ()
  (interactive)
  (if (region-active-p)
      (json-pretty-print (region-beginning) (region-end))
    (json-pretty-print-buffer)))

(defun sql-prettify ()
  (interactive)
  (if (region-active-p)
      (jw--sql-pretty-print (region-beginning) (region-end))
    (jw--sql-pretty-print (point-min) (point-max))))

(defun math-symbol-at-point (arg)
  (interactive "P")
  (if arg
      (xah-math-input-list-math-symbols)
    (xah-math-input-change-to-symbol)))

(defun cmd (command)
  (interactive "sCommand: ")
  (jw--run-cmd command))

(defun cmd-tmux (command &optional tmux-session)
  (interactive "sCommand: ")
  (let ((ts (or tmux-session "emacs")))
    (jw--run-cmd-tmux command ts)
    (message "Sent to tmux session: %s" ts)))

(defun cmd-dwim (arg &optional command)
  "Shell command dwim.

M-x `cmd-dwim' will run an async shell command in a new buffer.
C-u M-x `cmd-dwim' will run a shell command and print the response in the echo area.
C-u C-u M-x `cmd-dwim' will run a shell command and insert the response in the buffer on the next line.
C-u C-u C-u M-x `cmd-dwim' will send a shell command to the default tmux session using `cmd-tmux'.

Interactively:
 - If a region is selected, the region will be used as the shell command.
 - If the point is on a line beginning with a dollar sign (e.g. \"$ whoami\"), the entire line will be used as the shell command.
 - Otherwise, the shell command is read from prompt."
  (interactive "P")
  (let ((prepared-cmd (or command (if (region-active-p)
                                      (buffer-substring-no-properties (region-beginning) (region-end))
                                    (if (s-starts-with? "$" (s-trim (or (thing-at-point 'line t) "")))
                                        (s-trim-left (s-chop-prefix "$" (s-trim (thing-at-point 'line t))))
                                      (read-shell-command "Command: "))))))
    (if arg
        (case (prefix-numeric-value arg)
          (16 (save-excursion (open-line-next) (insert (s-trim (shell-command-to-string prepared-cmd)))))
          (64 (cmd-tmux prepared-cmd))
          (t (message (string-trim (shell-command-to-string prepared-cmd)))))
      (cmd prepared-cmd))))

(jw--define-menu cmd-menu 'cmd-menu
  :actions '("Command menu (C-c m !)"
             (?! "sh cmd async    M-! (C-u echo area / C-u C-u at point)" cmd-dwim)
             (?: "elisp evaluate  M-:" helm-eval-expression-with-eldoc)
             (?* "calc evaluate   M-*" helm-calcul-expression))
  :max-action-columns 1)

(defun transpose-windows (arg)
  (interactive "p")
  (let ((selector (if (>= arg 0) 'next-window 'previous-window)))
    (while (/= arg 0)
      (let ((this-win (window-buffer))
            (next-win (window-buffer (funcall selector))))
        (set-window-buffer (selected-window) next-win)
        (set-window-buffer (funcall selector) this-win)
        (select-window (funcall selector)))
      (setq arg (if (plusp arg) (1- arg) (1+ arg))))))

(defun toggle-window-split ()
  (interactive)
  (if (= (count-windows) 2)
      (let* ((this-win-buffer (window-buffer))
             (next-win-buffer (window-buffer (next-window)))
             (this-win-edges (window-edges (selected-window)))
             (next-win-edges (window-edges (next-window)))
             (this-win-2nd (not (and (<= (car this-win-edges)
                                         (car next-win-edges))
                                     (<= (cadr this-win-edges)
                                         (cadr next-win-edges)))))
             (splitter
              (if (= (car this-win-edges)
                     (car (window-edges (next-window))))
                  'split-window-horizontally
                'split-window-vertically)))
        (delete-other-windows)
        (let ((first-win (selected-window)))
          (funcall splitter)
          (if this-win-2nd (other-window 1))
          (set-window-buffer (selected-window) this-win-buffer)
          (set-window-buffer (next-window) next-win-buffer)
          (select-window first-win)
          (if this-win-2nd (other-window 1))))))

(defun beginning-of-line-or-indentation ()
  (interactive)
  (let ((previous-point (point)))
    (back-to-indentation)
    (if (equal previous-point (point))
        (beginning-of-line))))

(defun indent-region-or-buffer--org-mode (arg)
  "Do not indent the entire buffer, only indent active regions.
   My org files can get pretty big, and I tend to indent certain parts of them manually as I see fit."
  (save-excursion
    (when (region-active-p)
      (indent-region (region-beginning) (region-end)))))

(defun indent-region-or-buffer--default (arg)
  (save-excursion
    (if (region-active-p)
        (indent-region (region-beginning) (region-end))
      (indent-region (point-min) (point-max))))
  (when arg (whitespace-cleanup)))

(defun indent-region-or-buffer (arg)
  (interactive "P")
  (jw--save-current-message
    (if (equal major-mode 'org-mode)
        (indent-region-or-buffer--org-mode arg)
      (indent-region-or-buffer--default arg))))

(defun comment-dwim-dwim (&optional arg)
  "When the region is active, then toggle comments over it.
Otherwise, toggle commenting the current line.
If there is a prefix arg, then append a comment to the end of the line instead.
If the prefix arg is 4, then kill the comment on the current line."
  (interactive "*P")
  (if (region-active-p)
      (comment-dwim arg)
    (if arg
        (if (equal arg 4)
            (save-excursion (comment-dwim arg))
          (comment-dwim nil))
      (comment-or-uncomment-region (line-beginning-position) (line-end-position)))))

(defun open-line-next ()
  (interactive)
  (end-of-line)
  (open-line 1)
  (next-line 1)
  (indent-according-to-mode))

(defun open-line-previous ()
  (interactive)
  (beginning-of-line)
  (open-line 1)
  (indent-according-to-mode))

(defun newline-and-open-line-previous ()
  (interactive)
  (let ((was-at-end-of-line (equal (point) (line-end-position))))
    (newline-and-indent)
    (unless was-at-end-of-line (open-line-previous))))

(defun split-window-down-last-buffer-or-scratch (arg)
  (interactive "P")
  (split-window-vertically)
  (other-window 1 nil)
  (if arg (scratch-buffer) (switch-to-buffer (other-buffer))))

(defun split-window-right-last-buffer-or-scratch (arg)
  (interactive "P")
  (split-window-horizontally)
  (other-window 1 nil)
  (if arg (scratch-buffer) (switch-to-buffer (other-buffer))))

(defun kill-matching-buffers-silently (pattern)
  (interactive "sKill buffers matching: ")
  (dolist (buffer (buffer-list))
    (when (string-match pattern (buffer-name buffer))
      (kill-buffer buffer))))

(defun set-transparency (value)
  (interactive "n0 - 100 (percent): ")
  (set-frame-parameter (selected-frame) 'alpha value))

(defun transparency-on ()
  (interactive)
  (set-transparency 75))

(defun transparency-off ()
  (interactive)
  (set-transparency 100))

(defun display-current-prefix-arg (arg)
  (interactive "P")
  (message "%s" arg))

contact

(defun config-insert-author ()
  (interactive)
  (insert jw-config-author-name))

(defun config-goto-homepage ()
  (interactive)
  (browse-url jw-config-author-url))

(defun config-goto-github ()
  (interactive)
  (browse-url jw-config-github-url))

emacs

(defun emacs-config ()
  (interactive)
  (find-file (expand-file-name "emacs.org" user-emacs-directory)))

(defun emacs-private-config ()
  (interactive)
  (find-file (expand-file-name "private.org" user-emacs-directory)))

(defun emacs-configs-toggle (arg)
  (interactive "P")
  (if arg
      (if (string= (buffer-name) "private.org") (switch-to-buffer (other-buffer)) (emacs-private-config))
    (if (string= (buffer-name) "emacs.org") (switch-to-buffer (other-buffer)) (emacs-config))))

(defun emacs-reload-config ()
  (interactive)
  (load-file (expand-file-name "init.el" user-emacs-directory)))

(defun emacs-archive-packages-and-reload-config ()
  (interactive)
  (emacs-archive-packages)
  (emacs-reload-config))

(defun emacs-archive-packages-and-die ()
  (interactive)
  (emacs-archive-packages)
  (life-is-too-much))

(defun emacs-archive-packages ()
  (when (f-exists? package-user-dir)
    (let ((archive-dir (format "/tmp/emacs-elpa--%s" (jw--iso-current-time-string))))
      (f-move package-user-dir archive-dir))))

(defun emacs-byte-compile-elpa-package-files ()
  (interactive)
  (-each (f-directories package-user-dir)
    (lambda (dir)
      (-each (f-entries dir)
        (lambda (entry) (when (s-matches? ".*el$" entry) (byte-compile-file entry)))))))

key bindings

base-keys (keys not in other parts of this config)

KeyFunctionScopeHookNotes
C-znilremove suspend
C-x C-znil
C-hnilremove original help
C-M-?help-command
<return>toggle-frame-maximizedctl-x-5-map
S-<return>toggle-frame-fullscreenctl-x-5-map
M-!cmd-dwim
M-&cmd-dwim
C-sisearch-forward-regexp
C-risearch-backward-regexp
C-M-ggoto-line
C-M-9winner-undo
C-M-0winner-redo
ttranspose-windowsctl-x-4-map
stoggle-window-splitctl-x-4-map
C-wkill-region-or-line
M-wkill-ring-save-region-or-line
C-abeginning-of-line-or-indentation
C-oopen-line-previous
C-<return>open-line-next
C-jnewline-and-open-line-previous
C-x 2split-window-down-last-buffer-or-scratch
C-x 3split-window-right-last-buffer-or-scratch
M-;comment-dwim-dwim
C-M-\indent-region-or-buffer
M-/dabbrev-expandhelm-dabbrev doesn’t work
C-M-/company-complete
M-gmagit-status
S-M-SPCmath-symbol-at-point
C-=er/expand-region
C-+er/contract-region
C-*mc/mark-all-like-this
C-<mc/mark-previous-like-this
C->mc/mark-next-like-this
C-x r tmc/edit-lines
M-s jdumb-jump-go
M-s Jdumb-jump-go-other-window
C-c ddocker
M-<backspace>nilsp-keymap
C-M-pnilsp-keymap
C-M-nnilsp-keymap
C-x mjw-keymap
C-c mjw-keymap
mjw-keymapctl-x-4-map
mjw-keymapctl-x-5-map
!cmd-menujw-keymap
&cmd-menujw-keymap
qemacs-configs-togglejw-keymap
ddatejw-keymap
wweatherjw-keymap
bcomputer-power-statusjw-keymap
itoggle-scratch-bufferjw-keymap
Itmp-scratch-bufferjw-keymap
C-c pprojectile-command-map
(define-prefix-command 'jw-keymap)
(keybinding-org-table 'base-keys)

eshell

eshell-keys

KeyFunctionScope
eeshell-ejw-keymap
Eeshell-Ejw-keymap
(defun eshell-e (arg)
  "A wrapper for `eshell', except that this function provides ordered cycling through all eshells creating using prefix arguments."
  (interactive "P")
  (eshell--exec arg nil))

(defun eshell-E (arg)
  "Similar to `eshell-e' except the cycling function is reversed."
  (interactive "P")
  (eshell--exec arg t))

(defun eshell-cleanup-eshells (arg)
  "Kill all eshells. If a prefix arg is provided, then leave the original eshell alive."
  (interactive "P")
  (-each (eshell--buffers-list)
    (lambda (buffer)
      (unless (and arg (s-equals? "*eshell*" (buffer-name buffer)))
        (kill-buffer buffer)))))

(defun eshell--exec (prefix-arg cycle-backward)
  (let ((eshells (eshell--buffer-names-list)))
    (if (or prefix-arg
            (not (eq major-mode 'eshell-mode))
            (not eshells))
        (eshell prefix-arg)
      (eshell--cycle-to-next eshells cycle-backward))))

(defun eshell--extract-buffer-name-digit (buffer)
  (string-to-number (or (car (s-match "[[:digit:]]+" (buffer-name buffer))) "-1")))

(defun eshell--buffers-list-ordering (b1 b2)
  (< (eshell--extract-buffer-name-digit b1) (eshell--extract-buffer-name-digit b2)))

(defun eshell--buffers-list ()
  (-sort
   'eshell--buffers-list-ordering
   (-filter
    (lambda (buffer) (eq (buffer-local-value 'major-mode buffer) 'eshell-mode))
    (buffer-list))))

(defun eshell--buffer-names-list ()
  (-map (lambda (b) (buffer-name b)) (eshell--buffers-list)))

(defun eshell--cycle-to-next (eshells cycle-backward)
  (let* ((num-eshells (length eshells))
         (idx (or (-elem-index (buffer-name) eshells) num-eshells))
         (next-idx (mod (if cycle-backward (- idx 1) (+ idx 1)) num-eshells))
         (next-eshell (nth next-idx eshells)))
    (switch-to-buffer next-eshell)))

(defun eshell--last-command-status-prompt-string ()
  (if (= 0 eshell-last-command-status)
      ""
    (propertize (format "-%s-\n" eshell-last-command-status) 'face '(:foreground "red3"))))

(defun eshell--git-prompt-string ()
  (require 'vc)
  (if (jw--git-root-dir)
      ;; vc-git-branches returns (list nil) instead of nil when there is no branch name instead of just nil (i.e. after a git-init)
      (let* ((git-branch-name (or (car (vc-git-branches)) "(in the beginning there was darkness)"))
             (git-is-clean (s-blank? (shell-command-to-string "git status --porcelain")))
             (git-is-clean-marker (if git-is-clean "" ""))
             (git-is-clean-color (if git-is-clean "green" "red1"))
             (git-branch-name-string (propertize git-branch-name 'face '(:foreground "yellow3")))
             (git-is-clean-string (propertize git-is-clean-marker 'face `(:foreground ,git-is-clean-color))))
        (format "%s %s" git-branch-name-string git-is-clean-string))
    ""))

(defun eshell--prompt-function ()
  (let* ((last-status-string (eshell--last-command-status-prompt-string))
         (dir-string (propertize (abbreviate-file-name (eshell/pwd)) 'face '(:foreground "CornflowerBlue")))
         (git-string (eshell--git-prompt-string))
         (prompt-string (propertize (if (= (user-uid) 0) "#" "»") 'face '(:foreground "red3")))
         (right-pad-string (propertize " " 'face '(:foreground nil)))
         (prompt-string (s-collapse-whitespace (format "%s %s %s %s" dir-string git-string prompt-string right-pad-string))))
    (concat last-status-string prompt-string)))

(setq eshell-prompt-function 'eshell--prompt-function)
(setq eshell-prompt-regexp "^[^#$»\n]* [#$»] ")

(keybinding-org-table 'eshell-keys)

(require 'em-alias)
(eshell/alias "l" "ls -alh")
(eshell/alias "d" "dired $1")
(eshell/alias "e" "find-file $1")
(eshell/alias "emacs" "find-file $1")
(eshell/alias "vi" "find-file $1")
(eshell/alias "vim" "find-file $1")
(eshell/alias "less" "find-file $1")
(eshell/alias "cat" "find-file $1")
(eshell/alias ":q" "exit")
(eshell/alias ":Q" "exit")

(add-to-list 'eshell-mode-hook (lambda ()
                                 (add-to-list 'eshell-visual-commands "htop")
                                 (add-to-list 'eshell-visual-subcommands '("git" "log" "diff" "show"))
                                 (add-to-list 'eshell-visual-subcommands '("g" "log" "diff" "show"))))

(defun eshell/which--advice--add-login-shell-which-output (eshell/which-function &rest names)
  (eshell-printn "\neshell/which:")
  (apply eshell/which-function names)
  (let* ((login-shell-program (jw--login-shell))
         (raw-result (shell-command-to-string (format "%s -c \"which %s\"" login-shell-program (s-join " " names))))
         (login-shell-which-result (format "\n%s's which:\n%s" login-shell-program raw-result)))
    (eshell-printn login-shell-which-result)))

(advice-add 'eshell/which :around 'eshell/which--advice--add-login-shell-which-output)

ansi-term additions

(defun eshell/ansi (&rest args)
  (interactive)
  (ansi-term (jw--login-shell))
  (when args
    (insert (s-join " " args))
    (term-send-input)))

(setq ansi-term-kill-on-exit t)

(defun ansi-term-life-is-too-much ()
  (interactive)
  (if (not ansi-term-kill-on-exit)
      (bury-buffer)
    (kill-buffer (current-buffer))))

(defun ansi-term--exit-hook ()
  (let ((ansi-process (get-buffer-process (current-buffer))))
    (jw--do-when-process-finishes ansi-process
                                  (lambda (proc)
                                    (switch-to-buffer (process-buffer proc))
                                    (ansi-term-life-is-too-much)))))

(add-hook 'term-mode-hook 'ansi-term--exit-hook)

yasnippet

yas-keys

KeyFunction
M-?yas-dwim
(defun yas-dwim (arg)
  (interactive "P")
  (if (equal arg 4) (yas-new-snippet)
    (if arg (yas-visit-snippet-file)
      (yas-insert-snippet))))

(yas-global-mode 1)

(keybinding-org-table 'yas-keys)


(setq yas-indent-line nil)

rcirc

(require 'rcirc)

(defun rcirc-connect-dwim (&optional server port nick user-name full-name startup-channels password encryption)
  "Alternative to `rcirc-connect'.
If the server is not connected, then connect to it.
If no server is provided, then a prompt will ask the user for a server.
If the server is connected, then toggle to it's process buffer.
If the server is connected and a prefix arg is provided, then invoke a quick /msg on the server and toggle back to the other-buffer."
  (interactive)
  (if server
      (let ((existing-sp (get-process server)))
        (if (process-live-p existing-sp)
            (if current-prefix-arg
                (save-window-excursion
                  (switch-to-buffer (process-buffer existing-sp))
                  (call-interactively 'rcirc-cmd-msg))
              (switch-to-buffer (process-buffer existing-sp)))
          (rcirc-connect server port nick user-name full-name startup-channels password encryption)))
    (rcirc t)))

(setq rcirc-buffer-maximum-lines 2000)

(add-to-list 'rcirc-omit-responses "MODE")

(custom-set-faces '(rcirc-my-nick ((t (:foreground "#00ffff"))))
                  '(rcirc-other-nick ((t (:foreground "#90ee90"))))
                  '(rcirc-server ((t (:foreground "#a2b5cd"))))
                  '(rcirc-server-prefix ((t (:foreground "#00bfff"))))
                  '(rcirc-timestamp ((t (:foreground "#7d7d7d"))))
                  '(rcirc-nick-in-message ((t (:foreground "#00ffff"))))
                  '(rcirc-prompt ((t (:foreground "#00bfff"))))
                  '(rcirc-keyword ((t :foreground "#00ffff")))
                  '(rcirc-nick-in-message-full-line ((t ())))
                  '(rcirc-track-nick ((t (:foreground "#00ffff"))))
                  '(rcirc-track-keyword ((t (:foreground "#00ffff")))))

(defun rcirc-hook--initial-config ()
  (jw--save-current-message
    (turn-on-flyspell)
    (rcirc-track-minor-mode t)
    (rcirc-omit-mode)
    (cd (getenv "HOME"))))

(add-hook 'rcirc-mode-hook 'rcirc-hook--initial-config)

(defun rcirc-hook--span-window-width ()
  (setq rcirc-fill-column (- (window-width) 2)))

(add-hook 'window-configuration-change-hook 'rcirc-hook--span-window-width)

(defun rcirc-handler-NOTICE--advice--ignore-KEEPALIVE (original-function &rest args)
  (let* ((function-args (nth 2 args))
         (msg (cadr function-args)))
    (unless (string-match "keepalive" msg)
      (apply original-function args))))

(advice-add 'rcirc-handler-NOTICE :around 'rcirc-handler-NOTICE--advice--ignore-KEEPALIVE)

here are some useful rcirc configs to set in in the safe private location

(setq rcirc-default-nick "nick"
      rcirc-default-user-name "username"
      rcirc-default-full-name "full name"
      rcirc-keywords '("nick1" "nick2")
      rcirc-server-alist '(("irc.freenode.net"
                            :port 6697
                            :encryption tls
                            :user-name "freenode username"
                            :password "free node pass"
                            :channels ("##doctorwho"))))

example of defining specific functions to connect to various irc servers

(defun freenode-irc-connect ()
  (interactive)
  (rcirc-connect-dwim "irc.freenode.net" 6697 "nick" "username" "full name" '("##doctorwho" "#emacs") "your password" 'tls)

(defun twitch-irc-connect ()
  (interactive)
  (rcirc-connect-dwim "irc.chat.twitch.tv" 6667 "nick" "username" "full name" nil "your password"))

helm

helm-keys

KeyFunctionScopeHookNotes
C-c hhelm-command-prefix
C-x cnilundo default helm prefix
M-xhelm-M-x
M-:helm-eval-expression-with-eldoc
M-*helm-calcul-expression
C-x C-bhelm-buffers-list
C-x C-fhelm-find-files
M-yhelm-show-kill-ring
M-s shelm-do-grep-ag
M-s ohelm-occur
M-s ihelm-semantic-or-imenu
C-x r lhelm-bookmarks
C-x r jhelm-register-jump-dwim
C-h ahelm-apropos
C-h bhelm-descbinds
C-h rhelm-info-emacs
C-h dhelm-info-at-point
C-h ihelm-info
hhelm-descbindshelm-command-map
M-s shelm-ff-run-grep-aghelm-find-files-map
C-shelm-ff-run-grep-aghelm-find-files-mapag instead of grep
C-c ! lhelm-flycheckflycheck-mode-map
C-M-ihelm-flyspell-correctflyspell-mode-map
<tab>helm-esh-pcompleteeshell-mode-mapeshell-mode-hook
M-phelm-eshell-historyeshell-mode-mapeshell-mode-hook
(require 'helm)
(require 'helm-config)
(require 'helm-dabbrev)

(setq helm-split-window-in-side-p t
      helm-ff-search-library-in-sexp t
      helm-scroll-amount 8
      helm-buffer-max-length nil
      helm-ff-file-name-history-use-recentf t
      helm-quick-update t
      helm-move-to-line-cycle-in-source nil
      helm-mode-fuzzy-match t
      helm-completion-in-region-fuzzy-match t
      helm-case-fold-search t
      helm-ag-insert-at-point 'symbol
      helm-show-completion-display-function nil ;; do not use separate window for completion selection
      )

(when (eq system-type 'darwin)
  (setq helm-man-format-switches "%s"))

(defalias 'kill-ring-show 'helm-show-kill-ring)
(defalias 'list-colors-display 'helm-colors)
(defalias 'proced 'helm-top)

(defun helm-register-jump-dwim (arg)
  (interactive "P")
  (if arg (helm-register) (call-interactively 'jump-to-register)))

(set-face-attribute 'helm-source-header nil :height 1.0 :weight 'normal :family (jw--font-name) :box '(:style released-button))
(set-face-attribute 'helm-candidate-number nil :background jw--mode-line-color :foreground "goldenrod")

(keybinding-org-table 'helm-keys)

(helm-mode 1)
(helm-autoresize-mode 1)

(projectile-global-mode)
(helm-projectile-on)

(setq projectile-completion-system 'helm
      projectile-mode-line ""  ;; this slowed tramp down sometimes
      projectile-switch-project-action 'helm-projectile)

(when (executable-find "ag")
  (setq helm-grep-ag-command "ag -i --nogroup --nocolor --line-numbers %s %s %s")
  (setq helm-ag-base-command "ag -i --nogroup --nocolor --line-numbers"))

(defun helm-projectile-projects-helm-projectile-ag (dir)
  (interactive)
  (with-temp-buffer
    (let ((default-directory dir))
      (call-interactively 'helm-projectile-ag))))

(helm-add-action-to-source "Ag in project `M-s a'" 'helm-projectile-projects-helm-projectile-ag helm-source-projectile-projects)
(helm-projectile-define-key helm-projectile-projects-map (kbd "M-s s") 'helm-projectile-projects-helm-projectile-ag)
(helm-projectile-define-key helm-projectile-projects-map (kbd "C-s") 'helm-projectile-projects-helm-projectile-ag) ;; hijack grep's keybinding

(defalias 'projectile-empty-garbage 'projectile-cleanup-known-projects)

(defun projectile-clear-known-projects--advice--ask-y-or-n (original-function)
  (if (yes-or-no-p "This will REMOVE ALL projects from projectile. Are you sure?")
      (apply original-function)
    (message "Did NOT clear the projectile projects.")))

(advice-add 'projectile-clear-known-projects :around 'projectile-clear-known-projects--advice--ask-y-or-n)

(add-to-list 'helm-dabbrev-major-mode-assoc '(scala-mode . sbt-mode))

make company-complete dropdown look more like helm

(require 'company)
(custom-set-faces `(company-tooltip ((t (:background ,jw--mode-line-color))))
                  `(company-scrollbar-bg ((t (:background "black"))))
                  `(company-scrollbar-fg ((t (:background "#005858"))))
                  `(company-tooltip-selection ((t (:inherit 'helm-selection))))
                  `(company-tooltip-common ((t (:inherit 'helm-match))))
                  `(company-tooltip-common-selection ((t (:inherit 'helm-match))))
                  `(company-tooltip-annotation ((t (:inherit 'helm-bookmark-file))))
                  `(company-preview-common ((t :inherit 'company-echo)))
                  `(company-echo-common ((t :inherit 'company-echo)))
                  `(company-template-field ((t :inherit 'helm-match-item))))

org

ob-scala copied from org-mode’s github since scala-mode’s ob-scala requires ensime

;;; ob-scala.el --- org-babel functions for Scala evaluation

;; Copyright (C) 2012-2014 Free Software Foundation, Inc.

;; Author: Andrzej Lichnerowicz
;; Keywords: literate programming, reproducible research
;; Homepage: http://orgmode.org

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;; Currently only supports the external execution.  No session support yet.

;;; Requirements:
;; - Scala language :: http://www.scala-lang.org/
;; - Scala major mode :: Can be installed from Scala sources
;;  https://github.com/scala/scala-dist/blob/master/tool-support/src/emacs/scala-mode.el

;;; Code:
(require 'ob)
(eval-when-compile (require 'cl))

(defvar org-babel-tangle-lang-exts) ;; Autoloaded
(add-to-list 'org-babel-tangle-lang-exts '("scala" . "scala"))
(defvar org-babel-default-header-args:scala '())
(defvar org-babel-scala-command "scala"
  "Name of the command to use for executing Scala code.")

(defun org-babel-execute:scala (body params)
  "Execute a block of Scala code with org-babel.  This function is
called by `org-babel-execute-src-block'"
  (message "executing Scala source code block")
  (let* ((processed-params (org-babel-process-params params))
         (session (org-babel-scala-initiate-session (nth 0 processed-params)))
         (vars (nth 1 processed-params))
         (result-params (nth 2 processed-params))
         (result-type (cdr (assoc :result-type params)))
         (full-body (org-babel-expand-body:generic
                     body params))
         (result (org-babel-scala-evaluate
                  session full-body result-type result-params)))

    (org-babel-reassemble-table
     result
     (org-babel-pick-name
      (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
     (org-babel-pick-name
      (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))


(defun org-babel-scala-table-or-string (results)
  "Convert RESULTS into an appropriate elisp value.
If RESULTS look like a table, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
  (org-babel-script-escape results))


(defvar org-babel-scala-wrapper-method

"var str_result :String = null;
Console.withOut(new java.io.OutputStream() {def write(b: Int){
}}) {
  str_result = {
%s
  }.toString
}
print(str_result)
")


(defun org-babel-scala-evaluate
  (session body &optional result-type result-params)
  "Evaluate BODY in external Scala process.
If RESULT-TYPE equals 'output then return standard output as a string.
If RESULT-TYPE equals 'value then return the value of the last statement
in BODY as elisp."
  (when session (error "Sessions are not (yet) supported for Scala"))
  (case result-type
    (output
     (let ((src-file (org-babel-temp-file "scala-")))
       (progn (with-temp-file src-file (insert body))
              (org-babel-eval
               (concat org-babel-scala-command " " src-file) ""))))
    (value
     (let* ((src-file (org-babel-temp-file "scala-"))
            (wrapper (format org-babel-scala-wrapper-method body)))
       (with-temp-file src-file (insert wrapper))
       (let ((raw (org-babel-eval
                   (concat org-babel-scala-command " " src-file) "")))
         (org-babel-result-cond result-params
	   raw
           (org-babel-scala-table-or-string raw)))))))


(defun org-babel-prep-session:scala (session params)
  "Prepare SESSION according to the header arguments specified in PARAMS."
  (error "Sessions are not (yet) supported for Scala"))

(defun org-babel-scala-initiate-session (&optional session)
  "If there is not a current inferior-process-buffer in SESSION
then create.  Return the initialized session.  Sessions are not
supported in Scala."
  nil)

(provide 'ob-scala)

;;; ob-scala.el ends here

org-keys

KeyFunctionScopeHook
ojw-todojw-keymap
aorg-agendajw-keymap
Ajw-org-agendajw-keymap
cjw-org-capturejw-keymap
<tab>org-pomodorojw-keymap
C-c <org-time-stamplocalorg-mode-hook
C-c .org-time-stamp-inactivelocalorg-mode-hook
C-c C-x gorg-feed-update-all-or-onelocalorg-mode-hook
(require 'org)
(require 'org-pomodoro)

(unless (boundp 'jw-org-todo-file)
  (setq jw-org-todo-file (f-expand "todo.org" user-emacs-directory)))

(defun jw-todo ()
  (interactive)
  (if (s-equals? (buffer-name) (f-filename jw-org-todo-file))
      (switch-to-buffer (other-buffer))
    (find-file jw-org-todo-file)
    (cd (getenv "HOME"))))

(setq jw-org-agenda-pre-hook nil)

(defun jw-org-agenda (arg)
  "Enriched `org-agenda' that runs `jw-org-agenda-pre-hook' before `org-agenda' is opened. `org-agenda-mode-hook' can be used for a post-hook"
  (interactive "P")
  (run-hooks 'jw-org-agenda-pre-hook)
  (org-agenda arg))

(defun org-feed-update-all-or-one (arg)
  "When called with a prefix argument, interactively call `org-feed-update'. Otherwise call `org-feed-update-all'."
  (interactive "P")
  (if arg
      (call-interactively 'org-feed-update)
    (org-feed-update-all)))

(defun org-id (arg)
  "Ensure an org-id exists and copy to kill ring. With prefix arg, force creation of a new org-id."
  (interactive "P")
  (org-id-get-create arg)
  (org-id-copy))

(defun jw-org-capture (arg)
  (interactive "P")
  (if arg
      (org-capture '(16))
    (helm-org-capture-templates)))

(keybinding-org-table 'org-keys)

(add-to-list 'org-latex-packages-alist '("" "physics"))
(setq org-latex-remove-logfiles nil) ;; evaluating latex blocks was causing errors because ox-latex couldn't find the logfiles
(setq org-latex-caption-above '(image table src-block special-block))

(setq org-use-speed-commands t
      org-enforce-todo-dependencies t
      org-enforce-todo-checkbox-dependencies t
      org-return-follows-link t
      org-hide-leading-stars t
      org-clock-clocked-in-display 'mode-line
      org-refile-targets '((org-agenda-files :maxlevel . 10))
      org-refile-use-outline-path t
      org-refile-allow-creating-parent-nodes '(confirm)
      org-tags-column -100
      org-src-preserve-indentation t
      org-src-window-setup 'current-window
      org-cycle-open-archived-trees t
      org-hide-block-startup t
      org-ellipsis ""
      org-fontify-done-headline t
      org-todo-keywords '((sequence "" "" "|" ""))
      org-startup-with-inline-images t
      org-confirm-babel-evaluate nil
      org-confirm-shell-link-function nil
      org-confirm-elisp-link-function nil
      org-id-link-to-org-use-id 'create-if-interactive
      org-agenda-window-setup 'only-window)

(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)

(setq org--todo-todo-boxed-states '("todo" "incoming" "captured" "unread" "question")
      org--todo-todo-states '("")
      org--blocked-todo-boxed-states '("blocked" "halted" "stalled" "paused")
      org--doing-todo-boxed-states '("doing" "going")
      org--doing-todo-states '("")
      org--delegated-todo-boxed-states '("delegated" "assigned" "pr" "waiting")
      org--done-todo-boxed-states '("done" "cancelled" "canceled" "finished" "boom" "read" "answered")
      org--done-todo-states '("" ""))

(defun org--red-box-state (s) `(,s :background "DarkRed" :foreground white :box (:style released-button)))
(defun org--red-state (s) `(,s :foreground "Coral"))
(defun org--blue-box-state (s) `(,s :background "DeepSkyBlue4" :foreground white :box (:style released-button)))
(defun org--blue-state (s) `(,s :foreground "DeepSkyBlue1"))
(defun org--green-box-state (s) `(,s :background "DarkGreen" :foreground white :box (:style released-button)))
(defun org--green-state (s) `(,s :foreground "LimeGreen"))

(setq org-todo-keyword-faces (append (mapcar 'org--red-box-state org--todo-todo-boxed-states)
                                     (mapcar 'org--red-box-state (mapcar 'upcase org--todo-todo-boxed-states))

                                     (mapcar 'org--red-box-state org--blocked-todo-boxed-states)
                                     (mapcar 'org--red-box-state (mapcar 'upcase org--blocked-todo-boxed-states))

                                     (mapcar 'org--red-state org--todo-todo-states)

                                     (mapcar 'org--blue-box-state org--doing-todo-boxed-states)
                                     (mapcar 'org--blue-box-state (mapcar 'upcase org--doing-todo-boxed-states))

                                     (mapcar 'org--blue-box-state org--delegated-todo-boxed-states)
                                     (mapcar 'org--blue-box-state (mapcar 'upcase org--delegated-todo-boxed-states))

                                     (mapcar 'org--blue-state org--doing-todo-states)

                                     (mapcar 'org--green-box-state org--done-todo-boxed-states)
                                     (mapcar 'org--green-box-state (mapcar 'upcase org--done-todo-boxed-states))

                                     (mapcar 'org--green-state org--done-todo-states)
                                     ))

(setq org-pomodoro-format "Pomodoro %s"
      org-pomodoro-short-break-format "Short Break %s"
      org-pomodoro-long-break-format "Long Break %s"
      org-pomodoro-ask-upon-killing nil
      org-pomodoro-short-break-sound-p nil
      org-pomodoro-long-break-sound-p nil)

(custom-set-faces `(org-headline-done ((t (:inherit shadow))))
                  `(org-pomodoro-mode-line ((t (:foreground "#2aa198"))))
                  `(org-link ((t (:underline nil))))
                  `(org-date ((t (:underline nil)))))

(add-to-list 'org-structure-template-alist '("n" "#+NAME: ?"))
(add-to-list 'org-structure-template-alist '("h" "#+HEADER: ?"))
(add-to-list 'org-structure-template-alist '("p" "#+PROPERTY: ?"))
(add-to-list 'org-structure-template-alist '("P" ":PROPERTIES:\n?\n:END:"))
(add-to-list 'org-structure-template-alist '("S" "#+BEGIN_SRC ?\n\n#+END_SRC"))
(add-to-list 'org-structure-template-alist '("call" "#+CALL: ?"))
(add-to-list 'org-structure-template-alist '("ipdf" "#+INTERLEAVE_PDF: ?"))

(defun org-babel-support-src-template-shortcut (shortcut &optional src-line)
  (let* ((shortcut-name (if (symbolp shortcut) (symbol-name shortcut) shortcut))
         (src-line-name (if src-line
                            (if (symbolp src-line) (symbol-name src-line) src-line)
                          shortcut-name))
         (src-block-template (format "#+BEGIN_SRC %s\n?\n#+END_SRC" src-line-name)))
    (add-to-list 'org-structure-template-alist `(,shortcut-name ,src-block-template))))

(defun org-babel-support-langs (langs)
  (org-babel-do-load-languages
   'org-babel-load-languages
   (-map (lambda (lang) (if (listp lang) `(,(car lang) . t) `(,lang . t))) langs))
  (-each langs
    (lambda (lang)
      (let* ((all-shortcuts (if (listp lang) lang (list lang)))
             (ob-lang (car all-shortcuts)))
        (-each all-shortcuts (lambda (shortcut) (org-babel-support-src-template-shortcut shortcut ob-lang)))))))

(org-babel-support-langs
 (list 'awk 'calc 'C 'dot '(emacs-lisp elisp el) '(haskell hask hs) 'http 'java 'js 'latex 'ledger 'lisp
       'makefile 'matlab 'org 'perl 'plantuml '(python py) 'R '(ruby rb)
       'scala ;; there are conflicting versions in org & scala-mode requiring ensime. right now, the org-mode version is pasted above.
       'scheme '(shell sh) 'sql '(translate tr)))

(add-to-list 'org-src-lang-modes '("dot" . graphviz-dot)) ;; "dot" src blocks don't use graphviz-dot-mode by default

(org-babel-support-src-template-shortcut 'bash)
(org-babel-support-src-template-shortcut 'md 'markdown)
(org-babel-support-src-template-shortcut 'gfm)
(org-babel-support-src-template-shortcut 'conf)
(org-babel-support-src-template-shortcut 'text)
(org-babel-support-src-template-shortcut 'json)
;; (org-babel-support-src-template-shortcut 'scala) ;; uncomment this if scala is commented out above, so that org babel still supports scala mode

(org-babel-support-src-template-shortcut 'trs "translate :src es :dest en") ;; traducir español al inglés
(org-babel-support-src-template-shortcut 'tre "translate :src en :dest es") ;; translate english to spanish

(setq org-babel-default-header-args:sh '((:results . "output"))
      org-babel-default-header-args:shell '((:results . "output"))
      org-babel-default-header-args:bash '((:results . "output"))
      org-babel-default-header-args:js '((:results . "output")) ;; doesn't work with "value" for some reason, it just prints "undefined"
      org-babel-default-header-args:python '((:results . "output")) ;; doesn't work with "value" for some reason, it just prints "None"
      org-babel-default-header-args:http '((:pretty . "yes")))

support cmd function in org-babel and cmd org link

(defconst org-babel-header-args:cmd '((bg . :any) (tmux . :any)))

;; warning: cmd does not work with the :async header since ob-cmd is never provided (which org-babel-do-load-languages requires)
(defun org-babel-execute:cmd (body params)
  (let* ((bg-option (assoc :bg params))
         (in-bg (and bg-option (not (string= (cdr bg-option) "no"))))
         (tmux-option (assoc :tmux params))
         (tmux-session (or (cdr tmux-option) "emacs")))
    (if tmux-option
        (progn (cmd-tmux body tmux-session) (format "Sent to tmux session: %s" tmux-session))
      (progn
        (cmd body)
        (when in-bg (switch-to-buffer (other-buffer)))
        "Running command"))))

(add-to-list 'org-src-lang-modes '("cmd" . sh))

(define-derived-mode cmd-mode sh-mode "cmd")

(setq org-babel-default-header-args:cmd '((:results . "silent")))

(org-babel-support-src-template-shortcut 'cmd)
(org-babel-support-src-template-shortcut 'tmux "cmd :tmux")

(add-to-list 'org-link-parameters '("cmd" :follow (lambda (ref) (cmd ref))))
(add-to-list 'org-link-parameters '("cmd+tmux" :follow (lambda (ref) (cmd-tmux ref))))

support gist and gist+raw org links

(defun org-gist-link-follow (ref &optional raw)
  (let ((url-segment (if (s-contains? "/" ref) ref
                       (concat (or (jw--git-config-get "github.user") (jw--git-config-get "user.name")) "/" ref)))
        (raw-segment (if raw "raw" "")))
    (browse-url (format "https://gist.github.com/%s/%s" url-segment raw-segment))))

(add-to-list 'org-link-parameters '("gist" :follow (lambda (ref) (org-gist-link-follow ref))))
(add-to-list 'org-link-parameters '("gist+raw" :follow (lambda (ref) (org-gist-link-follow ref 'raw))))

hacky way of using org tables for markdown tables copied from stackoverflow

(require 'org-table)

(defun markdown-cleanup-org-tables ()
  (interactive)
  (when (or (eq major-mode 'markdown-mode) (eq major-mode 'gfm-mode))
    (save-excursion
      (goto-char (point-min))
      (while (search-forward "-+-" nil t) (replace-match "-|-")))))

(add-hook 'markdown-mode-hook 'turn-on-orgtbl)
(advice-add 'org-table-align :after 'markdown-cleanup-org-tables)

(defalias 'markdown-table-create 'org-table-create)
(defalias 'markdown-table-insert-column 'org-table-insert-column)
(defalias 'markdown-table-delete-column 'org-table-delete-column)
(defalias 'markdown-table-insert-row 'org-table-insert-row)
(defalias 'markdown-table-delete-row 'org-table-delete-row)

scala

scala-keys

KeyFunctionScope
C-c ssbt-command-prefix
sjw-sbtsbt-keymap
csbt-compilesbt-keymap
osbt-test-only-current-testsbt-keymap
lsbt-run-previous-commandsbt-keymap
(defun jw-sbt ()
  (interactive)
  (if (eq major-mode 'sbt-mode)
      (switch-to-buffer (other-buffer))
    (with-temp-buffer
      (if (sbt:find-root)
          (sbt-start)
        (call-interactively 'jw-sbt-run-or-create-new)))))

(defun jw-sbt-run-or-create-new (dir)
  (interactive "DSBT run or create new project in: ")
  (when (not (f-exists? dir)) (make-directory dir 'make-parents))
  (let ((default-directory dir))
    (with-temp-buffer
      (if (sbt:find-root)
          (sbt-start)
        (cmd "sbt-new")))))

(defun sbt-current-tests-in-buffer ()
  (interactive)
  (save-excursion
    (let* ((pkg-name-components)
           (test-names))
      (goto-char (point-min))
      (while (re-search-forward "package " nil t)
        (push (filter-buffer-substring (point) (point-at-eol)) pkg-name-components))
      (goto-char (point-min))
      (while (re-search-forward "\\(object\\|class\\) " nil t)
        (push (filter-buffer-substring (point) (progn (re-search-forward " ")
                                                      (forward-char -1)
                                                      (point)))
              test-names))
      (let* ((full-pkg-name (string-join (reverse pkg-name-components) "."))
             (full-test-names (mapcar #'(lambda (test-name) (string-join (list full-pkg-name "." test-name))) test-names))
             (full-test-names-str (string-join full-test-names " ")))
        (message full-test-names-str)))))

(defun sbt-test-only-current-test (only-zzz)
  (interactive "P")
  (if only-zzz
      (sbt-command (concat "testOnly " (sbt-current-tests-in-buffer) " -- showtimes -- ex zzz"))
    (sbt-command (concat "testOnly " (sbt-current-tests-in-buffer) " -- showtimes"))))

(defun sbt-compile (test-compile)
  (interactive "P")
  (if test-compile
      (sbt-command "test:compile")
    (sbt-command "compile")))

(setq sbt-keymap (make-sparse-keymap))
(fset 'sbt-command-prefix sbt-keymap)

(keybinding-org-table 'scala-keys)

(add-to-list 'auto-mode-alist '("\\.scala$" . scala-mode))
(add-to-list 'auto-mode-alist '("\\.sbt$" . scala-mode))

(setq scala-indent:align-forms t
      scala-indent:align-parameters t)

adding sbt shortcut to helm projectile

(require 'helm-projectile)

;; sbt mode uses some local variables which causes issues from inside of the helm and switching between multiple projects
;; e.g. `sbt:buffer-project-root'
;; using with-temp-buffer to avoid that

(defun helm-projectile-projects-sbt (dir)
  (interactive)
  (with-temp-buffer
    (let ((default-directory dir)) (call-interactively 'jw-sbt))))

(defun helm-projectile-projects-sbt-compile (dir)
  (interactive)
  (with-temp-buffer (let ((default-directory dir)) (call-interactively 'sbt-compile))))

(helm-add-action-to-source "Dispatch sbt `C-c s ...'" 'helm-projectile-projects-sbt helm-source-projectile-projects)

(helm-projectile-define-key helm-projectile-projects-map (kbd "C-c s s") 'helm-projectile-projects-sbt)
(helm-projectile-define-key helm-projectile-projects-map (kbd "C-c s c") 'helm-projectile-projects-sbt-compile)

remove flycheck from *.sbt files

(defun disable-flycheck-scala-in-sbt-files ()
  (when (and buffer-file-name (s-equals? "sbt" (file-name-extension buffer-file-name)))
    (flycheck-mode -1)))

(add-hook 'scala-mode-hook 'disable-flycheck-scala-in-sbt-files)

sonic pi

sonic-pi-keys

KeyFunctionScope
msonic-pi-stop-or-playjw-keymap
(require 'org)
(require 'ob)

(defun sonic-pi-play (&optional ruby)
  "Sends snippet of ruby code to Sonic Pi GUI application via a custom shell script."
  (interactive)
  (let ((prepared-ruby (or ruby (if (region-active-p)
                                    (buffer-substring-no-properties (point) (mark))
                                  (buffer-substring-no-properties (point-min) (point-max))))))
    (shell-command (format "echo '%s' | sonic-pi" prepared-ruby))))

(defun sonic-pi-stop ()
  (interactive)
  (shell-command "sonic-pi stop"))

(defun sonic-pi-stop-or-play (arg)
  (interactive "P")
  (if arg (sonic-pi-stop) (sonic-pi-play)))

(keybinding-org-table 'sonic-pi-keys)

;; warning: sonic-pi does not work with the :async header since ob-sonic-pi is never provided (which org-babel-do-load-languages requires)
(defun org-babel-execute:sonic-pi (body params)
  (sonic-pi-play body)
  "Sent to Sonic Pi")

(add-to-list 'org-src-lang-modes '("sonic-pi" . ruby))

(define-derived-mode sonic-pi-mode ruby-mode "sonic-pi")

(setq org-babel-default-header-args:sonic-pi '((:results . "silent")))

(org-babel-support-src-template-shortcut 'sonicpi "sonic-pi")

exercism-io

exercism-io keys

KeyFunctionScope
xexercism-io-menujw-keymap
(jw--define-menu exercism-io-menu 'exercism-io-menu
  :actions '("exercism.io"
             (?f "fetch" exercism-io-fetch)
             (?F "submit this file" exercism-io-submit-this-file)
             (?c "configure / login" exercism-io-configure)
             (?t "tracks" exercism-io-tracks)
             (?l "list" exercism-io-list)
             (?s "status" exercism-io-status)
             (?r "restore" exercism-io-restore)
             (?h "help" exercism-io-help)
             (?x "(other command)" exercism-io-cmd))
  :max-action-columns 1)

(keybinding-org-table 'exercism-io-keys)

(setq exercism-io--cached-track-list nil)
(defun exercism-io--get-track-list ()
  (or exercism-io--cached-track-list
      (let* ((json (json-read-from-string (jw--http-get-request-to-string "http://x.exercism.io/tracks")))
             (tracks-json-array (alist-get 'tracks json))
             (track-ids (-map (lambda (track-json) (alist-get 'id track-json)) tracks-json-array)))
        (setq exercism-io--cached-track-list track-ids)
        exercism-io--cached-track-list)))

(defun exercism-io--read-track ()
  (completing-read "Track: " (exercism-io--get-track-list) nil t))

(defun exercism-io-cmd (cmd)
  (interactive "sCommand: ")
  (cmd (format "exercism %s" cmd)))

(defun exercism-io-help ()
  (interactive)
  (exercism-io-cmd "--help"))

(defun exercism-io-fetch (arg)
  (interactive "P")
  (if arg
      (exercism-io-cmd (format "fetch %s" (exercism-io--read-track)))
    (exercism-io-cmd "fetch")))

(defun exercism-io-submit-this-file ()
  (interactive)
  (exercism-io-cmd (format "submit %s" (buffer-file-name))))

(defun exercism-io-tracks ()
  (interactive)
  (exercism-io-cmd "tracks"))

(defun exercism-io-restore ()
  (interactive)
  (exercism-io-cmd "restore"))

(defun exercism-io-list ()
  (interactive)
  (exercism-io-cmd (format "list %s" (exercism-io--read-track))))

(defun exercism-io-status ()
  (interactive)
  (exercism-io-cmd (format "status %s" (exercism-io--read-track))))

(defun exercism-io-configure ()
  (interactive)
  (let ((key-url "http://exercism.io/account/key"))
    (browse-url key-url)
    (let ((key (read-string (format "Paste key from %s here: " key-url))))
      (exercism-io-cmd (format "configure --key=%s" key)))))

private

load the private directory and the private.org file if they exist

(let ((path (expand-file-name "private" user-emacs-directory)))
  (when (file-exists-p path)
    (add-to-list 'load-path path)
    (mapcar 'load-file (directory-files path t "\.el$"))))

(let ((private-org (expand-file-name "private.org" user-emacs-directory)))
  (when (file-exists-p private-org)
    (org-babel-load-file private-org)))

finally

(scratch-buffer)
(transparency-on)
(cd (getenv "HOME"))
(toggle-frame-maximized)
(unless (server-running-p) (server-start))